2023-01-29 16:44:02 +01:00
|
|
|
import { Tab, Tabs } from './tabs.mjs'
|
2022-09-27 18:20:46 +02:00
|
|
|
import Md from 'react-markdown'
|
2022-09-30 01:45:37 +02:00
|
|
|
import { pluginBundle } from '@freesewing/plugin-bundle'
|
|
|
|
import { pluginFlip } from '@freesewing/plugin-flip'
|
|
|
|
import { pluginGore } from '@freesewing/plugin-gore'
|
2022-09-27 18:20:46 +02:00
|
|
|
import { Design } from '@freesewing/core'
|
2022-10-12 00:16:36 +02:00
|
|
|
import yaml from 'js-yaml'
|
2023-06-17 13:20:54 +02:00
|
|
|
import { Pattern, PatternXray } from '@freesewing/react-components'
|
2022-09-22 09:05:20 +02:00
|
|
|
|
2022-09-27 18:20:46 +02:00
|
|
|
// Get code from children
|
2022-09-30 00:08:53 +02:00
|
|
|
export const asText = (reactEl) => {
|
2023-07-15 16:55:22 +02:00
|
|
|
if (reactEl) {
|
|
|
|
if (typeof reactEl.props.children === 'string') return reactEl.props.children
|
|
|
|
if (Array.isArray(reactEl.props.children)) {
|
|
|
|
return reactEl.props.children.map((el) => (typeof el === 'string' ? el : asText(el))).join('')
|
|
|
|
}
|
|
|
|
if (typeof reactEl.props.children === 'object') return asText(reactEl.props.children)
|
2022-09-27 18:20:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return ''
|
2022-09-22 09:05:20 +02:00
|
|
|
}
|
|
|
|
|
2023-06-17 12:27:47 +02:00
|
|
|
// Returns a FreeSewing pattern based on code in children
|
|
|
|
const buildPattern = (children, settings = { margin: 5 }, tutorial = false, paperless = false) => {
|
2022-10-10 04:51:21 +02:00
|
|
|
let code = asText(children)
|
|
|
|
// FIXME: Refactor to not use eval
|
|
|
|
let draft
|
|
|
|
if (code.split('\n')[0].includes('function')) {
|
|
|
|
code = '(' + code.split('(').slice(1).join('(')
|
|
|
|
code = code.split(')')
|
|
|
|
code = code[0] + ') => ' + code.slice(1).join(')')
|
|
|
|
}
|
2022-10-12 18:34:34 +02:00
|
|
|
try {
|
|
|
|
draft = eval(code)
|
|
|
|
} catch (err) {
|
|
|
|
console.log(err, code)
|
|
|
|
}
|
2022-09-27 18:20:46 +02:00
|
|
|
const part = {
|
2022-10-10 04:51:21 +02:00
|
|
|
draft: draft,
|
2023-03-20 19:18:01 -05:00
|
|
|
name: tutorial ? 'tutorial.bib' : 'example',
|
2022-10-10 04:51:21 +02:00
|
|
|
measurements: tutorial ? [] : ['head'],
|
|
|
|
options: tutorial
|
|
|
|
? {
|
|
|
|
neckRatio: { pct: 80, min: 70, max: 90, menu: 'fit' },
|
|
|
|
widthRatio: { pct: 45, min: 35, max: 55, menu: 'style' },
|
|
|
|
lengthRatio: { pct: 75, min: 55, max: 85, menu: 'style' },
|
|
|
|
}
|
|
|
|
: {},
|
2022-09-30 01:45:37 +02:00
|
|
|
plugins: [pluginBundle, pluginFlip, pluginGore],
|
2022-09-27 18:20:46 +02:00
|
|
|
}
|
2022-10-11 15:07:56 +02:00
|
|
|
const design = new Design({
|
|
|
|
parts: [part],
|
2023-03-20 19:18:01 -05:00
|
|
|
data: tutorial ? { name: 'Tutorial', version: '0.0.1' } : { name: 'Example', version: '0.0.1' },
|
2022-10-11 15:07:56 +02:00
|
|
|
})
|
2022-10-10 04:51:21 +02:00
|
|
|
if (tutorial) settings.measurements = { head: 380 }
|
2022-10-11 15:07:56 +02:00
|
|
|
if (paperless) settings.paperless = true
|
|
|
|
|
2022-09-27 18:20:46 +02:00
|
|
|
return new design(settings)
|
|
|
|
}
|
|
|
|
|
2023-06-17 13:20:54 +02:00
|
|
|
// Handles display of pattern in mormal or xray mode
|
|
|
|
const ShowPattern = ({ renderProps, logs, mode = 'normal' }) => {
|
|
|
|
if (!renderProps) return null
|
|
|
|
|
|
|
|
if (logs.pattern.error.length > 0 || logs.sets[0].error.length > 0)
|
|
|
|
return (
|
|
|
|
<div className="max-w-full p-4">
|
|
|
|
<pre>fixme: Errors logged. Please implement log view</pre>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
|
2023-06-18 17:53:33 +02:00
|
|
|
return mode === 'xray' ? <PatternXray {...{ renderProps }} /> : <Pattern {...{ renderProps }} />
|
2023-06-17 13:20:54 +02:00
|
|
|
}
|
|
|
|
|
2022-09-27 18:20:46 +02:00
|
|
|
// Wrapper component dealing with the tabs and code view
|
2023-01-29 16:44:02 +01:00
|
|
|
export const TabbedExample = ({
|
2022-10-12 14:54:35 +02:00
|
|
|
children,
|
|
|
|
caption,
|
|
|
|
tutorial,
|
|
|
|
previewFirst,
|
|
|
|
withHead,
|
|
|
|
paperless,
|
|
|
|
settings,
|
2023-07-17 11:40:45 -05:00
|
|
|
patternProps,
|
2022-10-12 14:54:35 +02:00
|
|
|
}) => {
|
2022-10-12 00:16:36 +02:00
|
|
|
if (settings)
|
|
|
|
settings = {
|
|
|
|
margin: 5,
|
|
|
|
...yaml.load(settings),
|
|
|
|
}
|
|
|
|
else settings = { margin: 5 }
|
|
|
|
if (withHead) settings.measurements = { head: 300 }
|
2023-04-24 00:15:05 -04:00
|
|
|
|
2023-07-17 11:40:45 -05:00
|
|
|
if (children && !patternProps) {
|
|
|
|
const pattern = buildPattern(children, settings, tutorial, paperless)
|
2023-04-24 00:15:05 -04:00
|
|
|
|
2023-07-17 11:40:45 -05:00
|
|
|
// Check that it's a valid pattern
|
|
|
|
if (!pattern.sample) return null
|
|
|
|
|
|
|
|
patternProps = {
|
|
|
|
renderProps: settings.sample
|
|
|
|
? pattern.sample().getRenderProps()
|
|
|
|
: pattern.draft().getRenderProps(),
|
|
|
|
logs: pattern.getLogs(),
|
|
|
|
}
|
2023-06-17 13:20:54 +02:00
|
|
|
}
|
2023-04-24 00:15:05 -04:00
|
|
|
|
2023-07-17 11:40:45 -05:00
|
|
|
const tabs = []
|
|
|
|
const tabNames = ['Preview']
|
|
|
|
tabs.push(
|
|
|
|
<Tab key="preview">
|
|
|
|
<ShowPattern {...patternProps} />
|
|
|
|
</Tab>
|
|
|
|
)
|
|
|
|
if (children) {
|
|
|
|
const codeTab = <Tab key="code">{children}</Tab>
|
|
|
|
|
|
|
|
if (tutorial && !previewFirst) {
|
|
|
|
tabs.unshift(codeTab)
|
|
|
|
tabNames.unshift('Code')
|
|
|
|
} else {
|
|
|
|
tabs.push(codeTab)
|
|
|
|
tabNames.push('Code')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tabs.push(
|
|
|
|
<Tab key="xray">
|
|
|
|
<ShowPattern {...patternProps} mode="xray" />
|
|
|
|
</Tab>
|
|
|
|
)
|
|
|
|
tabNames.push('X-Ray')
|
2022-09-27 18:20:46 +02:00
|
|
|
|
|
|
|
return (
|
|
|
|
<div className="my-8">
|
2023-07-17 11:40:45 -05:00
|
|
|
<Tabs tabs={tabNames.join(', ')}>{tabs}</Tabs>
|
2022-09-27 18:20:46 +02:00
|
|
|
{caption && (
|
|
|
|
<div className="text-center italic -mt-4">
|
|
|
|
<Md>{caption}</Md>
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|