Skip to content

Commit

Permalink
[docs] Show the JSX by default for small examples (#17831)
Browse files Browse the repository at this point in the history
  • Loading branch information
mbrookes authored and oliviertassinari committed Oct 19, 2019
1 parent 5c70cfc commit f8080a6
Show file tree
Hide file tree
Showing 45 changed files with 497 additions and 349 deletions.
252 changes: 130 additions & 122 deletions docs/src/modules/components/Demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import MarkdownElement from 'docs/src/modules/components/MarkdownElement';
import DemoSandboxed from 'docs/src/modules/components/DemoSandboxed';
import DemoLanguages from 'docs/src/modules/components/DemoLanguages';
import getDemoConfig from 'docs/src/modules/utils/getDemoConfig';
import getJsxPreview from 'docs/src/modules/utils/getJsxPreview';
import { getCookie } from 'docs/src/modules/utils/helpers';
import { ACTION_TYPES, CODE_VARIANTS } from 'docs/src/modules/constants';

Expand All @@ -39,7 +40,6 @@ function addHiddenInput(form, name, value) {

const styles = theme => ({
root: {
position: 'relative',
marginBottom: 40,
marginLeft: -theme.spacing(2),
marginRight: -theme.spacing(2),
Expand All @@ -50,6 +50,7 @@ const styles = theme => ({
},
},
demo: {
position: 'relative',
outline: 0,
margin: 'auto',
borderRadius: theme.shape.borderRadius,
Expand Down Expand Up @@ -77,6 +78,9 @@ const styles = theme => ({
},
justifyContent: 'space-between',
},
headerButtons: {
margin: '2px 0',
},
code: {
display: 'none',
padding: 0,
Expand All @@ -87,7 +91,6 @@ const styles = theme => ({
},
'& pre': {
overflow: 'auto',
paddingTop: theme.spacing(5),
margin: '0px !important',
maxHeight: 1000,
},
Expand Down Expand Up @@ -263,150 +266,155 @@ function Demo(props) {

const match = useMediaQuery(theme => theme.breakpoints.up('sm'));

const jsx = getJsxPreview(demoData.raw || '', demoOptions.defaultCodeOpen);
const showPreview =
!demoOptions.hideHeader && jsx !== demoData.raw && jsx.split(/\n/).length <= 20;

let showCodeLabel;
if (codeOpen) {
showCodeLabel = showPreview ? t('hideFullSource') : t('hideSource');
} else {
showCodeLabel = showPreview ? t('showFullSource') : t('showSource');
}

return (
<div className={classes.root}>
<div
className={clsx(classes.demo, {
[classes.demoHiddenHeader]: demoOptions.hideHeader,
})}
tabIndex={-1}
onMouseEnter={handleDemoHover}
onMouseLeave={handleDemoHover}
>
<DemoSandboxed
style={demoSandboxedStyle}
component={DemoComponent}
iframe={demoOptions.iframe}
name={demoName}
/>
</div>
<div className={classes.anchorLink} id={`${demoName}.js`} />
<div className={classes.anchorLink} id={`${demoName}.tsx`} />
{demoOptions.hideHeader ? null : (
<div>
<div className={classes.header}>
<DemoLanguages
demo={demo}
codeOpen={codeOpen}
codeVariant={codeVariant}
gaEventCategory={gaCategory}
onLanguageClick={handleCodeLanguageClick}
/>
<div>
<Tooltip
classes={{ popper: classes.tooltip }}
key={showSourceHint}
open={showSourceHint && match ? true : undefined}
PopperProps={{ disablePortal: true }}
title={codeOpen ? t('hideSource') : t('showSource')}
placement="top"
<div className={classes.header}>
<DemoLanguages
demo={demo}
codeOpen={codeOpen}
codeVariant={codeVariant}
gaEventCategory={gaCategory}
onLanguageClick={handleCodeLanguageClick}
/>
<div className={classes.headerButtons}>
<Tooltip
classes={{ popper: classes.tooltip }}
key={showSourceHint}
open={showSourceHint && match ? true : undefined}
PopperProps={{ disablePortal: true }}
title={showCodeLabel}
placement="top"
>
<IconButton
aria-label={showCodeLabel}
data-ga-event-category={gaCategory}
data-ga-event-action="expand"
onClick={handleClickCodeOpen}
color={demoHovered ? 'primary' : 'default'}
>
<IconButton
aria-label={codeOpen ? t('hideSource') : t('showSource')}
data-ga-event-category={gaCategory}
data-ga-event-action="expand"
onClick={handleClickCodeOpen}
color={demoHovered ? 'primary' : 'default'}
>
<CodeIcon fontSize="small" />
</IconButton>
</Tooltip>
<CodeIcon fontSize="small" />
</IconButton>
</Tooltip>
<Tooltip classes={{ popper: classes.tooltip }} title={t('viewGitHub')} placement="top">
<IconButton
aria-label={t('viewGitHub')}
data-ga-event-category={gaCategory}
data-ga-event-action="github"
href={demoData.githubLocation}
target="_blank"
rel="noopener nofollow"
>
<GitHubIcon fontSize="small" />
</IconButton>
</Tooltip>
{demoOptions.hideEditButton ? null : (
<Tooltip
classes={{ popper: classes.tooltip }}
title={t('viewGitHub')}
title={t('codesandbox')}
placement="top"
>
<IconButton
aria-label={t('viewGitHub')}
aria-label={t('codesandbox')}
data-ga-event-category={gaCategory}
data-ga-event-action="github"
href={demoData.githubLocation}
target="_blank"
rel="noopener nofollow"
data-ga-event-action="codesandbox"
onClick={handleClickCodeSandbox}
>
<GitHubIcon fontSize="small" />
<EditIcon fontSize="small" />
</IconButton>
</Tooltip>
{demoOptions.hideEditButton ? null : (
<Tooltip
classes={{ popper: classes.tooltip }}
title={t('codesandbox')}
placement="top"
>
<IconButton
aria-label={t('codesandbox')}
data-ga-event-category={gaCategory}
data-ga-event-action="codesandbox"
onClick={handleClickCodeSandbox}
>
<EditIcon fontSize="small" />
</IconButton>
</Tooltip>
)}
<IconButton
onClick={handleClickMore}
aria-owns={anchorEl ? 'demo-menu-more' : undefined}
aria-haspopup="true"
aria-label={t('seeMore')}
)}
<IconButton
onClick={handleClickMore}
aria-owns={anchorEl ? 'demo-menu-more' : undefined}
aria-haspopup="true"
aria-label={t('seeMore')}
>
<MoreVertIcon fontSize="small" />
</IconButton>
<Menu
id="demo-menu-more"
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={handleCloseMore}
getContentAnchorEl={null}
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
>
<MenuItem
data-ga-event-category={gaCategory}
data-ga-event-action="copy"
onClick={handleClickCopy}
>
<MoreVertIcon fontSize="small" />
</IconButton>
<Menu
id="demo-menu-more"
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={handleCloseMore}
getContentAnchorEl={null}
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
>
<MenuItem
data-ga-event-category={gaCategory}
data-ga-event-action="copy"
onClick={handleClickCopy}
>
{t('copySource')}
</MenuItem>
{demoOptions.hideEditButton ? null : (
<MenuItem
data-ga-event-category={gaCategory}
data-ga-event-action="stackblitz"
onClick={handleClickStackBlitz}
>
{t('stackblitz')}
</MenuItem>
)}
<MenuItem
data-ga-event-category={gaCategory}
data-ga-event-action="copy-js-source-link"
onClick={createHandleCodeSourceLink(`${demoName}.js`)}
>
{t('copySourceLinkJS')}
</MenuItem>
{t('copySource')}
</MenuItem>
{demoOptions.hideEditButton ? null : (
<MenuItem
data-ga-event-category={gaCategory}
data-ga-event-action="copy-ts-source-link"
onClick={createHandleCodeSourceLink(`${demoName}.tsx`)}
data-ga-event-action="stackblitz"
onClick={handleClickStackBlitz}
>
{t('copySourceLinkTS')}
{t('stackblitz')}
</MenuItem>
</Menu>
</div>
)}
<MenuItem
data-ga-event-category={gaCategory}
data-ga-event-action="copy-js-source-link"
onClick={createHandleCodeSourceLink(`${demoName}.js`)}
>
{t('copySourceLinkJS')}
</MenuItem>
<MenuItem
data-ga-event-category={gaCategory}
data-ga-event-action="copy-ts-source-link"
onClick={createHandleCodeSourceLink(`${demoName}.tsx`)}
>
{t('copySourceLinkTS')}
</MenuItem>
</Menu>
</div>
<Collapse in={codeOpen} unmountOnExit>
<MarkdownElement
className={classes.code}
text={`\`\`\`${demoData.sourceLanguage}\n${demoData.raw}\n\`\`\``}
/>
</Collapse>
</div>
)}
<div
className={clsx(classes.demo, {
[classes.demoHiddenHeader]: demoOptions.hideHeader,
})}
tabIndex={-1}
onMouseEnter={handleDemoHover}
onMouseLeave={handleDemoHover}
>
<DemoSandboxed
style={demoSandboxedStyle}
component={DemoComponent}
iframe={demoOptions.iframe}
name={demoName}
<Collapse in={codeOpen || showPreview} unmountOnExit>
<MarkdownElement
className={classes.code}
text={`\`\`\`${demoData.sourceLanguage}\n${codeOpen ? demoData.raw : jsx}\n\`\`\``}
/>
</div>
</Collapse>
</div>
);
}
Expand Down
1 change: 1 addition & 0 deletions docs/src/modules/components/MarkdownDocs.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ function MarkdownDocs(props) {
try {
demoOptions = JSON.parse(`{${content}}`);
} catch (err) {
console.error('JSON.parse fails with: ', `{${content}}`);
console.error(err);
return null;
}
Expand Down
28 changes: 28 additions & 0 deletions docs/src/modules/utils/getJsxPreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export default function getJsxPreview(code, defaultCodeOpen) {
/* The regex matches the content of the return statement in the default export,
* stripping any wrapper divs:
*
* `export default.*`
* `\n return (\n` or `\n return `
* ` <div.*>\n` (optional)
* everything until:
* `\n </div>` (optional)
* ` );\n}` or `;\n}`
*/
let jsx = code.match(
/export default .*(?:\n {2}return \(\n|\n {2}return )(?: {4}<div.*?>\n)?(.*?)(\n {4}<\/div>)?(\n {2}\);\n}|;\n})/s,
);
// Just the match, otherwise the full source if either no match or preview disabled,
// so as not to break the Collapse transition.
jsx = jsx && defaultCodeOpen !== false ? jsx[1] : code;

// Remove leading spaces from each line
return jsx.split(/\n/).reduce(
(acc, line) =>
`${acc}${line.slice(
// Number of leading spaces on the first line
jsx.match(/^ */)[0].length,
)}\n`,
'',
);
}
Loading

0 comments on commit f8080a6

Please sign in to comment.