diff --git a/addons/docs/package.json b/addons/docs/package.json index a289e8449363..31f1113d81cb 100644 --- a/addons/docs/package.json +++ b/addons/docs/package.json @@ -64,6 +64,8 @@ "lodash": "^4.17.15", "prop-types": "^15.7.2", "react-element-to-jsx-string": "^14.1.0", + "remark-external-links": "^5.0.0", + "remark-slug": "^5.1.2", "ts-dedent": "^1.1.0", "util-deprecate": "^1.0.2", "vue-docgen-api": "^3.26.0", diff --git a/addons/docs/src/blocks/Anchor.tsx b/addons/docs/src/blocks/Anchor.tsx index 912f20258eeb..7ed1160cfd74 100644 --- a/addons/docs/src/blocks/Anchor.tsx +++ b/addons/docs/src/blocks/Anchor.tsx @@ -1,4 +1,4 @@ -import React, { FunctionComponent } from 'react'; +import React, { FC } from 'react'; export const anchorBlockIdFromId = (storyId: string) => `anchor--${storyId}`; @@ -6,6 +6,6 @@ export interface AnchorProps { storyId: string; } -export const Anchor: FunctionComponent = ({ storyId, children }) => ( +export const Anchor: FC = ({ storyId, children }) => (
{children}
); diff --git a/addons/docs/src/blocks/DocsContainer.tsx b/addons/docs/src/blocks/DocsContainer.tsx index a415bac0b7d1..cedf8e18f4de 100644 --- a/addons/docs/src/blocks/DocsContainer.tsx +++ b/addons/docs/src/blocks/DocsContainer.tsx @@ -1,44 +1,24 @@ import React, { FunctionComponent, useEffect } from 'react'; -import { document } from 'global'; +import { document, window } from 'global'; import { MDXProvider } from '@mdx-js/react'; import { ThemeProvider, ensure as ensureTheme } from '@storybook/theming'; -import { DocsWrapper, DocsContent, Source } from '@storybook/components'; -import { components as htmlComponents, Code } from '@storybook/components/html'; +import { DocsWrapper, DocsContent } from '@storybook/components'; +import { components as htmlComponents } from '@storybook/components/html'; import { DocsContextProps, DocsContext } from './DocsContext'; import { anchorBlockIdFromId } from './Anchor'; import { storyBlockIdFromId } from './Story'; +import { CodeOrSourceMdx, AnchorMdx, HeadersMdx } from './mdx'; +import { scrollToElement } from './utils'; interface DocsContainerProps { context: DocsContextProps; } -interface CodeOrSourceProps { - className?: string; -} -export const CodeOrSource: FunctionComponent = props => { - const { className, children, ...rest } = props; - // markdown-to-jsx does not add className to inline code - if ( - typeof className !== 'string' && - (typeof children !== 'string' || !(children as string).match(/[\n\r]/g)) - ) { - return {children}; - } - // className: "lang-jsx" - const language = className && className.split('-'); - return ( - - ); -}; - const defaultComponents = { ...htmlComponents, - code: CodeOrSource, + code: CodeOrSourceMdx, + a: AnchorMdx, + ...HeadersMdx, }; export const DocsContainer: FunctionComponent = ({ context, children }) => { @@ -46,30 +26,40 @@ export const DocsContainer: FunctionComponent = ({ context, const options = parameters.options || {}; const theme = ensureTheme(options.theme); const { components: userComponents = null } = parameters.docs || {}; - const components = { ...defaultComponents, ...userComponents }; + const allComponents = { ...defaultComponents, ...userComponents }; useEffect(() => { - let element = document.getElementById(anchorBlockIdFromId(storyId)); - if (!element) { - element = document.getElementById(storyBlockIdFromId(storyId)); - } - if (element) { - const allStories = element.parentElement.querySelectorAll('[id|="anchor-"]'); - let block = 'start'; - if (allStories && allStories[0] === element) { - block = 'end'; // first story should be shown with the intro content above + const url = new URL(window.parent.location); + if (url.hash) { + const element = document.getElementById(url.hash.substring(1)); + if (element) { + // Introducing a delay to ensure scrolling works when it's a full refresh. + setTimeout(() => { + scrollToElement(element); + }, 200); + } + } else { + const element = + document.getElementById(anchorBlockIdFromId(storyId)) || + document.getElementById(storyBlockIdFromId(storyId)); + if (element) { + const allStories = element.parentElement.querySelectorAll('[id|="anchor-"]'); + let block = 'start'; + if (allStories && allStories[0] === element) { + block = 'end'; // first story should be shown with the intro content above + } + // Introducing a delay to ensure scrolling works when it's a full refresh. + setTimeout(() => { + scrollToElement(element, block); + }, 200); } - element.scrollIntoView({ - behavior: 'smooth', - block, - inline: 'nearest', - }); } }, [storyId]); + return ( - + {children} diff --git a/addons/docs/src/blocks/mdx.tsx b/addons/docs/src/blocks/mdx.tsx index 2f580d923114..9f3e6f17fda1 100644 --- a/addons/docs/src/blocks/mdx.tsx +++ b/addons/docs/src/blocks/mdx.tsx @@ -1,14 +1,203 @@ -import * as React from 'react'; +import React, { FC, SyntheticEvent } from 'react'; +import { Source } from '@storybook/components'; +import { Code, components } from '@storybook/components/html'; +import { document, window } from 'global'; +import { isNil } from 'lodash'; +import { styled } from '@storybook/theming'; import { DocsContext, DocsContextProps } from './DocsContext'; +import { scrollToElement } from './utils'; // Hacky utility for dealing with functions or values in MDX Story elements export const makeStoryFn = (val: any) => (typeof val === 'function' ? val : () => val); // Hacky utilty for adding mdxStoryToId to the default context -export const AddContext: React.FC = props => { +export const AddContext: FC = props => { const { children, ...rest } = props; const parentContext = React.useContext(DocsContext); return ( {children} ); }; + +interface CodeOrSourceMdxProps { + className?: string; +} + +export const CodeOrSourceMdx: FC = ({ className, children, ...rest }) => { + // markdown-to-jsx does not add className to inline code + if ( + typeof className !== 'string' && + (typeof children !== 'string' || !(children as string).match(/[\n\r]/g)) + ) { + return {children}; + } + // className: "lang-jsx" + const language = className && className.split('-'); + return ( + + ); +}; + +function generateHrefWithHash(hash: string): string { + const url = new URL(window.parent.location); + const href = `${url.origin}/${url.search}#${hash}`; + + return href; +} + +// @ts-ignore +const A = components.a; + +interface AnchorInPageProps { + hash: string; +} + +const AnchorInPage: FC = ({ hash, children }) => ( + { + event.preventDefault(); + + const hashValue = hash.substring(1); + const element = document.getElementById(hashValue); + if (!isNil(element)) { + window.parent.history.replaceState(null, '', generateHrefWithHash(hashValue)); + scrollToElement(element); + } + }} + > + {children} + +); + +interface AnchorMdxProps { + href: string; + target: string; +} + +export const AnchorMdx: FC = props => { + const { href, target, children, ...rest } = props; + + if (!isNil(href)) { + // Enable scrolling for in-page anchors. + if (href.startsWith('#')) { + return {children}; + } + + // Links to other pages of SB should use the base URL of the top level iframe instead of the base URL of the preview iframe. + if (target !== '_blank') { + const parentUrl = new URL(window.parent.location.href); + const newHref = `${parentUrl.origin}${href}`; + + return ( + + {children} + + ); + } + } + + // External URL dont need any modification. + return ; +}; + +const SUPPORTED_MDX_HEADERS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']; + +const OcticonHeaders = SUPPORTED_MDX_HEADERS.reduce( + (acc, headerType) => ({ + ...acc, + // @ts-ignore + [headerType]: styled(components[headerType])({ + '& svg': { + visibility: 'hidden', + }, + '&:hover svg': { + visibility: 'visible', + }, + }), + }), + {} +); + +const OcticonAnchor = styled.a(() => ({ + float: 'left', + paddingRight: '4px', + marginLeft: '-20px', +})); + +interface HeaderWithOcticonAnchorProps { + as: string; + id: string; + children: any; +} + +const HeaderWithOcticonAnchor: FC = ({ + as, + id, + children, + ...rest +}) => { + // @ts-ignore + const OcticonHeader = OcticonHeaders[as]; + + return ( + + + {children} + + ); +}; + +interface HeaderMdxProps { + as: string; + id: string; +} + +const HeaderMdx: FC = props => { + const { as, id, children, ...rest } = props; + + // An id should have been added on every header by the "remark-slug" plugin. + if (!isNil(id)) { + return ( + + {children} + + ); + } + + // @ts-ignore + const Header = components[as]; + + // Make sure it still work if "remark-slug" plugin is not present. + return
; +}; + +export const HeadersMdx = SUPPORTED_MDX_HEADERS.reduce( + (acc, headerType) => ({ + ...acc, + // @ts-ignore + [headerType]: (props: object) => , + }), + {} +); diff --git a/addons/docs/src/blocks/utils.ts b/addons/docs/src/blocks/utils.ts index 316c6bae4a92..92129cca1801 100644 --- a/addons/docs/src/blocks/utils.ts +++ b/addons/docs/src/blocks/utils.ts @@ -32,3 +32,11 @@ export const getComponentName = (component: Component): string => { return component.name; }; + +export function scrollToElement(element: any, block = 'start') { + element.scrollIntoView({ + behavior: 'smooth', + block, + inline: 'nearest', + }); +} diff --git a/addons/docs/src/frameworks/common/preset.ts b/addons/docs/src/frameworks/common/preset.ts index 79a1a84ebaf8..ce48d65c65f5 100644 --- a/addons/docs/src/frameworks/common/preset.ts +++ b/addons/docs/src/frameworks/common/preset.ts @@ -1,5 +1,7 @@ /* eslint-disable import/no-extraneous-dependencies */ import createCompiler from '@storybook/addon-docs/mdx-compiler-plugin'; +import remarkSlug from 'remark-slug'; +import remarkExternalLinks from 'remark-external-links'; function createBabelOptions(babelOptions?: any, configureJSX?: boolean) { if (!configureJSX) { @@ -26,6 +28,10 @@ export function webpack(webpackConfig: any = {}, options: any = {}) { sourceLoaderOptions = {}, } = options; + const mdxLoaderOptions = { + remarkPlugins: [remarkSlug, remarkExternalLinks], + }; + // set `sourceLoaderOptions` to `null` to disable for manual configuration const sourceLoader = sourceLoaderOptions ? [ @@ -67,6 +73,7 @@ export function webpack(webpackConfig: any = {}, options: any = {}) { loader: '@mdx-js/loader', options: { compilers: [createCompiler(options)], + ...mdxLoaderOptions, }, }, ], @@ -81,6 +88,7 @@ export function webpack(webpackConfig: any = {}, options: any = {}) { }, { loader: '@mdx-js/loader', + options: mdxLoaderOptions, }, ], }, diff --git a/addons/docs/src/typings.d.ts b/addons/docs/src/typings.d.ts index 179e926ed6ae..dc9928da3997 100644 --- a/addons/docs/src/typings.d.ts +++ b/addons/docs/src/typings.d.ts @@ -4,3 +4,5 @@ declare module '@storybook/addon-docs/blocks'; declare module 'global'; declare module 'react-is'; declare module '@egoist/vue-to-react'; +declare module "remark-slug"; +declare module "remark-external-links"; diff --git a/examples/cra-ts-kitchen-sink/src/stories/anchors/anchors.stories.mdx b/examples/cra-ts-kitchen-sink/src/stories/anchors/anchors.stories.mdx new file mode 100644 index 000000000000..fa27a4109c98 --- /dev/null +++ b/examples/cra-ts-kitchen-sink/src/stories/anchors/anchors.stories.mdx @@ -0,0 +1,62 @@ +import { Meta } from '@storybook/addon-docs/blocks'; + + + +go to bottom + +## Hey + +Some code!!! +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque leo dolor, pharetra non arcu vel, accumsan commodo ligula. Vestibulum ut nulla mauris. Mauris vehicula pharetra sem, ac semper quam euismod eget. Fusce sit amet laoreet leo. Maecenas vitae mollis nibh. Morbi ullamcorper justo at enim malesuada, non porta augue ullamcorper. Etiam varius ultrices nisi, eu pharetra lacus sollicitudin eu. Suspendisse sit amet tincidunt dolor, a lobortis lectus.

+

Quisque venenatis placerat est, sed pulvinar dui cursus ut. Curabitur rutrum odio sit amet est bibendum maximus. Nulla euismod finibus condimentum. Vestibulum finibus, felis nec malesuada accumsan, urna velit convallis ligula, ut pharetra lacus lorem elementum nunc. Donec ac massa eget massa auctor rhoncus at et nulla. Nam sollicitudin, mauris eget egestas pellentesque, leo eros tincidunt felis, in luctus metus tortor sit amet tortor. Mauris ut velit vitae ipsum pharetra consequat. Vivamus id magna quis orci congue fringilla. Vestibulum vitae mollis risus.

+

Phasellus eu mauris lacus. Fusce nec ante non ante condimentum ullamcorper. Phasellus condimentum massa vitae diam dignissim volutpat. Aenean ut dignissim felis. Suspendisse vitae sollicitudin est, vel dapibus elit. Nullam auctor dui et erat sagittis, quis imperdiet tellus consequat. Donec eu auctor nulla. Pellentesque sed leo lectus. Quisque molestie, urna non gravida vestibulum, nulla augue pellentesque neque, sed ultrices quam diam id metus.

+

Etiam nec suscipit nunc. Vestibulum in euismod neque, eu vehicula tellus. Praesent id suscipit nunc. Pellentesque non orci egestas, bibendum magna et, commodo lorem. Phasellus et convallis arcu, ac dapibus velit. Integer ac pellentesque nibh. Aenean erat magna, hendrerit bibendum fringilla a, maximus eu mi. Curabitur pulvinar pulvinar pellentesque. Duis in dapibus enim.

+

Integer vitae convallis velit. Integer ut turpis risus. Nunc non dui vitae est aliquam tempus nec ac nibh. Integer condimentum libero lorem, vitae ultrices neque commodo sit amet. Sed et lacinia sapien. Sed mattis magna eu nunc varius vehicula. Ut id velit vitae nunc aliquet iaculis. Proin enim turpis, ultricies vel vulputate in, pharetra at mauris. Duis non tincidunt augue.

+ +## Ho + +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque leo dolor, pharetra non arcu vel, accumsan commodo ligula. Vestibulum ut nulla mauris. Mauris vehicula pharetra sem, ac semper quam euismod eget. Fusce sit amet laoreet leo. Maecenas vitae mollis nibh. Morbi ullamcorper justo at enim malesuada, non porta augue ullamcorper. Etiam varius ultrices nisi, eu pharetra lacus sollicitudin eu. Suspendisse sit amet tincidunt dolor, a lobortis lectus.

+

Quisque venenatis placerat est, sed pulvinar dui cursus ut. Curabitur rutrum odio sit amet est bibendum maximus. Nulla euismod finibus condimentum. Vestibulum finibus, felis nec malesuada accumsan, urna velit convallis ligula, ut pharetra lacus lorem elementum nunc. Donec ac massa eget massa auctor rhoncus at et nulla. Nam sollicitudin, mauris eget egestas pellentesque, leo eros tincidunt felis, in luctus metus tortor sit amet tortor. Mauris ut velit vitae ipsum pharetra consequat. Vivamus id magna quis orci congue fringilla. Vestibulum vitae mollis risus.

+

Phasellus eu mauris lacus. Fusce nec ante non ante condimentum ullamcorper. Phasellus condimentum massa vitae diam dignissim volutpat. Aenean ut dignissim felis. Suspendisse vitae sollicitudin est, vel dapibus elit. Nullam auctor dui et erat sagittis, quis imperdiet tellus consequat. Donec eu auctor nulla. Pellentesque sed leo lectus. Quisque molestie, urna non gravida vestibulum, nulla augue pellentesque neque, sed ultrices quam diam id metus.

+

Etiam nec suscipit nunc. Vestibulum in euismod neque, eu vehicula tellus. Praesent id suscipit nunc. Pellentesque non orci egestas, bibendum magna et, commodo lorem. Phasellus et convallis arcu, ac dapibus velit. Integer ac pellentesque nibh. Aenean erat magna, hendrerit bibendum fringilla a, maximus eu mi. Curabitur pulvinar pulvinar pellentesque. Duis in dapibus enim.

+

Integer vitae convallis velit. Integer ut turpis risus. Nunc non dui vitae est aliquam tempus nec ac nibh. Integer condimentum libero lorem, vitae ultrices neque commodo sit amet. Sed et lacinia sapien. Sed mattis magna eu nunc varius vehicula. Ut id velit vitae nunc aliquet iaculis. Proin enim turpis, ultricies vel vulputate in, pharetra at mauris. Duis non tincidunt augue.

+ +## Hey + +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque leo dolor, pharetra non arcu vel, accumsan commodo ligula. Vestibulum ut nulla mauris. Mauris vehicula pharetra sem, ac semper quam euismod eget. Fusce sit amet laoreet leo. Maecenas vitae mollis nibh. Morbi ullamcorper justo at enim malesuada, non porta augue ullamcorper. Etiam varius ultrices nisi, eu pharetra lacus sollicitudin eu. Suspendisse sit amet tincidunt dolor, a lobortis lectus.

+

Quisque venenatis placerat est, sed pulvinar dui cursus ut. Curabitur rutrum odio sit amet est bibendum maximus. Nulla euismod finibus condimentum. Vestibulum finibus, felis nec malesuada accumsan, urna velit convallis ligula, ut pharetra lacus lorem elementum nunc. Donec ac massa eget massa auctor rhoncus at et nulla. Nam sollicitudin, mauris eget egestas pellentesque, leo eros tincidunt felis, in luctus metus tortor sit amet tortor. Mauris ut velit vitae ipsum pharetra consequat. Vivamus id magna quis orci congue fringilla. Vestibulum vitae mollis risus.

+

Phasellus eu mauris lacus. Fusce nec ante non ante condimentum ullamcorper. Phasellus condimentum massa vitae diam dignissim volutpat. Aenean ut dignissim felis. Suspendisse vitae sollicitudin est, vel dapibus elit. Nullam auctor dui et erat sagittis, quis imperdiet tellus consequat. Donec eu auctor nulla. Pellentesque sed leo lectus. Quisque molestie, urna non gravida vestibulum, nulla augue pellentesque neque, sed ultrices quam diam id metus.

+

Etiam nec suscipit nunc. Vestibulum in euismod neque, eu vehicula tellus. Praesent id suscipit nunc. Pellentesque non orci egestas, bibendum magna et, commodo lorem. Phasellus et convallis arcu, ac dapibus velit. Integer ac pellentesque nibh. Aenean erat magna, hendrerit bibendum fringilla a, maximus eu mi. Curabitur pulvinar pulvinar pellentesque. Duis in dapibus enim.

+

Integer vitae convallis velit. Integer ut turpis risus. Nunc non dui vitae est aliquam tempus nec ac nibh. Integer condimentum libero lorem, vitae ultrices neque commodo sit amet. Sed et lacinia sapien. Sed mattis magna eu nunc varius vehicula. Ut id velit vitae nunc aliquet iaculis. Proin enim turpis, ultricies vel vulputate in, pharetra at mauris. Duis non tincidunt augue.

+ +## Ho + +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque leo dolor, pharetra non arcu vel, accumsan commodo ligula. Vestibulum ut nulla mauris. Mauris vehicula pharetra sem, ac semper quam euismod eget. Fusce sit amet laoreet leo. Maecenas vitae mollis nibh. Morbi ullamcorper justo at enim malesuada, non porta augue ullamcorper. Etiam varius ultrices nisi, eu pharetra lacus sollicitudin eu. Suspendisse sit amet tincidunt dolor, a lobortis lectus.

+

Quisque venenatis placerat est, sed pulvinar dui cursus ut. Curabitur rutrum odio sit amet est bibendum maximus. Nulla euismod finibus condimentum. Vestibulum finibus, felis nec malesuada accumsan, urna velit convallis ligula, ut pharetra lacus lorem elementum nunc. Donec ac massa eget massa auctor rhoncus at et nulla. Nam sollicitudin, mauris eget egestas pellentesque, leo eros tincidunt felis, in luctus metus tortor sit amet tortor. Mauris ut velit vitae ipsum pharetra consequat. Vivamus id magna quis orci congue fringilla. Vestibulum vitae mollis risus.

+

Phasellus eu mauris lacus. Fusce nec ante non ante condimentum ullamcorper. Phasellus condimentum massa vitae diam dignissim volutpat. Aenean ut dignissim felis. Suspendisse vitae sollicitudin est, vel dapibus elit. Nullam auctor dui et erat sagittis, quis imperdiet tellus consequat. Donec eu auctor nulla. Pellentesque sed leo lectus. Quisque molestie, urna non gravida vestibulum, nulla augue pellentesque neque, sed ultrices quam diam id metus.

+

Etiam nec suscipit nunc. Vestibulum in euismod neque, eu vehicula tellus. Praesent id suscipit nunc. Pellentesque non orci egestas, bibendum magna et, commodo lorem. Phasellus et convallis arcu, ac dapibus velit. Integer ac pellentesque nibh. Aenean erat magna, hendrerit bibendum fringilla a, maximus eu mi. Curabitur pulvinar pulvinar pellentesque. Duis in dapibus enim.

+

Integer vitae convallis velit. Integer ut turpis risus. Nunc non dui vitae est aliquam tempus nec ac nibh. Integer condimentum libero lorem, vitae ultrices neque commodo sit amet. Sed et lacinia sapien. Sed mattis magna eu nunc varius vehicula. Ut id velit vitae nunc aliquet iaculis. Proin enim turpis, ultricies vel vulputate in, pharetra at mauris. Duis non tincidunt augue.

+ +## Hey + +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque leo dolor, pharetra non arcu vel, accumsan commodo ligula. Vestibulum ut nulla mauris. Mauris vehicula pharetra sem, ac semper quam euismod eget. Fusce sit amet laoreet leo. Maecenas vitae mollis nibh. Morbi ullamcorper justo at enim malesuada, non porta augue ullamcorper. Etiam varius ultrices nisi, eu pharetra lacus sollicitudin eu. Suspendisse sit amet tincidunt dolor, a lobortis lectus.

+

Quisque venenatis placerat est, sed pulvinar dui cursus ut. Curabitur rutrum odio sit amet est bibendum maximus. Nulla euismod finibus condimentum. Vestibulum finibus, felis nec malesuada accumsan, urna velit convallis ligula, ut pharetra lacus lorem elementum nunc. Donec ac massa eget massa auctor rhoncus at et nulla. Nam sollicitudin, mauris eget egestas pellentesque, leo eros tincidunt felis, in luctus metus tortor sit amet tortor. Mauris ut velit vitae ipsum pharetra consequat. Vivamus id magna quis orci congue fringilla. Vestibulum vitae mollis risus.

+

Phasellus eu mauris lacus. Fusce nec ante non ante condimentum ullamcorper. Phasellus condimentum massa vitae diam dignissim volutpat. Aenean ut dignissim felis. Suspendisse vitae sollicitudin est, vel dapibus elit. Nullam auctor dui et erat sagittis, quis imperdiet tellus consequat. Donec eu auctor nulla. Pellentesque sed leo lectus. Quisque molestie, urna non gravida vestibulum, nulla augue pellentesque neque, sed ultrices quam diam id metus.

+

Etiam nec suscipit nunc. Vestibulum in euismod neque, eu vehicula tellus. Praesent id suscipit nunc. Pellentesque non orci egestas, bibendum magna et, commodo lorem. Phasellus et convallis arcu, ac dapibus velit. Integer ac pellentesque nibh. Aenean erat magna, hendrerit bibendum fringilla a, maximus eu mi. Curabitur pulvinar pulvinar pellentesque. Duis in dapibus enim.

+

Integer vitae convallis velit. Integer ut turpis risus. Nunc non dui vitae est aliquam tempus nec ac nibh. Integer condimentum libero lorem, vitae ultrices neque commodo sit amet. Sed et lacinia sapien. Sed mattis magna eu nunc varius vehicula. Ut id velit vitae nunc aliquet iaculis. Proin enim turpis, ultricies vel vulputate in, pharetra at mauris. Duis non tincidunt augue.

+ +## Ho + +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque leo dolor, pharetra non arcu vel, accumsan commodo ligula. Vestibulum ut nulla mauris. Mauris vehicula pharetra sem, ac semper quam euismod eget. Fusce sit amet laoreet leo. Maecenas vitae mollis nibh. Morbi ullamcorper justo at enim malesuada, non porta augue ullamcorper. Etiam varius ultrices nisi, eu pharetra lacus sollicitudin eu. Suspendisse sit amet tincidunt dolor, a lobortis lectus.

+

Quisque venenatis placerat est, sed pulvinar dui cursus ut. Curabitur rutrum odio sit amet est bibendum maximus. Nulla euismod finibus condimentum. Vestibulum finibus, felis nec malesuada accumsan, urna velit convallis ligula, ut pharetra lacus lorem elementum nunc. Donec ac massa eget massa auctor rhoncus at et nulla. Nam sollicitudin, mauris eget egestas pellentesque, leo eros tincidunt felis, in luctus metus tortor sit amet tortor. Mauris ut velit vitae ipsum pharetra consequat. Vivamus id magna quis orci congue fringilla. Vestibulum vitae mollis risus.

+

Phasellus eu mauris lacus. Fusce nec ante non ante condimentum ullamcorper. Phasellus condimentum massa vitae diam dignissim volutpat. Aenean ut dignissim felis. Suspendisse vitae sollicitudin est, vel dapibus elit. Nullam auctor dui et erat sagittis, quis imperdiet tellus consequat. Donec eu auctor nulla. Pellentesque sed leo lectus. Quisque molestie, urna non gravida vestibulum, nulla augue pellentesque neque, sed ultrices quam diam id metus.

+

Etiam nec suscipit nunc. Vestibulum in euismod neque, eu vehicula tellus. Praesent id suscipit nunc. Pellentesque non orci egestas, bibendum magna et, commodo lorem. Phasellus et convallis arcu, ac dapibus velit. Integer ac pellentesque nibh. Aenean erat magna, hendrerit bibendum fringilla a, maximus eu mi. Curabitur pulvinar pulvinar pellentesque. Duis in dapibus enim.

+

Integer vitae convallis velit. Integer ut turpis risus. Nunc non dui vitae est aliquam tempus nec ac nibh. Integer condimentum libero lorem, vitae ultrices neque commodo sit amet. Sed et lacinia sapien. Sed mattis magna eu nunc varius vehicula. Ut id velit vitae nunc aliquet iaculis. Proin enim turpis, ultricies vel vulputate in, pharetra at mauris. Duis non tincidunt augue.

+ +## Bottom + +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque leo dolor, pharetra non arcu vel, accumsan commodo ligula. Vestibulum ut nulla mauris. Mauris vehicula pharetra sem, ac semper quam euismod eget. Fusce sit amet laoreet leo. Maecenas vitae mollis nibh. Morbi ullamcorper justo at enim malesuada, non porta augue ullamcorper. Etiam varius ultrices nisi, eu pharetra lacus sollicitudin eu. Suspendisse sit amet tincidunt dolor, a lobortis lectus.

+

Quisque venenatis placerat est, sed pulvinar dui cursus ut. Curabitur rutrum odio sit amet est bibendum maximus. Nulla euismod finibus condimentum. Vestibulum finibus, felis nec malesuada accumsan, urna velit convallis ligula, ut pharetra lacus lorem elementum nunc. Donec ac massa eget massa auctor rhoncus at et nulla. Nam sollicitudin, mauris eget egestas pellentesque, leo eros tincidunt felis, in luctus metus tortor sit amet tortor. Mauris ut velit vitae ipsum pharetra consequat. Vivamus id magna quis orci congue fringilla. Vestibulum vitae mollis risus.

+

Phasellus eu mauris lacus. Fusce nec ante non ante condimentum ullamcorper. Phasellus condimentum massa vitae diam dignissim volutpat. Aenean ut dignissim felis. Suspendisse vitae sollicitudin est, vel dapibus elit. Nullam auctor dui et erat sagittis, quis imperdiet tellus consequat. Donec eu auctor nulla. Pellentesque sed leo lectus. Quisque molestie, urna non gravida vestibulum, nulla augue pellentesque neque, sed ultrices quam diam id metus.

+

Etiam nec suscipit nunc. Vestibulum in euismod neque, eu vehicula tellus. Praesent id suscipit nunc. Pellentesque non orci egestas, bibendum magna et, commodo lorem. Phasellus et convallis arcu, ac dapibus velit. Integer ac pellentesque nibh. Aenean erat magna, hendrerit bibendum fringilla a, maximus eu mi. Curabitur pulvinar pulvinar pellentesque. Duis in dapibus enim.

+

Integer vitae convallis velit. Integer ut turpis risus. Nunc non dui vitae est aliquam tempus nec ac nibh. Integer condimentum libero lorem, vitae ultrices neque commodo sit amet. Sed et lacinia sapien. Sed mattis magna eu nunc varius vehicula. Ut id velit vitae nunc aliquet iaculis. Proin enim turpis, ultricies vel vulputate in, pharetra at mauris. Duis non tincidunt augue.

\ No newline at end of file diff --git a/examples/cra-ts-kitchen-sink/src/stories/props-sort.stories.mdx b/examples/cra-ts-kitchen-sink/src/stories/props-sort.stories.mdx index 9e2346555868..5441e4f1f39b 100644 --- a/examples/cra-ts-kitchen-sink/src/stories/props-sort.stories.mdx +++ b/examples/cra-ts-kitchen-sink/src/stories/props-sort.stories.mdx @@ -1,5 +1,5 @@ import { PropsSort } from "./PropsSort"; -import { Props } from '@storybook/addon-docs/blocks'; +import { Props, Meta } from '@storybook/addon-docs/blocks'; diff --git a/examples/official-storybook/stories/addon-docs/docs-only.stories.mdx b/examples/official-storybook/stories/addon-docs/docs-only.stories.mdx index d748141b63f8..aef2c1db786e 100644 --- a/examples/official-storybook/stories/addon-docs/docs-only.stories.mdx +++ b/examples/official-storybook/stories/addon-docs/docs-only.stories.mdx @@ -7,3 +7,10 @@ import { Meta } from '@storybook/addon-docs/blocks'; This file is a documentation-only MDX file, i.e. it doesn't contain any `` definitions. Therefore, it shows up in the navigation UI as a document icon. + +


















+


















+ +## Bottom + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc faucibus urna id nibh mollis, varius facilisis sapien scelerisque. Pellentesque lobortis convallis mi, at accumsan nisl sollicitudin id. Aliquam vitae elementum libero. Nulla blandit est turpis, a consectetur ante rhoncus a. Integer eu quam eu mauris pharetra elementum. Donec ex nisl, tincidunt ut tincidunt id, bibendum ut sem. Sed in congue tortor, a congue dolor. Fusce a magna vel nulla laoreet sagittis. diff --git a/examples/official-storybook/stories/addon-docs/markdown.stories.mdx b/examples/official-storybook/stories/addon-docs/markdown.stories.mdx index a711700e13ce..077715496817 100644 --- a/examples/official-storybook/stories/addon-docs/markdown.stories.mdx +++ b/examples/official-storybook/stories/addon-docs/markdown.stories.mdx @@ -133,6 +133,10 @@ Right aligned columns [link with title](https://hichroma.com 'Insert title!') +[link to in page anchor](#h1-heading) + +[link to another story](/?path=/docs/addons-docs-docs-only--page#bottom) + ## Images ![Minion](https://octodex.github.com/images/minion.png) diff --git a/lib/components/src/html.tsx b/lib/components/src/html.tsx index 62f1ae83f4f3..9b45fa7c582f 100644 --- a/lib/components/src/html.tsx +++ b/lib/components/src/html.tsx @@ -6,9 +6,14 @@ export * from './typography/DocumentFormatting'; export const components = Object.entries(rawComponents).reduce( (acc, [k, V]) => ({ ...acc, - [k.toLowerCase()]: (props: object) => ( - - ), + [k.toLowerCase()]: ({ className, ...rest }: { className: string }) => { + return ( + + ); + }, }), {} ); diff --git a/yarn.lock b/yarn.lock index ab4d09cd38cd..ce30e4e3036c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11627,6 +11627,11 @@ emitter-mixin@0.0.3: resolved "https://registry.yarnpkg.com/emitter-mixin/-/emitter-mixin-0.0.3.tgz#5948cb286f2e48edc3b251a7cfc1f7883396d65c" integrity sha1-WUjLKG8uSO3DslGnz8H3iDOW1lw= +"emoji-regex@>=6.0.0 <=6.1.1": + version "6.1.1" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.1.1.tgz#c6cd0ec1b0642e2a3c67a1137efc5e796da4f88e" + integrity sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4= + emoji-regex@^7.0.1, emoji-regex@^7.0.2: version "7.0.3" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" @@ -14680,6 +14685,13 @@ github-release-from-changelog@^2.1.0: grizzly "^3.0.3" minimist "^1.2.0" +github-slugger@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.2.1.tgz#47e904e70bf2dccd0014748142d31126cfd49508" + integrity sha512-SsZUjg/P03KPzQBt7OxJPasGw6NRO5uOgiZ5RGXVud5iSIZ0eNZeNp5rTwCxtavrRUa/A77j8mePVc5lEvk0KQ== + dependencies: + emoji-regex ">=6.0.0 <=6.1.1" + gitlab@^10.0.1: version "10.2.1" resolved "https://registry.yarnpkg.com/gitlab/-/gitlab-10.2.1.tgz#1f5fb2c2bad08f95b7c7d91dd41805ab5eea3960" @@ -16406,7 +16418,7 @@ is-absolute-url@^2.0.0: resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= -is-absolute-url@^3.0.1, is-absolute-url@^3.0.3: +is-absolute-url@^3.0.0, is-absolute-url@^3.0.1, is-absolute-url@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== @@ -19957,7 +19969,7 @@ mdast-util-compact@^1.0.0: dependencies: unist-util-visit "^1.1.0" -mdast-util-definitions@^1.2.0: +mdast-util-definitions@^1.2.0, mdast-util-definitions@^1.2.3: version "1.2.5" resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-1.2.5.tgz#3fe622a4171c774ebd06f11e9f8af7ec53ea5c74" integrity sha512-CJXEdoLfiISCDc2JB6QLb79pYfI6+GcIH+W2ox9nMc7od0Pz+bovcHsiq29xAQY6ayqe/9CsK2VzkSJdg1pFYA== @@ -19986,7 +19998,7 @@ mdast-util-to-hast@6.0.2: unist-util-visit "^1.1.0" xtend "^4.0.1" -mdast-util-to-string@^1.0.2: +mdast-util-to-string@^1.0.0, mdast-util-to-string@^1.0.2: version "1.0.7" resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.0.7.tgz#62d8e9c6b2113070d8b497c7dc35bf12796f06ee" integrity sha512-P+gdtssCoHOX+eJUrrC30Sixqao86ZPlVjR5NEAoy0U79Pfxb1Y0Gntei0+GrnQD4T04X9xA8tcugp90cSmNow== @@ -26426,6 +26438,17 @@ remark-cli@^7.0.0, remark-cli@^7.0.1: remark "^11.0.0" unified-args "^7.0.0" +remark-external-links@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/remark-external-links/-/remark-external-links-5.0.0.tgz#e7fc0e0cc4c92d33fb195b08ed1dc691fdb1689a" + integrity sha512-lYnZGNN10N3YGMvO95Zup4hZ+VHI82JgcrGJfuxOLQExoho/iNhlrPVSkmdapYQl928pkOn4YOgJf/0pdZkteA== + dependencies: + extend "^3.0.0" + is-absolute-url "^3.0.0" + mdast-util-definitions "^1.2.3" + space-separated-tokens "^1.1.2" + unist-util-visit "^1.4.0" + remark-lint-final-newline@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/remark-lint-final-newline/-/remark-lint-final-newline-1.0.3.tgz#06c3d71ec7b97c16cde31543cd41a16b36c30f79" @@ -26672,6 +26695,15 @@ remark-preset-lint-recommended@^3.0.2: remark-lint-no-unused-definitions "^1.0.0" remark-lint-ordered-list-marker-style "^1.0.0" +remark-slug@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/remark-slug/-/remark-slug-5.1.2.tgz#715ecdef8df1226786204b1887d31ab16aa24609" + integrity sha512-DWX+Kd9iKycqyD+/B+gEFO3jjnt7Yg1O05lygYSNTe5i5PIxxxPjp5qPBDxPIzp5wreF7+1ROCwRgjEcqmzr3A== + dependencies: + github-slugger "^1.0.0" + mdast-util-to-string "^1.0.0" + unist-util-visit "^1.0.0" + remark-squeeze-paragraphs@3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-3.0.4.tgz#9fe50c3bf3b572dd88754cd426ada007c0b8dc5f" @@ -28415,7 +28447,7 @@ sourcemap-validator@^1.1.0: lodash.template "^4.5.0" source-map "~0.1.x" -space-separated-tokens@^1.0.0: +space-separated-tokens@^1.0.0, space-separated-tokens@^1.1.2: version "1.1.4" resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.4.tgz#27910835ae00d0adfcdbd0ad7e611fb9544351fa" integrity sha512-UyhMSmeIqZrQn2UdjYpxEkwY9JUrn8pP+7L4f91zRzOQuI8MF1FGLfYU9DKCYeLdo7LXMxwrX5zKFy7eeeVHuA==