mirror of
https://github.com/explosion/spaCy.git
synced 2025-01-12 18:26:30 +03:00
Refactor Quickstart component
The previous implementation was hidding the irrelevant lines via data-props and dynamically generated CSS. This created problems with Next and was also hard to follow. CSS was used to do what React is supposed to handle. The new implementation simplfy filters the list of children (React elements) via their props.
This commit is contained in:
parent
4b315d1c4c
commit
04ec2c0e93
|
@ -1,4 +1,4 @@
|
||||||
import React, { Fragment, useState, useEffect, useRef } from 'react'
|
import React, { Fragment, useState, useEffect, useRef, Children } from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import { window, document } from 'browser-monads'
|
import { window, document } from 'browser-monads'
|
||||||
|
@ -36,7 +36,6 @@ const Quickstart = ({
|
||||||
const isClient = typeof window !== 'undefined'
|
const isClient = typeof window !== 'undefined'
|
||||||
const supportsCopy = isClient && document.queryCommandSupported('copy')
|
const supportsCopy = isClient && document.queryCommandSupported('copy')
|
||||||
const showCopy = supportsCopy && copy
|
const showCopy = supportsCopy && copy
|
||||||
const [styles, setStyles] = useState({})
|
|
||||||
const [checked, setChecked] = useState({})
|
const [checked, setChecked] = useState({})
|
||||||
const [initialized, setInitialized] = useState(false)
|
const [initialized, setInitialized] = useState(false)
|
||||||
const [copySuccess, setCopySuccess] = useState(false)
|
const [copySuccess, setCopySuccess] = useState(false)
|
||||||
|
@ -57,14 +56,6 @@ const Quickstart = ({
|
||||||
copyToClipboard(copyAreaRef, setCopySuccess)
|
copyToClipboard(copyAreaRef, setCopySuccess)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCss = (id, checkedOptions) => {
|
|
||||||
const checkedForId = checkedOptions[id] || []
|
|
||||||
const exclude = checkedForId
|
|
||||||
.map((value) => `:not([data-quickstart-${id}="${value}"])`)
|
|
||||||
.join('')
|
|
||||||
return `[data-quickstart-results]>[data-quickstart-${id}]${exclude} {display: none}`
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
window.dispatchEvent(new Event('resize')) // scroll position for progress
|
window.dispatchEvent(new Event('resize')) // scroll position for progress
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
|
@ -74,16 +65,25 @@ const Quickstart = ({
|
||||||
[id]: options.filter((option) => option.checked).map(({ id }) => id),
|
[id]: options.filter((option) => option.checked).map(({ id }) => id),
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
const initialStyles = Object.assign(
|
|
||||||
{},
|
|
||||||
...data.map(({ id }) => ({ [id]: getCss(id, initialChecked) }))
|
|
||||||
)
|
|
||||||
setChecked(initialChecked)
|
setChecked(initialChecked)
|
||||||
setStyles(initialStyles)
|
|
||||||
setInitialized(true)
|
setInitialized(true)
|
||||||
}
|
}
|
||||||
}, [data, initialized])
|
}, [data, initialized])
|
||||||
|
|
||||||
|
const isRelevant = (child) => {
|
||||||
|
if (typeof child === 'string' || child.type !== QS) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.every((itemData) => {
|
||||||
|
return (
|
||||||
|
!child.props[itemData.id] ||
|
||||||
|
!checked[itemData.id] ||
|
||||||
|
checked[itemData.id].includes(child.props[itemData.id])
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return !data.length ? null : (
|
return !data.length ? null : (
|
||||||
<Container id={id}>
|
<Container id={id}>
|
||||||
<div
|
<div
|
||||||
|
@ -117,10 +117,6 @@ const Quickstart = ({
|
||||||
const dropdownGetter = showDropdown[id] || (() => true)
|
const dropdownGetter = showDropdown[id] || (() => true)
|
||||||
return hidden ? null : (
|
return hidden ? null : (
|
||||||
<div key={id} data-quickstart-group={id} className={classes['group']}>
|
<div key={id} data-quickstart-group={id} className={classes['group']}>
|
||||||
<style data-quickstart-style={id} scoped>
|
|
||||||
{styles[id] ||
|
|
||||||
`[data-quickstart-results]>[data-quickstart-${id}] { display: none }`}
|
|
||||||
</style>
|
|
||||||
<div className={classes['legend']}>
|
<div className={classes['legend']}>
|
||||||
{title}
|
{title}
|
||||||
{help && (
|
{help && (
|
||||||
|
@ -147,10 +143,6 @@ const Quickstart = ({
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
setChecked(newChecked)
|
setChecked(newChecked)
|
||||||
setStyles({
|
|
||||||
...styles,
|
|
||||||
[id]: getCss(id, newChecked),
|
|
||||||
})
|
|
||||||
setterFunc(newChecked[id])
|
setterFunc(newChecked[id])
|
||||||
}}
|
}}
|
||||||
type={optionType}
|
type={optionType}
|
||||||
|
@ -231,7 +223,7 @@ const Quickstart = ({
|
||||||
data-quickstart-results=""
|
data-quickstart-results=""
|
||||||
ref={contentRef}
|
ref={contentRef}
|
||||||
>
|
>
|
||||||
{children}
|
{Children.toArray(children).flat().filter(isRelevant)}
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
<menu className={classes['menu']}>
|
<menu className={classes['menu']}>
|
||||||
|
@ -295,17 +287,7 @@ const QS = ({ children, prompt = 'bash', divider = false, comment = false, ...pr
|
||||||
[classes['divider']]: !!divider,
|
[classes['divider']]: !!divider,
|
||||||
[classes['comment']]: !!comment,
|
[classes['comment']]: !!comment,
|
||||||
})
|
})
|
||||||
const attrs = Object.assign(
|
return <span className={qsClassNames}>{children}</span>
|
||||||
{},
|
|
||||||
...Object.keys(props).map((key) => ({
|
|
||||||
[`data-quickstart-${key}`]: props[key],
|
|
||||||
}))
|
|
||||||
)
|
|
||||||
return (
|
|
||||||
<span className={qsClassNames} {...attrs}>
|
|
||||||
{children}
|
|
||||||
</span>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export { Quickstart, QS }
|
export { Quickstart, QS }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user