From 351a7bb83a5713e1b2f8d6c4ee1f4df1503b5705 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Fri, 17 Feb 2023 23:48:20 +0100 Subject: [PATCH 1/8] add .sb-unstyled class explicitly to blocks --- code/ui/blocks/src/blocks/Subtitle.tsx | 2 +- code/ui/blocks/src/blocks/Title.tsx | 2 +- code/ui/blocks/src/components/ArgsTable/ArgsTable.tsx | 2 +- code/ui/blocks/src/components/ColorPalette.tsx | 2 +- code/ui/blocks/src/components/EmptyBlock.tsx | 4 +++- code/ui/blocks/src/components/IconGallery.tsx | 2 +- code/ui/blocks/src/components/Preview.tsx | 2 +- code/ui/blocks/src/components/Source.tsx | 2 +- code/ui/blocks/src/components/Story.tsx | 2 +- code/ui/blocks/src/components/Typeset.tsx | 2 +- 10 files changed, 12 insertions(+), 10 deletions(-) diff --git a/code/ui/blocks/src/blocks/Subtitle.tsx b/code/ui/blocks/src/blocks/Subtitle.tsx index f8f9d09630e2..139b028d2512 100644 --- a/code/ui/blocks/src/blocks/Subtitle.tsx +++ b/code/ui/blocks/src/blocks/Subtitle.tsx @@ -14,5 +14,5 @@ export const Subtitle: FunctionComponent = ({ children }) => { if (!text) { text = parameters?.componentSubtitle; } - return text ? {text} : null; + return text ? {text} : null; }; diff --git a/code/ui/blocks/src/blocks/Title.tsx b/code/ui/blocks/src/blocks/Title.tsx index 42ae7b3c6493..b8cfccea204a 100644 --- a/code/ui/blocks/src/blocks/Title.tsx +++ b/code/ui/blocks/src/blocks/Title.tsx @@ -21,5 +21,5 @@ export const Title: FunctionComponent = ({ children }) => { if (!text) { text = extractTitle(context.storyById().title); } - return text ? {text} : null; + return text ? {text} : null; }; diff --git a/code/ui/blocks/src/components/ArgsTable/ArgsTable.tsx b/code/ui/blocks/src/components/ArgsTable/ArgsTable.tsx index b0147faff0c4..c4ffeb0d8c2b 100644 --- a/code/ui/blocks/src/components/ArgsTable/ArgsTable.tsx +++ b/code/ui/blocks/src/components/ArgsTable/ArgsTable.tsx @@ -423,7 +423,7 @@ export const ArgsTable: FC = (props) => { diff --git a/code/ui/blocks/src/components/ColorPalette.tsx b/code/ui/blocks/src/components/ColorPalette.tsx index 5e018b24388e..4bf8d3e91401 100644 --- a/code/ui/blocks/src/components/ColorPalette.tsx +++ b/code/ui/blocks/src/components/ColorPalette.tsx @@ -202,7 +202,7 @@ interface ColorPaletteProps { */ export const ColorPalette: FunctionComponent = ({ children, ...props }) => ( - + Name Swatches diff --git a/code/ui/blocks/src/components/EmptyBlock.tsx b/code/ui/blocks/src/components/EmptyBlock.tsx index 41e84c48070b..7eff60b19ffd 100644 --- a/code/ui/blocks/src/components/EmptyBlock.tsx +++ b/code/ui/blocks/src/components/EmptyBlock.tsx @@ -17,4 +17,6 @@ const Wrapper = styled.div(withReset, ({ theme }) => ({ fontSize: theme.typography.size.s2, })); -export const EmptyBlock = (props: any) => ; +export const EmptyBlock = (props: any) => ( + +); diff --git a/code/ui/blocks/src/components/IconGallery.tsx b/code/ui/blocks/src/components/IconGallery.tsx index 22456d889ae2..8ea2be3b32d6 100644 --- a/code/ui/blocks/src/components/IconGallery.tsx +++ b/code/ui/blocks/src/components/IconGallery.tsx @@ -68,7 +68,7 @@ interface IconGalleryProps { */ export const IconGallery: FunctionComponent = ({ children, ...props }) => ( - + {children} diff --git a/code/ui/blocks/src/components/Preview.tsx b/code/ui/blocks/src/components/Preview.tsx index fd8dd3289823..acb71cebd2d8 100644 --- a/code/ui/blocks/src/components/Preview.tsx +++ b/code/ui/blocks/src/components/Preview.tsx @@ -193,7 +193,7 @@ export const Preview: FC = ({ const [expanded, setExpanded] = useState(isExpanded); const { source, actionItem } = getSource(withSource, expanded, setExpanded); const [scale, setScale] = useState(1); - const previewClasses = [className].concat(['sbdocs', 'sbdocs-preview']); + const previewClasses = [className].concat(['sbdocs', 'sbdocs-preview', 'sb-unstyled']); const defaultActionItems = withSource ? [actionItem] : []; const [additionalActionItems, setAdditionalActionItems] = useState( diff --git a/code/ui/blocks/src/components/Source.tsx b/code/ui/blocks/src/components/Source.tsx index c9296eafdf07..94d3df6b9ef9 100644 --- a/code/ui/blocks/src/components/Source.tsx +++ b/code/ui/blocks/src/components/Source.tsx @@ -108,7 +108,7 @@ const Source: FunctionComponent = ({ copyable format={format} language={language} - className="docblock-source" + className="docblock-source sb-unstyled" {...rest} > {code} diff --git a/code/ui/blocks/src/components/Story.tsx b/code/ui/blocks/src/components/Story.tsx index 78153eae5ef5..7fa72271d20c 100644 --- a/code/ui/blocks/src/components/Story.tsx +++ b/code/ui/blocks/src/components/Story.tsx @@ -105,7 +105,7 @@ const Story: FunctionComponent = (props) => { const { inline } = props; return ( -
+
{inline ? ( ) : ( diff --git a/code/ui/blocks/src/components/Typeset.tsx b/code/ui/blocks/src/components/Typeset.tsx index 35f0dda5f31d..8fbfca58b568 100644 --- a/code/ui/blocks/src/components/Typeset.tsx +++ b/code/ui/blocks/src/components/Typeset.tsx @@ -51,7 +51,7 @@ export const Typeset: FC = ({ sampleText, ...props }) => ( - + {fontSizes.map((size) => ( From 08ab4773b0f50dfe75b2737dee6a64ce45667390 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Fri, 17 Feb 2023 23:49:11 +0100 Subject: [PATCH 2/8] remove random Docs key for legacy Angular inline docs --- code/addons/docs/src/DocsRenderer.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/code/addons/docs/src/DocsRenderer.tsx b/code/addons/docs/src/DocsRenderer.tsx index 6c02b09e974f..15c06f093998 100644 --- a/code/addons/docs/src/DocsRenderer.tsx +++ b/code/addons/docs/src/DocsRenderer.tsx @@ -22,9 +22,6 @@ export class DocsRenderer { element: HTMLElement, callback: () => void ): void => { - // Use a random key to force the container to re-render each time we call `renderDocs` - // TODO: do we still need this? It was needed for angular (legacy) inline rendering: - // https://github.com/storybookjs/storybook/pull/16149 const components = { ...defaultComponents, ...docsParameter?.components, @@ -33,7 +30,7 @@ export class DocsRenderer { import('@mdx-js/react').then(({ MDXProvider }) => { ReactDOM.render( - + , element, callback From fb8a9061ef446d278a5af46d30209aa57bb4e393 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Sat, 18 Feb 2023 00:00:52 +0100 Subject: [PATCH 3/8] make global docs styles actually global, in a layer. --- code/ui/blocks/src/components/DocsPage.tsx | 615 ++++++++++----------- 1 file changed, 304 insertions(+), 311 deletions(-) diff --git a/code/ui/blocks/src/components/DocsPage.tsx b/code/ui/blocks/src/components/DocsPage.tsx index 86e487dcc865..a14d51a8362a 100644 --- a/code/ui/blocks/src/components/DocsPage.tsx +++ b/code/ui/blocks/src/components/DocsPage.tsx @@ -1,46 +1,30 @@ import { withReset } from '@storybook/components'; import type { CSSObject } from '@storybook/theming'; -import { styled } from '@storybook/theming'; +import type { GlobalProps } from '@emotion/react'; +import { Global, styled } from '@storybook/theming'; 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(div:not(.sb-unstyled, .sbdocs-preview... :where(.sb-unstyled, .sbdocs-preview...) div)) + * :where(.sbdocs-content div:not(.sb-unstyled, .sb-anchor, .sb-unstyled div, .sb-unstyled 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, .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. + * 1. ':where': ensures this has a specificity of 0, making it easier to override. + * 2. '.sbdocs-content': anything in DocsContent + * 3. 'div:not(...)': selects all div elements that are not... + * 4. '.sb-anchor': Ensures anchors are not styled, which would have led to inheritable styles bleeding all the way down to stories + * 5. '.sb-unstyled, .sb-unstyled div': any element with sb-unstyled class, or descendants thereof + * 6. .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 the 'sb-unstyled' class or the block. + * + * Most Storybook doc blocks has the sb-unstyled class to opt-out of the default styles. */ -const UNSTYLED_SELECTORS = [ - '.sb-unstyled', - '.sbdocs-preview', - '.sbdocs-pre', - '.sb-story', - '.docblock-source', - '.docblock-argstable', - '.sbdocs-title', - '.sbdocs-subtitle', - '.docblock-icongallery', - '.docblock-emptyblock', - '.docblock-typeset', - '.docblock-colorpalette', -].join(', '); const toGlobalSelector = (element: string): string => - `& :where(${element}:not(${UNSTYLED_SELECTORS}, :where(${UNSTYLED_SELECTORS}) ${element}))`; + `:where(.sbdocs-content ${element}:not(.sb-anchor, .sb-unstyled, .sb-unstyled ${element}))`; const breakpoint = 600; -export interface DocsPageProps { - title: string; - subtitle?: string; -} - export const Title = styled.h1(withReset, ({ theme }) => ({ color: theme.color.defaultText, fontSize: theme.typography.size.m3, @@ -70,8 +54,8 @@ export const Subtitle = styled.h2(withReset, ({ theme }) => ({ color: transparentize(0.25, theme.color.defaultText), })); -// @ts-expect-error don't know why it doesn't accept our returned styles. if we add `...{}` anywhere to the returned object it stops erroring -export const DocsContent = styled.div(({ theme }) => { +// @ts-expect-error Emotion types are hard... +export const globalDocsStyles: GlobalProps['styles'] = (theme) => { const reset = { fontFamily: theme.typography.fonts.base, fontSize: theme.typography.size.s3, @@ -120,323 +104,331 @@ export const DocsContent = styled.div(({ theme }) => { }; return { - maxWidth: 1000, - width: '100%', - [toGlobalSelector('a')]: { - ...reset, - fontSize: 'inherit', - lineHeight: '24px', + // use a CSS Cascade Layer to make the style even less specific, and easier to override + '@layer sb-docs': { + [toGlobalSelector('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, - }, - }, - [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, + 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, + }, }, - }, - [toGlobalSelector('div')]: reset, - [toGlobalSelector('dl')]: { - ...reset, - margin: '16px 0', - padding: 0, - '& dt': { - fontSize: '14px', - fontWeight: 'bold', - fontStyle: 'italic', - padding: 0, - margin: '16px 0 4px', + [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, + }, }, - '& dt:first-of-type': { + [toGlobalSelector('div')]: reset, + [toGlobalSelector('dl')]: { + ...reset, + margin: '16px 0', padding: 0, - }, - '& dt > :first-of-type': { - marginTop: 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, - }, + '& dt > :last-child': { + marginBottom: 0, + }, - '& dd': { - margin: '0 0 16px', - padding: '0 15px', - }, + '& dd': { + margin: '0 0 16px', + padding: '0 15px', + }, - '& dd > :first-of-type': { - marginTop: 0, - }, + '& 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.bold, - }, - [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', + '& dd > :last-child': { + marginBottom: 0, + }, }, - '& ul, & ol': { - marginTop: '.25em', - marginBottom: 0, + [toGlobalSelector('h1')]: { + ...reset, + ...headers, + fontSize: `${theme.typography.size.l1}px`, + fontWeight: theme.typography.weight.bold, + }, + [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, }, - '& code': code, - }, - [toGlobalSelector('ol')]: { - ...reset, - margin: '16px 0', - paddingLeft: 30, - '& :first-of-type': { - marginTop: 0, + [toGlobalSelector('img')]: { + maxWidth: '100%', }, - '& :last-child': { - marginBottom: 0, + [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('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, + [toGlobalSelector('ol')]: { + ...reset, + margin: '16px 0', + paddingLeft: 30, + '& :first-of-type': { + marginTop: 0, + }, + '& :last-child': { + marginBottom: 0, + }, }, - '& pre, &.prismjs': { - padding: 15, - margin: 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', - fontSize: '13px', - lineHeight: '19px', - code: { + 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: 'inherit', + fontSize: '13px', + lineHeight: '19px', + code: { + color: 'inherit', + fontSize: 'inherit', + }, + }, + '& code': { + whiteSpace: 'pre', + }, + '& code, & tt': { + border: 'none', }, }, - '& code': { - whiteSpace: 'pre', - }, - '& code, & tt': { - border: 'none', - }, - }, - [toGlobalSelector('span')]: { - ...reset, - '&.frame': { - display: 'block', - overflow: 'hidden', - - '& > span': { - border: `1px solid ${theme.color.medium}`, + [toGlobalSelector('span')]: { + ...reset, + '&.frame': { display: 'block', - float: 'left', overflow: 'hidden', - margin: '13px 0 0', - padding: 7, - width: 'auto', + + '& > 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', + }, }, - '& span img': { + '&.align-center': { display: 'block', - float: 'left', - }, - '& span span': { + overflow: 'hidden', clear: 'both', - color: theme.color.darkest, - display: 'block', - padding: '5px 0 0', - }, - }, - '&.align-center': { - display: 'block', - overflow: 'hidden', - clear: 'both', - '& > span': { + '& > span': { + display: 'block', + overflow: 'hidden', + margin: '13px auto 0', + textAlign: 'center', + }, + '& span img': { + margin: '0 auto', + textAlign: 'center', + }, + }, + '&.align-right': { 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', + clear: 'both', - '& > span': { + '& > 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', - 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: 'left', + '& span': { + margin: '13px 0 0', + }, }, - }, - '&.float-right': { - display: 'block', - marginLeft: 13, - overflow: 'hidden', - float: 'right', - - '& > span': { + '&.float-right': { display: 'block', + marginLeft: 13, overflow: 'hidden', - margin: '13px auto 0', - textAlign: 'right', + 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, + [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, + }, }, - '& 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, + [toGlobalSelector('ul')]: { + ...reset, + margin: '16px 0', + paddingLeft: 30, + '& :first-of-type': { + marginTop: 0, + }, + '& :last-child': { + marginBottom: 0, + }, + listStyle: 'disc', }, - listStyle: 'disc', }, }; +}; + +export const DocsContent = styled.div(({ theme }) => { + return { + maxWidth: 1000, + width: '100%', + }; }); export const DocsWrapper = styled.div(({ theme }) => ({ @@ -455,7 +447,8 @@ interface DocsPageWrapperProps { } export const DocsPageWrapper: FC = ({ children }) => ( - - {children} + + + {children} ); From 7d3ca8cfb1b94fbc29bb1404a744a3606e0ab41b Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Sat, 18 Feb 2023 00:01:27 +0100 Subject: [PATCH 4/8] encapsulate and use DocsWrapper+DocsContent everywhere --- code/ui/.storybook/preview.tsx | 10 ++++------ code/ui/blocks/src/blocks/DocsContainer.tsx | 6 ++---- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/code/ui/.storybook/preview.tsx b/code/ui/.storybook/preview.tsx index 703ae846724a..ed08e0fd9886 100644 --- a/code/ui/.storybook/preview.tsx +++ b/code/ui/.storybook/preview.tsx @@ -18,7 +18,7 @@ import type { Channel } from '@storybook/channels'; import { DocsContext } from '@storybook/blocks'; -import { DocsContent, DocsWrapper } from '../blocks/src/components'; +import { DocsPageWrapper } from '../blocks/src/components'; const { document } = global; @@ -150,11 +150,9 @@ export const decorators = [ * Activated with parameters.docsStyles = true */ (Story, { parameters: { docsStyles } }) => docsStyles ? ( - - - - - + + + ) : ( ), diff --git a/code/ui/blocks/src/blocks/DocsContainer.tsx b/code/ui/blocks/src/blocks/DocsContainer.tsx index 2885838ac926..dec9974a3569 100644 --- a/code/ui/blocks/src/blocks/DocsContainer.tsx +++ b/code/ui/blocks/src/blocks/DocsContainer.tsx @@ -4,7 +4,7 @@ import { global } from '@storybook/global'; import type { ThemeVars } from '@storybook/theming'; import { ThemeProvider, ensure as ensureTheme } from '@storybook/theming'; import type { Renderer } from '@storybook/types'; -import { DocsWrapper, DocsContent } from '../components'; +import { DocsPageWrapper } from '../components'; import type { DocsContextProps } from './DocsContext'; import { DocsContext } from './DocsContext'; import { SourceContainer } from './SourceContainer'; @@ -45,9 +45,7 @@ export const DocsContainer: FunctionComponent = ({ - - {children} - + {children} From e5449ec8421759285d1c4f1b2cce08aa676af389 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Sat, 18 Feb 2023 21:44:49 +0100 Subject: [PATCH 5/8] fix types --- code/ui/blocks/src/components/DocsPage.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/code/ui/blocks/src/components/DocsPage.tsx b/code/ui/blocks/src/components/DocsPage.tsx index a14d51a8362a..ee4d610002d4 100644 --- a/code/ui/blocks/src/components/DocsPage.tsx +++ b/code/ui/blocks/src/components/DocsPage.tsx @@ -1,6 +1,5 @@ import { withReset } from '@storybook/components'; -import type { CSSObject } from '@storybook/theming'; -import type { GlobalProps } from '@emotion/react'; +import type { CSSObject, StorybookTheme } from '@storybook/theming'; import { Global, styled } from '@storybook/theming'; import { transparentize } from 'polished'; import type { FC } from 'react'; @@ -54,8 +53,7 @@ export const Subtitle = styled.h2(withReset, ({ theme }) => ({ color: transparentize(0.25, theme.color.defaultText), })); -// @ts-expect-error Emotion types are hard... -export const globalDocsStyles: GlobalProps['styles'] = (theme) => { +export const globalDocsStyles = (theme: StorybookTheme) => { const reset = { fontFamily: theme.typography.fonts.base, fontSize: theme.typography.size.s3, From 3561e085d7c4d1e7cc1bd4b51e48f00ba74c0b61 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Sat, 18 Feb 2023 23:21:05 +0100 Subject: [PATCH 6/8] fix types for real --- code/ui/blocks/src/components/DocsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ui/blocks/src/components/DocsPage.tsx b/code/ui/blocks/src/components/DocsPage.tsx index ee4d610002d4..e918ab4e1d1f 100644 --- a/code/ui/blocks/src/components/DocsPage.tsx +++ b/code/ui/blocks/src/components/DocsPage.tsx @@ -53,7 +53,7 @@ export const Subtitle = styled.h2(withReset, ({ theme }) => ({ color: transparentize(0.25, theme.color.defaultText), })); -export const globalDocsStyles = (theme: StorybookTheme) => { +export const globalDocsStyles = (theme: StorybookTheme): any => { const reset = { fontFamily: theme.typography.fonts.base, fontSize: theme.typography.size.s3, From 3fd6831afa53aaaeb2203098ddecd7b52e15d9dd Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Mon, 20 Feb 2023 22:11:36 +0100 Subject: [PATCH 7/8] revert CSS Cascade Layer approach --- code/ui/blocks/src/components/DocsPage.tsx | 576 ++++++++++----------- 1 file changed, 283 insertions(+), 293 deletions(-) diff --git a/code/ui/blocks/src/components/DocsPage.tsx b/code/ui/blocks/src/components/DocsPage.tsx index e918ab4e1d1f..c8141db410fd 100644 --- a/code/ui/blocks/src/components/DocsPage.tsx +++ b/code/ui/blocks/src/components/DocsPage.tsx @@ -1,16 +1,15 @@ import { withReset } from '@storybook/components'; -import type { CSSObject, StorybookTheme } from '@storybook/theming'; -import { Global, styled } from '@storybook/theming'; +import type { CSSObject } from '@storybook/theming'; +import { styled } from '@storybook/theming'; 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(.sbdocs-content div:not(.sb-unstyled, .sb-anchor, .sb-unstyled div, .sb-unstyled div)) + * :where(div:not(.sb-unstyled, .sb-anchor, .sb-unstyled div, .sb-unstyled div)) * * 1. ':where': ensures this has a specificity of 0, making it easier to override. - * 2. '.sbdocs-content': anything in DocsContent * 3. 'div:not(...)': selects all div elements that are not... * 4. '.sb-anchor': Ensures anchors are not styled, which would have led to inheritable styles bleeding all the way down to stories * 5. '.sb-unstyled, .sb-unstyled div': any element with sb-unstyled class, or descendants thereof @@ -20,7 +19,7 @@ import React from 'react'; * Most Storybook doc blocks has the sb-unstyled class to opt-out of the default styles. */ const toGlobalSelector = (element: string): string => - `:where(.sbdocs-content ${element}:not(.sb-anchor, .sb-unstyled, .sb-unstyled ${element}))`; + `& :where(${element}:not(.sb-anchor, .sb-unstyled, .sb-unstyled ${element}))`; const breakpoint = 600; @@ -53,7 +52,7 @@ export const Subtitle = styled.h2(withReset, ({ theme }) => ({ color: transparentize(0.25, theme.color.defaultText), })); -export const globalDocsStyles = (theme: StorybookTheme): any => { +export const DocsContent = styled.div(({ theme }) => { const reset = { fontFamily: theme.typography.fonts.base, fontSize: theme.typography.size.s3, @@ -102,330 +101,322 @@ export const globalDocsStyles = (theme: StorybookTheme): any => { }; return { - // use a CSS Cascade Layer to make the style even less specific, and easier to override - '@layer sb-docs': { - [toGlobalSelector('a')]: { - ...reset, - fontSize: 'inherit', - lineHeight: '24px', + maxWidth: 1000, + width: '100%', + [toGlobalSelector('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, - }, + color: theme.color.secondary, + textDecoration: 'none', + '&.absent': { + color: '#cc0000', }, - [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, - }, + '&.anchor': { + display: 'block', + paddingLeft: 30, + marginLeft: -30, + cursor: 'pointer', + position: 'absolute', + top: 0, + left: 0, + 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', + }, + [toGlobalSelector('div')]: reset, + [toGlobalSelector('dl')]: { + ...reset, + margin: '16px 0', + padding: 0, + '& dt': { + fontSize: '14px', + fontWeight: 'bold', + fontStyle: 'italic', 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, - }, + margin: '16px 0 4px', + }, + '& dt:first-of-type': { + padding: 0, + }, + '& dt > :first-of-type': { + marginTop: 0, + }, - '& dt > :last-child': { - marginBottom: 0, - }, + '& dt > :last-child': { + marginBottom: 0, + }, - '& dd': { - margin: '0 0 16px', - padding: '0 15px', - }, + '& dd': { + margin: '0 0 16px', + padding: '0 15px', + }, - '& dd > :first-of-type': { - marginTop: 0, - }, + '& dd > :first-of-type': { + marginTop: 0, + }, - '& dd > :last-child': { - marginBottom: 0, - }, + '& dd > :last-child': { + marginBottom: 0, }, - [toGlobalSelector('h1')]: { - ...reset, - ...headers, - fontSize: `${theme.typography.size.l1}px`, - fontWeight: theme.typography.weight.bold, - }, - [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('h1')]: { + ...reset, + ...headers, + fontSize: `${theme.typography.size.l1}px`, + fontWeight: theme.typography.weight.bold, + }, + [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', }, - [toGlobalSelector('img')]: { - maxWidth: '100%', + '& ul, & ol': { + marginTop: '.25em', + marginBottom: 0, }, - [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, + '& code': code, + }, + [toGlobalSelector('ol')]: { + ...reset, + margin: '16px 0', + paddingLeft: 30, + '& :first-of-type': { + marginTop: 0, }, - [toGlobalSelector('ol')]: { - ...reset, - margin: '16px 0', - paddingLeft: 30, - '& :first-of-type': { - marginTop: 0, - }, - '& :last-child': { - marginBottom: 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', + }, + [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', - 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', + fontSize: '13px', + lineHeight: '19px', + code: { color: 'inherit', - fontSize: '13px', - lineHeight: '19px', - code: { - color: 'inherit', - fontSize: 'inherit', - }, - }, - '& code': { - whiteSpace: 'pre', - }, - '& code, & tt': { - border: 'none', + fontSize: 'inherit', }, }, - [toGlobalSelector('span')]: { - ...reset, - '&.frame': { - display: 'block', - overflow: 'hidden', + '& 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': { + '& > span': { + border: `1px solid ${theme.color.medium}`, display: 'block', + float: 'left', overflow: 'hidden', - clear: 'both', - - '& > span': { - display: 'block', - overflow: 'hidden', - margin: '13px auto 0', - textAlign: 'center', - }, - '& span img': { - margin: '0 auto', - textAlign: 'center', - }, + margin: '13px 0 0', + padding: 7, + width: 'auto', }, - '&.align-right': { + '& span img': { 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': { + '& span span': { + clear: 'both', + color: theme.color.darkest, display: 'block', - marginLeft: 13, - overflow: 'hidden', - float: 'right', - - '& > span': { - display: 'block', - overflow: 'hidden', - margin: '13px auto 0', - textAlign: 'right', - }, + padding: '5px 0 0', }, }, - [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, + '&.align-center': { + display: 'block', + overflow: 'hidden', + clear: 'both', + + '& > span': { + display: 'block', + overflow: 'hidden', + margin: '13px auto 0', + textAlign: 'center', }, - '& tr:nth-of-type(2n)': { - backgroundColor: theme.base === 'dark' ? theme.color.darker : theme.color.lighter, + '& span img': { + margin: '0 auto', + textAlign: 'center', }, - '& tr th': { - fontWeight: 'bold', - color: theme.color.defaultText, - border: `1px solid ${theme.appBorderColor}`, - margin: 0, - padding: '6px 13px', + }, + '&.align-right': { + display: 'block', + overflow: 'hidden', + clear: 'both', + + '& > span': { + display: 'block', + overflow: 'hidden', + margin: '13px 0 0', + textAlign: 'right', }, - '& tr td': { - border: `1px solid ${theme.appBorderColor}`, - color: theme.color.defaultText, + '& span img': { 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, + textAlign: 'right', }, }, - [toGlobalSelector('ul')]: { - ...reset, - margin: '16px 0', - paddingLeft: 30, - '& :first-of-type': { - marginTop: 0, + '&.float-left': { + display: 'block', + marginRight: 13, + overflow: 'hidden', + float: 'left', + '& span': { + margin: '13px 0 0', }, - '& :last-child': { - marginBottom: 0, + }, + '&.float-right': { + display: 'block', + marginLeft: 13, + overflow: 'hidden', + float: 'right', + + '& > span': { + display: 'block', + overflow: 'hidden', + margin: '13px auto 0', + textAlign: 'right', }, - listStyle: 'disc', }, }, - }; -}; - -export const DocsContent = styled.div(({ theme }) => { - return { - maxWidth: 1000, - width: '100%', + [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', + }, }; }); @@ -446,7 +437,6 @@ interface DocsPageWrapperProps { export const DocsPageWrapper: FC = ({ children }) => ( - {children} ); From 35bec31eb0341b61395a35f677fa21cbef792780 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 21 Feb 2023 00:08:12 +0100 Subject: [PATCH 8/8] fix type error --- code/ui/blocks/src/components/DocsPage.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/code/ui/blocks/src/components/DocsPage.tsx b/code/ui/blocks/src/components/DocsPage.tsx index c8141db410fd..d7dded1379a4 100644 --- a/code/ui/blocks/src/components/DocsPage.tsx +++ b/code/ui/blocks/src/components/DocsPage.tsx @@ -52,6 +52,7 @@ export const Subtitle = styled.h2(withReset, ({ theme }) => ({ color: transparentize(0.25, theme.color.defaultText), })); +// @ts-expect-error don't know why it doesn't accept our returned styles. if we add `...{}` anywhere to the returned object it stops erroring export const DocsContent = styled.div(({ theme }) => { const reset = { fontFamily: theme.typography.fonts.base,