1
0
Fork 0

feat(dev): Added react docs for Pattern + refactor

This adds support for not only documenating components, but also
constants and functions that may be exported next to components.
This commit is contained in:
joostdecock 2025-05-25 16:29:57 +02:00
parent d0baf7cece
commit 22a89f12d3
50 changed files with 1816 additions and 669 deletions

View file

@ -2,7 +2,24 @@ import React from 'react'
import { diffWords, diffJson } from 'diff'
import ReactDiffViewer from 'react-diff-viewer-continued'
/**
* A method to diff JSON content
*
* @public
* @param {object} from - Once side of the diff
* @param {object} to - Other side of the diff
* @returns {object}
*/
export const diffJSON = (from, to) => diffJson(from, to)
/**
* A method to diff string content
*
* @public
* @param {string} from - Once side of the diff
* @param {string} to - Other side of the diff
* @returns {object}
*/
export const diffCheck = (from, to) => diffWords(from, to)
export const DiffViewer = (props) => <ReactDiffViewer {...props} />

View file

@ -3,6 +3,12 @@ import * as _echarts from 'echarts'
import ReactECharts from 'echarts-for-react'
import { Popout } from '@freesewing/react/components/Popout'
/**
* Re-export of Apache Echarts
*
* @public
* @constant
*/
export const echarts = _echarts
echarts.registerTheme('light', {

View file

@ -36,10 +36,13 @@ import { Uma, UmaFront, UmaBack } from './uma.mjs'
import { Umbra, UmbraFront, UmbraBack } from './umbra.mjs'
import { Wahid, WahidFront, WahidBack } from './wahid.mjs'
/*
* Bundle all fronts
/**
* An object where the key is the design name and the value the front LineDrawing component
*
* @constant
* @public
*/
const lineDrawingsFront = {
export const lineDrawingsFront = {
aaron: AaronFront,
albert: AlbertFront,
bee: BeeFront,
@ -83,10 +86,13 @@ const lineDrawingsFront = {
wahid: WahidFront,
}
/*
* Bundle all backs
/**
* An object where the key is the design name and the value the back LineDrawing component
*
* @constant
* @public
*/
const lineDrawingsBack = {
export const lineDrawingsBack = {
aaron: AaronBack,
bella: BellaBack,
bent: BentBack,
@ -116,10 +122,13 @@ const lineDrawingsBack = {
wahid: WahidBack,
}
/*
* Bundle all linedrawings
/**
* An object where the key is the design name and the value the full LineDrawing component
*
* @constant
* @public
*/
const lineDrawings = {
export const lineDrawings = {
aaron: Aaron,
albert: Albert,
bee: Bee,
@ -146,17 +155,13 @@ const lineDrawings = {
huey: Huey,
hugo: Hugo,
jane: Jane,
lucy: Lucy,
lumina: Lumina,
lumira: Lumira,
lunetius: Lunetius,
noble: Noble,
simon: Simon,
teagan: Teagan,
tristan: Tristan,
uma: Uma,
umbra: Umbra,
@ -167,10 +172,6 @@ const lineDrawings = {
* Named exports
*/
export {
// Bundles
lineDrawings,
lineDrawingsBack,
lineDrawingsFront,
// Aaron
Aaron,
AaronFront,

View file

@ -1,5 +1,13 @@
import React from 'react'
/**
* A component to render a circle inside a FreeSewing pattern
*
* @component
* @param {object} props - All component props
* @param {object} props.point - The point that holds the circle info
* @returns {JSX.Element}
*/
export const Circle = ({ point }) =>
point.attributes.list['data-circle'].map((r, i) => {
const circleProps = point.attributes.circleProps

View file

@ -86,12 +86,20 @@ const PaperlessDefs = ({ units = 'metric', stacks }) =>
<MetricPaperlessDefs stacks={stacks} />
)
export const Defs = (props) =>
props.svg ? (
/**
* A component to render the defs section of an SVG element inside a FreeSewing pattern
*
* @component
* @param {object} props - All component props
* @param {Svg} props.svg - The FreeSewing Svg object for the pattern
* @param {object} props.settings - The settings for the pattern
* @param {object} props.stacks - The pattern stacks
* @returns {JSX.Element}
*/
export const Defs = ({ svg, stacks, settings = {} }) =>
svg ? (
<defs>
{props.svg.defs.list ? sanitize(Object.values(props.svg.defs.list).join('')) : null}
{props.settings[0].paperless ? (
<PaperlessDefs units={props.settings[0].units} stacks={props.stacks} />
) : null}
{svg.defs.list ? sanitize(Object.values(svg.defs.list).join('')) : null}
{settings[0]?.paperless ? <PaperlessDefs units={settings[0].units} stacks={stacks} /> : null}
</defs>
) : null

View file

@ -1,7 +1,14 @@
// __SDEFILE__ - This file is a dependency for the stand-alone environment
// eslint-disable-next-line no-unused-vars
import React from 'react'
/**
* A component to render the grid for a paperless FreeSewing pattern' stack
*
* @component
* @param {object} props - All component props
* @param {Stack} props.stack - The FreeSewing Stack object for the pattern
* @param {string} props.stackName - The name of the FreeSewing Stack
* @returns {JSX.Element}
*/
export const Grid = ({ stack, stackName }) => (
<rect
x={stack.topLeft.x}

View file

@ -1,7 +1,13 @@
// __SDEFILE__ - This file is a dependency for the stand-alone environment
// eslint-disable-next-line no-unused-vars
import React, { forwardRef } from 'react'
/**
* A component to render an SVG group
*
* @component
* @param {object} props - All component props
* @param {JSX.Element} props.children - The component children, will be rendered inside the group
* @returns {JSX.Element}
*/
export const Group = forwardRef((props, ref) => (
<g {...props} ref={ref}>
{props.children}

View file

@ -16,8 +16,11 @@ import { Circle as DefaultCircle } from './circle.mjs'
import { getId, getProps, withinPartBounds, translateStrings } from './utils.mjs'
import { Link as WebLink } from '@freesewing/react/components/Link'
/*
* Allow people to override these components
/**
* Default pattern components that you can override
*
* @public
* @constant
*/
const defaultComponents = {
Svg: DefaultSvg,
@ -34,9 +37,17 @@ const defaultComponents = {
Circle: DefaultCircle,
}
/*
* The pattern component
* FIXME: document props
/**
* A component to render a FreeSewing pattern based on its renderProps
*
* @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.string = {}] - Strings to use for translation
* @param {object} props.renderProps - The pattern's renderProps as generated by FreeSewing core
* @returns {JSX.Element}
*/
const Pattern = forwardRef((props, ref) => {
if (!props.renderProps) return null
@ -102,3 +113,17 @@ export {
// The Pattern component itself
Pattern,
}
// Also export default components
export const Svg = DefaultSvg
export const Defs = DefaultDefs
export const Group = DefaultGroup
export const Stack = DefaultStack
export const Part = DefaultPart
export const Point = DefaultPoint
export const Path = DefaultPath
export const Snippet = DefaultSnippet
export const Grid = DefaultGrid
export const Text = DefaultText
export const TextOnPath = DefaultTextOnPath
export const Circle = DefaultCircle

View file

@ -2,6 +2,20 @@
import React, { forwardRef } from 'react'
import { getId, getProps } from './utils.mjs'
/**
* A component to render an inner FreeSewing Part in a pattern (no group)
*
* @component
* @param {object} props - All component props
* @param {string} props.stackName - The name of the stack the part belongs to
* @param {string} props.partName - The name of the part
* @param {object} props.part - The part object itself
* @param {object} props.settings - The pattern settings object
* @param {object} props.components - An object holding the pattern compnents to use
* @param {object} props.strings - An object holding translations
* @param {object} props.drillProps - An object holding extra props to pass down (used in Xray mode)
* @returns {JSX.Element}
*/
export const PartInner = forwardRef(
({ stackName, partName, part, settings, components, strings, drillProps }, ref) => {
const { Group, Path, Point, Snippet } = components
@ -50,6 +64,20 @@ export const PartInner = forwardRef(
PartInner.displayName = 'PartInner'
/**
* A component to render a FreeSewing Part (group) in a pattern
*
* @component
* @param {object} props - All component props
* @param {string} props.stackName - The name of the stack the part belongs to
* @param {string} props.partName - The name of the part
* @param {object} props.part - The part object itself
* @param {object} props.settings - The pattern settings object
* @param {object} props.components - An object holding the pattern compnents to use
* @param {object} props.strings - An object holding translations
* @param {object} props.drillProps - An object holding extra props to pass down (used in Xray mode)
* @returns {JSX.Element}
*/
export const Part = ({ stackName, partName, part, settings, components, strings, drillProps }) => {
const { Group } = components

View file

@ -2,6 +2,20 @@
import React from 'react'
import { getId, getProps } from './utils.mjs'
/**
* A component to render a FreeSewing Path in a pattern
*
* @component
* @param {object} props - All component props
* @param {string} props.stackName - The name of the stack the part belongs to
* @param {string} props.partName - The name of the part
* @param {string} props.pathName - The name of the path
* @param {object} props.path - The path object itself
* @param {object} props.settings - The pattern settings object
* @param {object} props.components - An object holding the pattern compnents to use
* @param {object} props.strings - An object holding translations
* @returns {JSX.Element}
*/
export const Path = ({ stackName, pathName, path, partName, settings, components, strings }) => {
// Don't render hidden paths
if (path.hidden) return null

View file

@ -2,10 +2,25 @@
import React from 'react'
import { withinPartBounds } from './utils.mjs'
/**
* A component to render a FreeSewing Point in a pattern
*
* @component
* @param {object} props - All component props
* @param {string} props.stackName - The name of the stack the part belongs to
* @param {string} props.partName - The name of the part
* @param {string} props.pointName - The name of the point
* @param {object} props.point - The point object itself
* @param {object} props.components - An object holding the pattern compnents to use
* @param {object} props.strings - An object holding translations
* @returns {JSX.Element}
*/
export const Point = ({ stackName, partName, pointName, part, point, components, strings }) => {
/*
* Don't include points outside the part bounding box
* Unless the `data-render-always` attribute is set
*
* FIXME: This is undocumented
*/
if (!withinPartBounds(point, part) && !point.attributes.list['data-render-always']) return null

View file

@ -1,8 +1,16 @@
// __SDEFILE__ - This file is a dependency for the stand-alone environment
// eslint-disable-next-line no-unused-vars
import React from 'react'
import { getProps } from './utils.mjs'
/**
* A component to render a FreeSewing Snippet in a pattern
*
* @component
* @param {object} props - All component props
* @param {object} props.snippet - The snippet object itself
* @param {object} props.settings - The pattern settings object
* @returns {JSX.Element}
*/
export const Snippet = ({ snippet, settings }) => {
if (!snippet?.anchor || !snippet.def) return null
if (!settings[0].complete && !snippet.attributes.list?.['data-force']?.[0]) return null

View file

@ -1,6 +1,19 @@
import React from 'react'
import { getProps } from './utils.mjs'
/**
* A component to render a FreeSewing Stack inside a pattern
*
* @component
* @param {object} props - All component props
* @param {string} props.stackName - The name of the stack the part belongs to
* @param {object} props.stack - The stack object itself
* @param {object} props.settings - The pattern settings object
* @param {object} props.components - An object holding the pattern components to use
* @param {object} props.strings - An object holding translations
* @param {object} props.drillProps - An object holding extra props to pass down (used in Xray mode)
* @returns {JSX.Element}
*/
export const Stack = ({ stackName, stack, settings, components, strings, drillProps }) => {
const { Group, Part, Grid } = components

View file

@ -2,6 +2,21 @@
import React from 'react'
import { forwardRef } from 'react'
/**
* A component to render an SVG tag to hold a FreeSewing pattern
*
* @component
* @param {object} props - All component props
* @param {JSX.Element} props.children - The component children, will be rendered inside the SVG tag
* @param {strign} [props.className = 'freesewing pattern'] - The CSS classes to apply to the SVG tag
* @param {string} [props.embed = true] - Set this to false to output SVG suitable for printing rather than auto-scaled SVG
* @param {number} props.heigth - The pattern height in mm
* @param {string} [props.locale = en] - The locale/language to use
* @param {object} [props.style = {}] - Any additional style to apply to the SVG tag
* @param {object} [props.viewBox = false] - Set this to use a custom viewBox attribute rather than the default 0 0 width height
* @param {number} props.width - The pattern width in mm
* @returns {JSX.Element}
*/
export const Svg = forwardRef(
(
{

View file

@ -2,6 +2,15 @@
import React from 'react'
import { translateStrings } from './utils.mjs'
/**
* A component to render a tspan tag in a FreeSewing pattern
*
* @component
* @param {object} props - All component props
* @param {object} props.point - The point that the text is defined on
* @param {object} strings - The translation strings
* @returns {JSX.Element}
*/
export const TextSpans = ({ point, strings }) => {
const translated = translateStrings(point.attributes.list['data-text'], strings)
const text = []
@ -27,12 +36,31 @@ export const TextSpans = ({ point, strings }) => {
return text
}
/**
* A component to render a text tag in a FreeSewing pattern
*
* @component
* @param {object} props - All component props
* @param {object} props.point - The point that the text is defined on
* @param {object} strings - The translation strings
* @returns {JSX.Element}
*/
export const Text = ({ point, strings }) => (
<text x={point.x} y={point.y} {...point.attributes.textProps}>
<TextSpans point={point} strings={strings} />
</text>
)
/**
* A component to render a text along a path in a FreeSewing pattern
*
* @component
* @param {object} props - All component props
* @param {object} props.path - The path that the text is to be rendered along
* @param {string} props.pathId - The ID of the path
* @param {object} strings - The translation strings
* @returns {JSX.Element}
*/
export const TextOnPath = ({ path, pathId, strings }) => {
const textPathProps = {
xlinkHref: '#' + pathId,

View file

@ -1,5 +1,47 @@
import React from 'react'
/**
* A method to generated an ID for an object part of a FreeSewing pattern
*
* @public
* @param {object} parameters - All parameters passed as an object
* @param {object} [parameters.settings = {}] - The pattern settings
* @param {string} [parameters.stackName = false] - An optional stack name
* @param {string} [parameters.partName = false] - An optional part name
* @param {string} [parameters.pathName = false] - An optional path name
* @param {string} [parameters.pointName = false] - An optional point name
* @param {string} [parameters.snippetName = false] - An optional snippet name
* @param {string} [parameters.name = false] - An optional name
* @param {Part} parameters.part - The part to check the point against
* @returns {string}
*/
export const getId = ({
settings = {},
stackName = false,
partName = false,
pathName = false,
pointName = false,
snippetName = false,
name = false,
}) => {
let id = settings.idPrefix || ''
if (stackName) id += `${stackName}-`
if (partName) id += `${partName}-`
if (pathName) id += `${pathName}-`
if (pointName) id += `${pointName}-`
if (snippetName) id += `${snippetName}-`
if (name) id += name
return id
}
/**
* A method to extract React props from an classic object
*
* @public
* @param {object} obj - The object to extract props from
* @returns {object}
*/
export const getProps = (obj) => {
/** I can't believe it but there seems to be no method on NPM todo this */
const cssKey = (key) => {
@ -38,34 +80,15 @@ export const getProps = (obj) => {
return props
}
export const withinPartBounds = (point, part) =>
point.x >= part.topLeft.x &&
point.x <= part.bottomRight.x &&
point.y >= part.topLeft.y &&
point.y <= part.bottomRight.y
? true
: false
export const getId = ({
settings = {},
stackName = false,
partName = false,
pathName = false,
pointName = false,
snippetName = false,
name = false,
}) => {
let id = settings.idPrefix || ''
if (stackName) id += `${stackName}-`
if (partName) id += `${partName}-`
if (pathName) id += `${pathName}-`
if (pointName) id += `${pointName}-`
if (snippetName) id += `${snippetName}-`
if (name) id += name
return id
}
/**
* A method to translate strings for a FreeSewing pattern
*
* @public
* @param {object} [settings = {}] - The pattern settings
* @param {array} list - An array with strings (or arrays of strings) to translate
* @param {object} [translations = {}] - An object holding translations
* @returns {string}
*/
export const translateStrings = (list, translations = {}) => {
let translated = ''
if (!list) return translated
@ -80,3 +103,19 @@ export const translateStrings = (list, translations = {}) => {
return translated
}
/**
* A method to determine whether a FreeSewing point is within the bounding box of a FreeSewing part
*
* @public
* @param {Point} point - The point to check
* @param {Part} part - The part to check the point against
* @returns {boolean}
*/
export const withinPartBounds = (point, part) =>
point.x >= part.topLeft.x &&
point.x <= part.bottomRight.x &&
point.y >= part.topLeft.y &&
point.y <= part.bottomRight.y
? true
: false

View file

@ -9,6 +9,7 @@ jsdoc -c jsdoc.json components/Collection/* > ../../sites/dev/prebuild/jsdoc/rea
jsdoc -c jsdoc.json components/Control/* > ../../sites/dev/prebuild/jsdoc/react/components/control.json
jsdoc -c jsdoc.json components/CuratedSet/* > ../../sites/dev/prebuild/jsdoc/react/components/curatedset.json
jsdoc -c jsdoc.json components/Docusaurus/* > ../../sites/dev/prebuild/jsdoc/react/components/docusaurus.json
jsdoc -c jsdoc.json components/DiffViewer/* > ../../sites/dev/prebuild/jsdoc/react/components/diffviewer.json
jsdoc -c jsdoc.json components/Echart/* > ../../sites/dev/prebuild/jsdoc/react/components/echart.json
jsdoc -c jsdoc.json components/Editor/* > ../../sites/dev/prebuild/jsdoc/react/components/editor.json
jsdoc -c jsdoc.json components/Heading/* > ../../sites/dev/prebuild/jsdoc/react/components/heading.json
@ -27,3 +28,4 @@ jsdoc -c jsdoc.json components/Newsletter/* > ../../sites/dev/prebuild/jsdoc/rea
jsdoc -c jsdoc.json components/Null/* > ../../sites/dev/prebuild/jsdoc/react/components/null.json
jsdoc -c jsdoc.json components/Number/* > ../../sites/dev/prebuild/jsdoc/react/components/number.json
jsdoc -c jsdoc.json components/Patrons/* > ../../sites/dev/prebuild/jsdoc/react/components/patrons.json
jsdoc -c jsdoc.json components/Pattern/* > ../../sites/dev/prebuild/jsdoc/react/components/pattern.json