85 lines
2.5 KiB
JavaScript
85 lines
2.5 KiB
JavaScript
import React, { forwardRef } from 'react'
|
|
import { defaultComponents as patternComponents } from '@freesewing/react/components/Pattern'
|
|
import { PointXray } from './point.mjs'
|
|
import { PathXray } from './path.mjs'
|
|
|
|
/**
|
|
* Default Xray components that you can override
|
|
*
|
|
* @public
|
|
* @constant
|
|
*/
|
|
const defaultComponents = {
|
|
Point: PointXray,
|
|
Path: PathXray,
|
|
}
|
|
|
|
/**
|
|
* A component to code-highlight JSON data
|
|
*
|
|
* @component
|
|
* @param {object} props - All component props
|
|
* @param {JSX.Element} props.children - The component children, if they are set, we will not render any stacks
|
|
* @param {string} [props.className = 'freesewing pattern'] - SVG classes to set on the SVG element
|
|
* @param {object} [props.components = {}] - Any custom components to use in the pattern
|
|
* @param {object} [props.drillProps = {}] - Any additional props to pass down
|
|
* @param {object} [props.strings = {}] - Strings to use for translation
|
|
* @param {object} props.renderProps - The pattern's renderProps as generated by FreeSewing core
|
|
* @returns {JSX.Element}
|
|
*/
|
|
export const Xray = forwardRef((props, ref) => {
|
|
if (!props.renderProps) return null
|
|
|
|
// desctructure props
|
|
const {
|
|
renderProps = false,
|
|
children = false,
|
|
className = 'freesewing pattern',
|
|
components = {},
|
|
drillProps = {},
|
|
strings = [],
|
|
} = props
|
|
|
|
// Merge pattern, default, and custom components
|
|
const mergedComponents = {
|
|
...patternComponents,
|
|
...defaultComponents,
|
|
...components,
|
|
}
|
|
|
|
const { Svg, Defs, Stack, Group } = mergedComponents
|
|
const optionalProps = {}
|
|
if (className) optionalProps.className = className
|
|
|
|
return (
|
|
<Svg
|
|
viewBox={`0 0 ${renderProps.width} ${renderProps.height}`}
|
|
embed={renderProps.settings.embed}
|
|
{...renderProps}
|
|
{...optionalProps}
|
|
ref={ref}
|
|
>
|
|
<Defs {...renderProps} />
|
|
<style>{`:root { --pattern-scale: ${renderProps.settings.scale || 1}} ${
|
|
renderProps.svg.style
|
|
}`}</style>
|
|
<Group>
|
|
{children
|
|
? children
|
|
: Object.keys(renderProps.stacks).map((stackName) => (
|
|
<Stack
|
|
key={stackName}
|
|
stackName={stackName}
|
|
stack={renderProps.stacks[stackName]}
|
|
settings={renderProps.settings}
|
|
components={mergedComponents}
|
|
strings={strings}
|
|
drillProps={drillProps}
|
|
/>
|
|
))}
|
|
</Group>
|
|
</Svg>
|
|
)
|
|
})
|
|
|
|
Xray.displayName = 'Xray'
|