UNPKG

@catho/quantum-storybook-ui

Version:

A **Design System** is the complete set of design standards, documentation, and principles along with the toolkit (UI patterns and code components) to achieve those standards. Over time, these 'systems' are growing in popularity - a very popular one is [Q

120 lines (98 loc) 3.19 kB
import React from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; import SimpleHighlight from '../SimpleHighlight'; import Title from '../Title'; import { FORBIDDEN_PROPS } from '../shared'; const MainTitle = styled(Title)` padding: 0; margin: 25px 0; `; const formatJSON = (key, value) => { if (typeof value === 'function') return '() => {}'; if (typeof value === 'string') return `'${value}'`; return value; }; const INDENTATION_SIZE = 2; const spaces = size => ' '.repeat(size); const jsonStr = (json, indentation) => JSON.stringify(json, formatJSON, INDENTATION_SIZE) .replace(/\n/g, `\n${indentation}${spaces(INDENTATION_SIZE)}`) .replace(/"/g, ''); const renderPropValue = (propValue, indentation) => { if (typeof propValue === 'object' && propValue instanceof RegExp) { return `{${propValue}}`; } const types = { function: () => '{() => {}}', string: prop => `"${prop}"`, number: prop => `{${prop}}`, object: prop => `{${jsonStr(prop, indentation)}}`, instanceOf: prop => `{${prop}}` }; const fn = types[typeof propValue]; return fn ? fn(propValue) : propValue; }; function getProps(props, indentation) { const breakline = `\n${indentation}${spaces(INDENTATION_SIZE)}`; return Object.entries(props) .filter(([name, value]) => value && !FORBIDDEN_PROPS.includes(name)) .map(([prop, value], index) => { const propText = typeof value === 'boolean' ? prop : `${prop}=${renderPropValue(value, indentation)}`; return `${index === 0 ? breakline : ''}${propText}`; }) .join(breakline); } const componentToString = (component, state, level = 0) => { let content; const indentation = spaces(level); if (typeof component === 'object') { const { type, props } = component; const name = type.displayName || type.name || type; const children = props ? props.children : null; content = `${indentation}<${name}${ Object.keys(state).length ? getProps(state, indentation) : '' }`; content += children ? `>\n${React.Children.map(children, child => componentToString(child, child.props, level + INDENTATION_SIZE) ).join('\n')}\n${indentation}</${name}>` : `\n${indentation}/>`; } else { content = component ? `${indentation}${component}` : ''; } return content; }; const msg = importModules => `import ${'{'} ${importModules} ${'}'} from '@catho/quantum';\n\n`; const CodeExample = ({ component, state, code, withImport, title }) => { const codeStr = code || componentToString(component, state || component.props); return ( <> {title && <MainTitle as="h2">{title}</MainTitle>} <SimpleHighlight> {withImport && msg(withImport)} {codeStr} </SimpleHighlight> </> ); }; CodeExample.defaultProps = { code: '', title: '', withImport: '', state: null, component: {} }; CodeExample.propTypes = { component: PropTypes.instanceOf(Object), state: PropTypes.instanceOf(Object), code: PropTypes.string, title: PropTypes.string, withImport: PropTypes.string }; export default CodeExample;