import React, { useState } from 'react' import Svg from './Svg' import Defs from './Defs' import Part from './Part' import Develop from './Develop' const PatternSvg = props => ( <Svg embed={props.settings.embed} width={props.width} height={props.height} language={props.settings.locale} id={props.settings.idPrefix + 'svg'} develop={props.develop || false} style={props.style || {}} viewBox={props.viewBox} className={props.className || 'freesewing pattern'} > <Defs {...props} /> <style>{`:root { --pattern-scale: ${props.settings.scale || 1}}`}</style> <g> {Object.keys(props.parts).map((name) => ( <Part part={props.parts[name]} language={props.settings.locale} paperless={props.settings.paperless} units={props.settings.units} key={name} name={name} focus={props.focus || false} develop={props.develop || false} raiseEvent={props.raiseEvent} /> ))} </g> </Svg> ) const Pattern = props => { const { pattern = 'examples', patterns = {}, children=null, options = {}, measurements = { head: 390}, part = '', sample, svgOnly=false, allowDevelop=true } = props const [develop, setDevelop] = useState(false) const [focus, setFocus] = useState(null) // Don't continue if there's no pattern if (!pattern || !patterns[pattern]) return <pre>{JSON.stringify(props,null,4)}</pre> //null /* Helper method to handle user clicks */ const raiseEvent = (type, data) => { if (type === 'clearFocusAll') return setFocus(null) let f = {} if (focus !== null) f = { ...focus } if (typeof f[data.part] === 'undefined') f[data.part] = { paths: [], points: [], coords: [] } if (type === 'point') f[data.part].points.push(data.name) else if (type === 'path') f[data.part].paths.push(data.name) else if (type === 'coords') f[data.part].coords.push(data.coords) else if (type === 'clearFocus') { let i = focus[data.part][data.type].indexOf(data.name) f[data.part][data.type].splice(i, 1) } setFocus(f) } /* Handle various elements with focus */ let focusCount = 0 if (focus !== null) { for (let p of Object.keys(focus)) { for (let i in focus[p].points) focusCount++ for (let i in focus[p].paths) focusCount++ for (let i in focus[p].coords) focusCount++ } } /* Set up settings object */ const settings = { options: { ...options }, measurements: { ...measurements }, ...props.settings } // Support for options_ prefix for (const [key, val] of Object.entries(props)) { if (key.slice(0,8) === 'options_') settings.options[key.slice(8)] = (val === 'true') ? true : (val === 'false') ? false : val if (key.slice(0,9) === 'settings_') settings[key.slice(9)] = (val === 'true') ? true : (val === 'false') ? false : val } if (part !== '') settings.only = [part] const patternInstance = new patterns[pattern](settings) if (sample) patternInstance.sample() else patternInstance.draft() const patternProps = patternInstance.getRenderProps() return svgOnly ? <PatternSvg {...patternProps} develop={develop} focus={focus} raiseEvent={raiseEvent} /> : ( <figure className={`my-4 ${develop ? 'develop example' : 'example'}`}> <div className="example text-base-content"> {allowDevelop && ( <div className="actions"> <div className="form-control"> <label className="cursor-pointer label justify-start gap-4 font-lg lg:font-xl font-bold"> <input type="checkbox" checked={develop} className="toggle toggle-secondary" onChange={() => setDevelop(!develop)} /> <span className="label-text text-secondary">{develop ? 'Disable' : 'Enable'} Developer View</span> </label> </div> </div> )} {develop && ( <div className="develop p-4 py-2 border rounded mb-2"> <div className="flex flex-row justify-between"> <h5>Developer info</h5> <button disabled={!develop} className="px-2 py-1 rounded text-secondary border-secondary border text-sm" onClick={() => raiseEvent('clearFocusAll', null)} > <strong>Clear</strong> </button> </div> <Develop focus={focus} develop={develop} raiseEvent={raiseEvent} parts={patternProps.parts} /> </div> )} <div className="shadow rounded border border-base-200"> <PatternSvg {...patternProps} develop={develop} focus={focus} raiseEvent={raiseEvent} /> </div> </div> <figcaption className="text-base-content text-center text-base lg:text-lg italic">{children}</figcaption> </figure> ) } export default Pattern