migrate all custom component styles to global styles

This commit is contained in:
Jeppe Reinhold 2022-11-29 21:19:45 +01:00
parent 23d345278e
commit b0fa9d707f
4 changed files with 371 additions and 4 deletions

View File

@ -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<string, any> = {
...htmlComponents,
code: CodeOrSourceMdx,
a: AnchorMdx,
...HeadersMdx,

View File

@ -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',

View File

@ -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 = () => (
<Source {...source.JSX.args} />
</DocsPageWrapper>
);
export const Html = {
name: 'HTML',
render: () => (
<DocsPageWrapper>
<h1>Heading 1</h1>
<h2>Heading 2</h2>
<a>A tag</a>
<pre>pre tag</pre>
<div>
<div>Div</div>
<a>Nested A tag</a>
</div>
<div className="sb-unstyled" style={{ border: '2px solid red' }}>
<h1>Unstyled content</h1>
<h2>Heading 2</h2>
<a>A tag</a>
<div>
<div>Div</div>
<a>Nested A tag</a>
</div>
</div>
</DocsPageWrapper>
),
};

View File

@ -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 `<p>`:
* :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',
},
};
});