Tidy up docs components [ci skip]

This commit is contained in:
Ines Montani 2020-08-06 01:22:49 +02:00
parent 30f316c688
commit 4d34efa697
31 changed files with 249 additions and 357 deletions

View File

@ -5,7 +5,7 @@ import classNames from 'classnames'
import Link from './link'
import classes from '../styles/accordion.module.sass'
const Accordion = ({ title, id, expanded, spaced, children }) => {
export default function Accordion({ title, id, expanded = false, spaced = false, children }) {
const [isExpanded, setIsExpanded] = useState(true)
const rootClassNames = classNames(classes.root, {
[classes.spaced]: !!spaced,
@ -59,14 +59,8 @@ const Accordion = ({ title, id, expanded, spaced, children }) => {
)
}
Accordion.defaultProps = {
expanded: false,
}
Accordion.propTypes = {
title: PropTypes.string,
id: PropTypes.string,
children: PropTypes.node.isRequired,
}
export default Accordion

View File

@ -5,7 +5,7 @@ import classNames from 'classnames'
import Icon from './icon'
import classes from '../styles/alert.module.sass'
const Alert = ({ title, icon, variant, closeOnClick, children }) => {
export default function Alert({ title, icon, variant, closeOnClick = true, children }) {
const [visible, setVisible] = useState(true)
const alertClassNames = classNames(classes.root, {
[classes.warning]: variant === 'warning',
@ -20,10 +20,6 @@ const Alert = ({ title, icon, variant, closeOnClick, children }) => {
)
}
Alert.defaultProps = {
closeOnClick: true,
}
Alert.propTypes = {
title: PropTypes.string,
icon: PropTypes.string,
@ -31,5 +27,3 @@ Alert.propTypes = {
closeOnClick: PropTypes.bool,
children: PropTypes.node,
}
export default Alert

View File

@ -3,20 +3,20 @@ import PropTypes from 'prop-types'
import classes from '../styles/aside.module.sass'
const Aside = ({ title, children }) => (
<aside className={classes.root}>
<div className={classes.content} role="complementary">
<div className={classes.text}>
{title && <h4 className={classes.title}>{title}</h4>}
{children}
export default function Aside({ title, children }) {
return (
<aside className={classes.root}>
<div className={classes.content} role="complementary">
<div className={classes.text}>
{title && <h4 className={classes.title}>{title}</h4>}
{children}
</div>
</div>
</div>
</aside>
)
</aside>
)
}
Aside.propTypes = {
title: PropTypes.string,
children: PropTypes.node.isRequired,
}
export default Aside

View File

@ -6,7 +6,15 @@ import Link from './link'
import Icon from './icon'
import classes from '../styles/button.module.sass'
const Button = ({ to, variant, large, icon, className, children, ...props }) => {
export default function Button({
to,
variant = 'secondary',
large = false,
icon,
className,
children,
...props
}) {
const buttonClassNames = classNames(classes.root, className, {
[classes.large]: large,
[classes.primary]: variant === 'primary',
@ -21,11 +29,6 @@ const Button = ({ to, variant, large, icon, className, children, ...props }) =>
)
}
Button.defaultProps = {
variant: 'secondary',
large: false,
}
Button.propTypes = {
to: PropTypes.string,
variant: PropTypes.oneOf(['primary', 'secondary', 'tertiary']),
@ -33,5 +36,3 @@ Button.propTypes = {
icon: PropTypes.string,
className: PropTypes.string,
}
export default Button

View File

@ -6,32 +6,34 @@ import Link from './link'
import { H5 } from './typography'
import classes from '../styles/card.module.sass'
const Card = ({ title, to, image, header, small, onClick, children }) => (
<div className={classNames(classes.root, { [classes.small]: !!small })}>
{header && (
export default function Card({ title, to, image, header, small, onClick, children }) {
return (
<div className={classNames(classes.root, { [classes.small]: !!small })}>
{header && (
<Link to={to} onClick={onClick} hidden>
{header}
</Link>
)}
{(title || image) && (
<H5 className={classes.title}>
{image && (
<div className={classes.image}>
<img src={image} width={35} alt="" />
</div>
)}
{title && (
<Link to={to} onClick={onClick} hidden>
{title}
</Link>
)}
</H5>
)}
<Link to={to} onClick={onClick} hidden>
{header}
{children}
</Link>
)}
{(title || image) && (
<H5 className={classes.title}>
{image && (
<div className={classes.image}>
<img src={image} width={35} alt="" />
</div>
)}
{title && (
<Link to={to} onClick={onClick} hidden>
{title}
</Link>
)}
</H5>
)}
<Link to={to} onClick={onClick} hidden>
{children}
</Link>
</div>
)
</div>
)
}
Card.propTypes = {
title: PropTypes.node,
@ -41,5 +43,3 @@ Card.propTypes = {
onClick: PropTypes.func,
children: PropTypes.node,
}
export default Card

View File

@ -21,7 +21,7 @@ export const Pre = props => {
return <pre className={classes.pre}>{props.children}</pre>
}
export const InlineCode = ({ wrap, className, children, ...props }) => {
export const InlineCode = ({ wrap = false, className, children, ...props }) => {
const codeClassNames = classNames(classes.inlineCode, className, {
[classes.wrap]: wrap || (isString(children) && children.length >= 20),
})
@ -32,10 +32,6 @@ export const InlineCode = ({ wrap, className, children, ...props }) => {
)
}
InlineCode.defaultProps = {
wrap: false,
}
InlineCode.propTypes = {
wrap: PropTypes.bool,
className: PropTypes.string,

View File

@ -14,7 +14,7 @@ export function copyToClipboard(ref, callback) {
}
}
const CopyInput = ({ text, prefix }) => {
export default function CopyInput({ text, prefix }) {
const isClient = typeof window !== 'undefined'
const supportsCopy = isClient && document.queryCommandSupported('copy')
const textareaRef = useRef()
@ -46,5 +46,3 @@ const CopyInput = ({ text, prefix }) => {
</div>
)
}
export default CopyInput

View File

@ -5,7 +5,7 @@ import { navigate } from 'gatsby'
import classes from '../styles/dropdown.module.sass'
const Dropdown = ({ defaultValue, className, onChange, children }) => {
export default function Dropdown({ defaultValue, className, onChange, children }) {
const defaultOnChange = ({ target }) => navigate(target.value)
return (
<select
@ -24,5 +24,3 @@ Dropdown.propTypes = {
onChange: PropTypes.func,
children: PropTypes.node.isRequired,
}
export default Dropdown

View File

@ -8,7 +8,7 @@ import { markdownToReact } from './util'
import classes from '../styles/embed.module.sass'
const YouTube = ({ id, ratio }) => {
const YouTube = ({ id, ratio = '16x9' }) => {
const embedClassNames = classNames(classes.root, classes.responsive, {
[classes.ratio16x9]: ratio === '16x9',
[classes.ratio4x3]: ratio === '4x3',
@ -28,16 +28,12 @@ const YouTube = ({ id, ratio }) => {
)
}
YouTube.defaultProps = {
ratio: '16x9',
}
YouTube.propTypes = {
id: PropTypes.string.isRequired,
ratio: PropTypes.oneOf(['16x9', '4x3']),
}
const SoundCloud = ({ id, color, title }) => {
const SoundCloud = ({ id, color = '09a3d5', title }) => {
const url = `https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/${id}&color=%23${color}&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true`
return (
<figure className={classes.root}>
@ -54,10 +50,6 @@ const SoundCloud = ({ id, color, title }) => {
)
}
SoundCloud.defaultProps = {
color: '09a3d5',
}
SoundCloud.propTypes = {
id: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
@ -69,7 +61,7 @@ function formatHTML(html) {
return `<html><head><meta charset="UTF-8"></head><body>${encoded}</body></html>`
}
const Iframe = ({ title, src, html, width, height }) => {
const Iframe = ({ title, src, html, width = 800, height = 300 }) => {
const source = html ? `data:text/html,${formatHTML(html)}` : src
return (
<iframe
@ -84,11 +76,6 @@ const Iframe = ({ title, src, html, width, height }) => {
)
}
Iframe.defaultProps = {
width: 800,
height: 300,
}
Iframe.propTypes = {
title: PropTypes.string.isRequired,
src: PropTypes.string,

View File

@ -9,68 +9,69 @@ import Newsletter from './newsletter'
import { ReactComponent as ExplosionLogo } from '../images/explosion.svg'
import classes from '../styles/footer.module.sass'
const Footer = ({ wide }) => (
<StaticQuery
query={query}
render={data => {
const { companyUrl, company, footer, newsletter } = data.site.siteMetadata
return (
<footer className={classes.root}>
<Grid cols={wide ? 4 : 3} narrow className={classes.content}>
{footer.map(({ label, items }, i) => (
<section key={i}>
export default function Footer({ wide = false }) {
return (
<StaticQuery
query={query}
render={data => {
const { companyUrl, company, footer, newsletter } = data.site.siteMetadata
return (
<footer className={classes.root}>
<Grid cols={wide ? 4 : 3} narrow className={classes.content}>
{footer.map(({ label, items }, i) => (
<section key={i}>
<ul className={classes.column}>
<li className={classes.label}>{label}</li>
{items.map(({ text, url }, j) => (
<li key={j}>
<Link to={url} hidden>
{text}
</Link>
</li>
))}
</ul>
</section>
))}
<section className={wide ? null : classes.full}>
<ul className={classes.column}>
<li className={classes.label}>{label}</li>
{items.map(({ text, url }, j) => (
<li key={j}>
<Link to={url} hidden>
{text}
</Link>
</li>
))}
<li className={classes.label}>Stay in the loop!</li>
<li>Receive updates about new releases, tutorials and more.</li>
<li>
<Newsletter {...newsletter} />
</li>
</ul>
</section>
))}
<section className={wide ? null : classes.full}>
<ul className={classes.column}>
<li className={classes.label}>Stay in the loop!</li>
<li>Receive updates about new releases, tutorials and more.</li>
<li>
<Newsletter {...newsletter} />
</li>
</ul>
</section>
</Grid>
<div className={classNames(classes.content, classes.copy)}>
<span>
&copy; 2016-{new Date().getFullYear()}{' '}
<Link to={companyUrl} hidden>
{company}
</Grid>
<div className={classNames(classes.content, classes.copy)}>
<span>
&copy; 2016-{new Date().getFullYear()}{' '}
<Link to={companyUrl} hidden>
{company}
</Link>
</span>
<Link
to={companyUrl}
aria-label={company}
hidden
className={classes.logo}
>
<ExplosionLogo width={45} height={45} />
</Link>
</span>
<Link to={companyUrl} aria-label={company} hidden className={classes.logo}>
<ExplosionLogo width={45} height={45} />
</Link>
<Link to={`${companyUrl}/legal`} hidden>
Legal / Imprint
</Link>
</div>
</footer>
)
}}
/>
)
Footer.defaultProps = {
wide: false,
<Link to={`${companyUrl}/legal`} hidden>
Legal / Imprint
</Link>
</div>
</footer>
)
}}
/>
)
}
Footer.propTypes = {
wide: PropTypes.bool,
}
export default Footer
const query = graphql`
query FooterQuery {
site {

View File

@ -13,7 +13,7 @@ Please use the link below to view the example. If you've come across
a broken link, we always appreciate a pull request to the repository,
or a report on the issue tracker. Thanks!`
const GitHubCode = ({ url, lang, errorMsg, className }) => {
const GitHubCode = ({ url, lang, errorMsg = defaultErrorMsg, className }) => {
const [initialized, setInitialized] = useState(false)
const [code, setCode] = useState(errorMsg)
const codeClassNames = classNames(classes.code, classes.maxHeight, className)
@ -56,10 +56,6 @@ const GitHubCode = ({ url, lang, errorMsg, className }) => {
)
}
GitHubCode.defaultProps = {
errorMsg: defaultErrorMsg,
}
GitHubCode.propTypes = {
url: PropTypes.string.isRequired,
lang: PropTypes.string,

View File

@ -4,7 +4,13 @@ import classNames from 'classnames'
import classes from '../styles/grid.module.sass'
const Grid = ({ cols, narrow, gutterBottom, className, children }) => {
export default function Grid({
cols = 1,
narrow = false,
gutterBottom = true,
className,
children,
}) {
const gridClassNames = classNames(classes.root, className, {
[classes.narrow]: narrow,
[classes.spacing]: gutterBottom,
@ -15,16 +21,8 @@ const Grid = ({ cols, narrow, gutterBottom, className, children }) => {
return <div className={gridClassNames}>{children}</div>
}
Grid.defaultProps = {
cols: 1,
narrow: false,
gutterBottom: true,
}
Grid.propTypes = {
cols: PropTypes.oneOf([1, 2, 3, 4]),
narrow: PropTypes.bool,
gutterBottom: PropTypes.bool,
}
export default Grid

View File

@ -51,7 +51,7 @@ const icons = {
download: DownloadIcon,
}
const Icon = ({ name, width, height, inline, variant, className }) => {
export default function Icon({ name, width = 20, height, inline = false, variant, className }) {
const IconComponent = icons[name]
const iconClassNames = classNames(classes.root, className, {
[classes.inline]: inline,
@ -69,11 +69,6 @@ const Icon = ({ name, width, height, inline, variant, className }) => {
)
}
Icon.defaultProps = {
width: 20,
inline: false,
}
Icon.propTypes = {
name: PropTypes.oneOf(Object.keys(icons)),
width: PropTypes.number,
@ -82,5 +77,3 @@ Icon.propTypes = {
variant: PropTypes.oneOf(['success', 'error', 'subtle']),
className: PropTypes.string,
}
export default Icon

View File

@ -5,7 +5,7 @@ import classNames from 'classnames'
import Icon from './icon'
import classes from '../styles/infobox.module.sass'
const Infobox = ({ title, emoji, id, variant, className, children }) => {
export default function Infobox({ title, emoji, id, variant = 'default', className, children }) {
const infoboxClassNames = classNames(classes.root, className, {
[classes.warning]: variant === 'warning',
[classes.danger]: variant === 'danger',
@ -32,10 +32,6 @@ const Infobox = ({ title, emoji, id, variant, className, children }) => {
)
}
Infobox.defaultProps = {
variant: 'default',
}
Infobox.propTypes = {
title: PropTypes.node,
id: PropTypes.string,
@ -43,5 +39,3 @@ Infobox.propTypes = {
className: PropTypes.string,
children: PropTypes.node.isRequired,
}
export default Infobox

View File

@ -8,7 +8,7 @@ import { OutputArea, OutputAreaModel } from '@jupyterlab/outputarea'
import { RenderMimeRegistry, standardRendererFactories } from '@jupyterlab/rendermime'
import { window } from 'browser-monads'
class Juniper extends React.Component {
export default class Juniper extends React.Component {
outputRef = null
inputRef = null
state = { kernel: null, renderers: null, fromStorage: null }
@ -270,5 +270,3 @@ Juniper.propTypes = {
output: PropTypes.string,
}),
}
export default Juniper

View File

@ -15,19 +15,19 @@ const Whitespace = ({ children }) => (
<> {children} </>
)
const Link = ({
export default function Link({
children,
to,
href,
onClick,
activeClassName,
hidden,
hideIcon,
ws,
forceExternal,
hidden = false,
hideIcon = false,
ws = false,
forceExternal = false,
className,
...other
}) => {
}) {
const dest = to || href
const external = forceExternal || /(http(s?)):\/\//gi.test(dest)
const isApi = !external && !hidden && !hideIcon && /^\/?api/.test(dest)
@ -100,13 +100,6 @@ export const OptionalLink = ({ to, href, children, ...props }) => {
)
}
Link.defaultProps = {
hidden: false,
hideIcon: false,
ws: false,
forceExternal: false,
}
Link.propTypes = {
children: PropTypes.node.isRequired,
to: PropTypes.string,
@ -118,5 +111,3 @@ Link.propTypes = {
ws: PropTypes.bool,
className: PropTypes.string,
}
export default Link

View File

@ -19,7 +19,14 @@ export const Content = ({ Component = 'div', className, children }) => (
<Component className={classNames(classes.content, className)}>{children}</Component>
)
const Main = ({ sidebar, asides, wrapContent, theme, footer, children }) => {
export default function Main({
sidebar = false,
asides = false,
wrapContent = false,
theme = 'blue',
footer,
children,
}) {
const pattern = patterns[theme]
const mainClassNames = classNames(classes.root, {
[classes.withSidebar]: sidebar,
@ -37,13 +44,6 @@ const Main = ({ sidebar, asides, wrapContent, theme, footer, children }) => {
)
}
Main.defaultProps = {
sidebar: false,
asides: false,
wrapContent: false,
theme: 'blue',
}
Main.propTypes = {
sidebar: PropTypes.bool,
asides: PropTypes.bool,
@ -51,5 +51,3 @@ Main.propTypes = {
theme: PropTypes.string.isRequired,
footer: PropTypes.node,
}
export default Main

View File

@ -9,7 +9,7 @@ import { github } from './util'
import { ReactComponent as Logo } from '../images/logo.svg'
import classes from '../styles/navigation.module.sass'
const NavigationDropdown = ({ items, section }) => {
const NavigationDropdown = ({ items = [], section }) => {
const active = items.find(({ text }) => text.toLowerCase() === section)
const defaultValue = active ? active.url : 'title'
return (
@ -26,7 +26,7 @@ const NavigationDropdown = ({ items, section }) => {
)
}
const Navigation = ({ title, items, section, search, children }) => {
export default function Navigation({ title, items = [], section, search, children }) {
return (
<nav className={classes.root}>
<Link to="/" aria-label={title} hidden>
@ -64,10 +64,6 @@ const Navigation = ({ title, items, section, search, children }) => {
)
}
Navigation.defaultProps = {
items: [],
}
Navigation.propTypes = {
title: PropTypes.string.isRequired,
items: PropTypes.arrayOf(
@ -79,5 +75,3 @@ Navigation.propTypes = {
section: PropTypes.string,
search: PropTypes.node,
}
export default Navigation

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
import classes from '../styles/newsletter.module.sass'
const Newsletter = ({ user, id, list }) => {
export default function Newsletter({ user, id, list }) {
const action = `//${user}.list-manage.com/subscribe/post?u=${id}&amp;id=${list}`
return (
<form
@ -46,5 +46,3 @@ Newsletter.propTypes = {
id: PropTypes.string.isRequired,
list: PropTypes.string.isRequired,
}
export default Newsletter

View File

@ -20,7 +20,7 @@ function getScrollY() {
return isNaN(pos) ? 0 : pos
}
const Progress = () => {
export default function Progress() {
const progressRef = useRef()
const [initialized, setInitialized] = useState(false)
const [offset, setOffset] = useState(getOffset())
@ -53,5 +53,3 @@ const Progress = () => {
const value = scrollY === 0 ? 0 : total || 0
return <progress ref={progressRef} className={classes.root} value={value} max="100" />
}
export default Progress

View File

@ -25,12 +25,12 @@ function getRawContent(ref) {
}
const Quickstart = ({
data,
data = [],
title,
description,
copy,
copy = true,
download,
id,
id = 'quickstart',
setters = {},
hidePrompts,
children,
@ -242,12 +242,6 @@ const Quickstart = ({
)
}
Quickstart.defaultProps = {
data: [],
id: 'quickstart',
copy: true,
}
Quickstart.propTypes = {
title: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
description: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),

View File

@ -7,21 +7,21 @@ import { Label } from './typography'
import classes from '../styles/readnext.module.sass'
const ReadNext = ({ title, to }) => (
<div className={classes.root}>
<Link to={to} hidden>
<Label>Read next</Label>
{title}
</Link>
<Link to={to} hidden className={classes.icon} aria-hidden="true">
<Icon name="arrowright" />
</Link>
</div>
)
export default function ReadNext({ title, to }) {
return (
<div className={classes.root}>
<Link to={to} hidden>
<Label>Read next</Label>
{title}
</Link>
<Link to={to} hidden className={classes.icon} aria-hidden="true">
<Icon name="arrowright" />
</Link>
</div>
)
}
ReadNext.propTypes = {
title: PropTypes.string.isRequired,
to: PropTypes.string.isRequired,
}
export default ReadNext

View File

@ -5,7 +5,7 @@ import { window } from 'browser-monads'
import Icon from './icon'
import classes from '../styles/search.module.sass'
const Search = ({ id, placeholder, settings }) => {
export default function Search({ id = 'docsearch', placeholder = 'Search docs', settings = {} }) {
const { apiKey, indexName } = settings
if (!apiKey && !indexName) return null
const [initialized, setInitialized] = useState(false)
@ -36,12 +36,6 @@ const Search = ({ id, placeholder, settings }) => {
)
}
Search.defaultProps = {
id: 'docsearch',
placeholder: 'Search docs',
settings: {},
}
Search.propTypes = {
settings: PropTypes.shape({
apiKey: PropTypes.string.isRequired,
@ -50,5 +44,3 @@ Search.propTypes = {
id: PropTypes.string.isRequired,
placeholder: PropTypes.string.isRequired,
}
export default Search

View File

@ -6,7 +6,7 @@ import { window } from 'browser-monads'
import classes from '../styles/section.module.sass'
const Section = ({ id, className, ...props }) => {
export default function Section({ id, className, ...props }) {
const sectionClassNames = classNames(classes.root, className)
const relId = id && id.startsWith('section-') ? id.slice(8) : id
const [ref, inView] = useInView({ threshold: 0 })
@ -24,6 +24,4 @@ Section.propTypes = {
className: PropTypes.string,
}
export default Section
export const Hr = () => <hr className={classes.hr} />

View File

@ -25,89 +25,95 @@ function getImage(section, nightly) {
return socialImageDefault
}
const SEO = ({ description, lang, title, section, sectionTitle, bodyClass, nightly }) => (
<StaticQuery
query={query}
render={data => {
const siteMetadata = data.site.siteMetadata
const metaDescription = description || siteMetadata.description
const pageTitle = getPageTitle(
title,
siteMetadata.title,
siteMetadata.slogan,
sectionTitle
)
const socialImage = siteMetadata.siteUrl + getImage(section, nightly)
const meta = [
{
name: 'description',
content: metaDescription,
},
{
property: 'og:title',
content: pageTitle,
},
{
property: 'og:description',
content: metaDescription,
},
{
property: 'og:type',
content: `website`,
},
{
property: 'og:site_name',
content: title,
},
{
property: 'og:image',
content: socialImage,
},
{
name: 'twitter:card',
content: 'summary_large_image',
},
{
name: 'twitter:image',
content: socialImage,
},
{
name: 'twitter:creator',
content: `@${siteMetadata.social.twitter}`,
},
{
name: 'twitter:site',
content: `@${siteMetadata.social.twitter}`,
},
{
name: 'twitter:title',
content: pageTitle,
},
{
name: 'twitter:description',
content: metaDescription,
},
{
name: 'docsearch:language',
content: lang,
},
]
export default function SEO({
description,
lang = 'en',
title,
section,
sectionTitle,
bodyClass,
nightly,
}) {
return (
<StaticQuery
query={query}
render={data => {
const siteMetadata = data.site.siteMetadata
const metaDescription = description || siteMetadata.description
const pageTitle = getPageTitle(
title,
siteMetadata.title,
siteMetadata.slogan,
sectionTitle
)
const socialImage = siteMetadata.siteUrl + getImage(section, nightly)
const meta = [
{
name: 'description',
content: metaDescription,
},
{
property: 'og:title',
content: pageTitle,
},
{
property: 'og:description',
content: metaDescription,
},
{
property: 'og:type',
content: `website`,
},
{
property: 'og:site_name',
content: title,
},
{
property: 'og:image',
content: socialImage,
},
{
name: 'twitter:card',
content: 'summary_large_image',
},
{
name: 'twitter:image',
content: socialImage,
},
{
name: 'twitter:creator',
content: `@${siteMetadata.social.twitter}`,
},
{
name: 'twitter:site',
content: `@${siteMetadata.social.twitter}`,
},
{
name: 'twitter:title',
content: pageTitle,
},
{
name: 'twitter:description',
content: metaDescription,
},
{
name: 'docsearch:language',
content: lang,
},
]
return (
<Helmet
defer={false}
htmlAttributes={{ lang }}
bodyAttributes={{ class: bodyClass }}
title={pageTitle}
meta={meta}
/>
)
}}
/>
)
SEO.defaultProps = {
lang: 'en',
return (
<Helmet
defer={false}
htmlAttributes={{ lang }}
bodyAttributes={{ class: bodyClass }}
title={pageTitle}
meta={meta}
/>
)
}}
/>
)
}
SEO.propTypes = {
@ -120,8 +126,6 @@ SEO.propTypes = {
bodyClass: PropTypes.string,
}
export default SEO
const query = graphql`
query DefaultSEOQuery {
site {

View File

@ -37,7 +37,7 @@ const DropdownNavigation = ({ items, defaultValue }) => {
)
}
const Sidebar = ({ items, pageMenu, slug }) => {
export default function Sidebar({ items = [], pageMenu = [], slug }) {
const [initialized, setInitialized] = useState(false)
const [activeSection, setActiveSection] = useState(null)
const activeRef = useRef()
@ -109,11 +109,6 @@ const Sidebar = ({ items, pageMenu, slug }) => {
)
}
Sidebar.defaultProps = {
items: [],
pageMenu: [],
}
Sidebar.propTypes = {
items: PropTypes.arrayOf(
PropTypes.shape({
@ -140,5 +135,3 @@ Sidebar.propTypes = {
})
),
}
export default Sidebar

View File

@ -8,7 +8,7 @@ import classes from '../styles/tag.module.sass'
const MIN_VERSION = 3
const Tag = ({ spaced, variant, tooltip, children }) => {
export default function Tag({ spaced = false, variant, tooltip, children }) {
if (variant === 'new') {
const isValid = isString(children) && !isNaN(children)
const version = isValid ? Number(children).toFixed(1) : children
@ -49,14 +49,8 @@ const TagTemplate = ({ spaced, tooltip, children }) => {
)
}
Tag.defaultProps = {
spaced: false,
}
Tag.propTypes = {
spaced: PropTypes.bool,
tooltip: PropTypes.string,
children: PropTypes.node.isRequired,
}
export default Tag

View File

@ -24,7 +24,7 @@ const MetaItem = ({ label, url, children, help }) => (
</span>
)
const Title = ({
export default function Title({
id,
title,
tag,
@ -35,7 +35,7 @@ const Title = ({
apiDetails,
children,
...props
}) => {
}) {
const hasApiDetails = Object.values(apiDetails || {}).some(v => v)
const metaIconProps = { className: classes.metaIcon, width: 18 }
return (
@ -111,5 +111,3 @@ Title.propTypes = {
image: PropTypes.string,
children: PropTypes.node,
}
export default Title

View File

@ -9,7 +9,7 @@ import { InlineCode } from '../components/code'
const DEFAULT_REPO = 'https://github.com/explosion/projects'
const COMMAND = 'python -m spacy project clone'
const Project = ({ id, repo, children }) => {
export default function Project({ id, repo, children }) {
const repoArg = repo ? ` --repo ${repo}` : ''
const text = `${COMMAND} ${id}${repoArg}`
const url = `${repo || DEFAULT_REPO}/${id}`
@ -28,5 +28,3 @@ const Project = ({ id, repo, children }) => {
</Infobox>
)
}
export default Project

View File

@ -33,7 +33,7 @@ const data = [
},
]
const QuickstartInstall = ({ id, title, description, defaultLang, children }) => (
const QuickstartInstall = ({ id, title, description, defaultLang = 'en', children }) => (
<StaticQuery
query={query}
render={({ site }) => {
@ -85,10 +85,6 @@ const QuickstartInstall = ({ id, title, description, defaultLang, children }) =>
/>
)
QuickstartInstall.defaultProps = {
defaultLang: 'en',
}
export default QuickstartInstall
const query = graphql`

View File

@ -55,7 +55,7 @@ const DATA = [
},
]
const QuickstartTraining = ({ id, title, download = 'config.cfg' }) => {
export default function QuickstartTraining({ id, title, download = 'config.cfg' }) {
const [lang, setLang] = useState(DEFAULT_LANG)
const [pipeline, setPipeline] = useState([])
const setters = { lang: setLang, components: setPipeline }
@ -124,5 +124,3 @@ const query = graphql`
}
}
`
export default QuickstartTraining