From 04ec2c0e93ec8e86a42cb1000afa216c7fb3c07b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcus=20Bl=C3=A4ttermann?= Date: Tue, 13 Dec 2022 07:04:27 +0100 Subject: [PATCH] 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. --- website/src/components/quickstart.js | 52 +++++++++------------------- 1 file changed, 17 insertions(+), 35 deletions(-) diff --git a/website/src/components/quickstart.js b/website/src/components/quickstart.js index c54fb38cb..2b8b58fe2 100644 --- a/website/src/components/quickstart.js +++ b/website/src/components/quickstart.js @@ -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 classNames from 'classnames' import { window, document } from 'browser-monads' @@ -36,7 +36,6 @@ const Quickstart = ({ const isClient = typeof window !== 'undefined' const supportsCopy = isClient && document.queryCommandSupported('copy') const showCopy = supportsCopy && copy - const [styles, setStyles] = useState({}) const [checked, setChecked] = useState({}) const [initialized, setInitialized] = useState(false) const [copySuccess, setCopySuccess] = useState(false) @@ -57,14 +56,6 @@ const Quickstart = ({ 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(() => { window.dispatchEvent(new Event('resize')) // scroll position for progress if (!initialized) { @@ -74,16 +65,25 @@ const Quickstart = ({ [id]: options.filter((option) => option.checked).map(({ id }) => id), })) ) - const initialStyles = Object.assign( - {}, - ...data.map(({ id }) => ({ [id]: getCss(id, initialChecked) })) - ) setChecked(initialChecked) - setStyles(initialStyles) setInitialized(true) } }, [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 : (
true) return hidden ? null : (
-
{title} {help && ( @@ -147,10 +143,6 @@ const Quickstart = ({ ), } setChecked(newChecked) - setStyles({ - ...styles, - [id]: getCss(id, newChecked), - }) setterFunc(newChecked[id]) }} type={optionType} @@ -231,7 +223,7 @@ const Quickstart = ({ data-quickstart-results="" ref={contentRef} > - {children} + {Children.toArray(children).flat().filter(isRelevant)} @@ -295,17 +287,7 @@ const QS = ({ children, prompt = 'bash', divider = false, comment = false, ...pr [classes['divider']]: !!divider, [classes['comment']]: !!comment, }) - const attrs = Object.assign( - {}, - ...Object.keys(props).map((key) => ({ - [`data-quickstart-${key}`]: props[key], - })) - ) - return ( - - {children} - - ) + return {children} } export { Quickstart, QS }