1
0
Fork 0

feat: Migrated to React 19

This commit is contained in:
joostdecock 2025-02-22 15:58:35 +01:00
parent 0a9c3d9473
commit 9ab297a471
502 changed files with 16459 additions and 21191 deletions

View file

@ -13,6 +13,9 @@ _types:
dev:
'mocha': *mocha
'chai': *chai
#
# Designs
#
aaron:
peer:
'@freesewing/brian': *freesewing
@ -45,21 +48,6 @@ charlie:
peer:
'@freesewing/titan': *freesewing
'@freesewing/snapseries': *freesewing
core:
_:
'@freesewing/core-plugins': *freesewing
'bezier-js': '6.1.4'
'hooks': '0.3.2'
'lodash.get': &_get '4.4.2'
'lodash.set': &_set '4.3.2'
'lodash.unset': &_unset '4.5.2'
'lodash.clonedeep': '^4.5.0'
dev:
'eslint': &eslint '8.57.0'
'nyc': '17.1.0'
'mocha': *mocha
'chai': *chai
'sinon': &sinon '^18.0.0'
diana:
peer:
'@freesewing/brian': *freesewing
@ -89,15 +77,6 @@ lily:
peer:
'@freesewing/titan': *freesewing
'@freesewing/paco': *freesewing
new-design:
_:
'axios': &axios '1.7.2'
'chalk': '5.3.0'
'execa': '9.2.0'
'mustache': &mustache '4.2.0'
'ora': &ora '8.0.1'
'prompts': '2.4.2'
'recursive-readdir': '2.2.3'
noble:
peer:
'@freesewing/bella': *freesewing
@ -105,12 +84,6 @@ paco:
peer:
'@freesewing/titan': *freesewing
'@freesewing/snapseries': *freesewing
core-plugins:
dev:
'@freesewing/plugin-annotations': *freesewing
'@freesewing/plugin-mirror': *freesewing
'@freesewing/plugin-round': *freesewing
'@freesewing/plugin-sprinkle': *freesewing
plugintest:
peer:
'@freesewing/plugin-annotations': *freesewing
@ -124,26 +97,6 @@ plugintest:
'@freesewing/plugin-sprinkle': *freesewing
'@freesewing/plugin-svgattr': *freesewing
'@freesewing/plugin-theme': *freesewing
react:
_:
axios: *axios
highlight.js: "^11.11.0"
html-react-parser: "^5.0.7"
luxon: "^3.5.0"
nuqs: "^1.17.6"
react-markdown: "^9.0.1"
tlds: "^1.255.0"
use-local-storage-state: "19.1.0"
use-session-storage-state: "^19.0.0"
peer:
react: "^18.2.0"
rehype-jargon:
_:
'unist-util-visit': &unist-util-visit '5.0.0'
'hast-util-from-html': '2.0.1'
rehype-highlight-lines:
_:
'unist-util-remove': '4.0.0'
sandy:
peer:
'@freesewing/snapseries': *freesewing
@ -187,6 +140,34 @@ yuri:
'@freesewing/brian': *freesewing
'@freesewing/plugin-bust': *freesewing
#
# Plugins
#
core-plugins:
dev:
'@freesewing/plugin-annotations': *freesewing
'@freesewing/plugin-mirror': *freesewing
'@freesewing/plugin-round': *freesewing
'@freesewing/plugin-sprinkle': *freesewing
#
# Packages
#
core:
_:
'@freesewing/core-plugins': *freesewing
'bezier-js': '6.1.4'
'hooks': '0.3.2'
'lodash.get': &_get '4.4.2'
'lodash.set': &_set '4.3.2'
'lodash.unset': &_unset '4.5.2'
'lodash.clonedeep': '^4.5.0'
dev:
'eslint': &eslint '8.57.0'
'nyc': '17.1.0'
'mocha': *mocha
'chai': *chai
'sinon': &sinon '^18.0.0'
collection:
_:
# Designs
@ -255,220 +236,26 @@ collection:
# Other
'@freesewing/core': *freesewing
'@freesewing/snapseries': *freesewing
# Sites go here
backend:
react:
_:
'@aws-sdk/client-sesv2': '3.592.0'
'@prisma/client': &prisma '5.15.0'
'bcryptjs': '2.4.3'
'cors': '2.8.5'
'dotenv': '16.4.5'
'express': '4.19.2'
'js-yaml': &jsyaml '4.1.0'
'lodash.get': *_get
'mustache': *mustache
'otplib': '12.0.1'
'passport': '0.7.0'
'passport-http': '0.3.0'
'passport-jwt': '4.0.1'
'pino': '9.2.0'
'qrcode': '1.5.3'
'swagger-ui-dist': '5.17.10'
'swagger-ui-express': '5.0.0'
dev:
'chai': *chai
'chai-http': '5.1.1'
'esbuild': '0.21.3'
'mocha': *mocha
'mocha-steps': '1.3.0'
'nodemon': '3.1.0'
'prisma': *prisma
dev:
"@uiw/react-codemirror": "^4.23.8"
d3-drag: "3.0.0"
d3-selection: "3.0.0"
file-saver: "^2.0.5"
"highlight.js": "^11.11.1"
html-react-parser: "^5.2.2"
jotai: "^2.12.1"
jotai-location: "^0.5.5"
luxon: "^3.5.0"
pdfkit: "^0.16.0"
react-dropzone: "^14.3.5"
react-zoom-pan-pinch: "^3.7.0"
svg-to-pdfkit: "^0.1.8"
use-local-storage-state: "^19.5.0"
web-worker: "^1.5.0"
peer:
react: &react "^19.0.0"
utils:
_:
'@mdx-js/mdx': &mdx '^3.0.0'
'@mdx-js/react': *mdx
'@mdx-js/runtime': &mdxRuntime '2.0.0-next.9'
'@next/bundle-analyzer': &next '14.2.3'
'@tailwindcss/typography': &tailwindTypography '0.5.13'
'algoliasearch': &algoliasearch '4.23.3'
'daisyui': &daisyui '4.11.1'
'lodash.get': *_get
'lodash.orderby': &_orderby '4.6.0'
'lodash.set': *_set
'next': *next
'react': &react '18.3.1'
'react-copy-to-clipboard': &reactCopyToClipboard '5.1.0'
'react-dom': *react
'react-hotkeys-hook': &reactHotkeysHook '4.5.0'
'react-instantsearch-dom': &reactInstantsearchDom '6.40.4'
'react-instantsearch-hooks-web': &reactInstantsearchHooksWeb '6.47.3'
'react-swipeable': &reactSwipeable '7.0.1'
'react-timeago': &reactTimeago '7.2.0'
'rehype-autolink-headings': &rehypeAutolinkHeadings '7.1.0'
'rehype-highlight': &rehypeHighlight '7.0.0'
'rehype-sanitize': &rehypeSanitize '6.0.0'
'rehype-slug': &rehypeSlug '6.0.0'
'rehype-stringify': &rehypeStringify '10.0.1'
'remark': &remark 15.0.1
# see: https://github.com/npm/cli/issues/2610#issuecomment-1295371753
'remark-copy-linked-files': &remarkCopyLinkedFiles 'git+https://git@github.com/joostdecock/remark-copy-linked-files'
'remark-gfm': &remarkGfm '4.0.0'
'strip-markdown': &stripMarkdown 6.0.0
dev: &nextSiteDevDependencies
'autoprefixer': &autoprefixer '10.4.19'
'js-yaml': &jsYaml '4.1.0'
'postcss': &postcss '8.4.38'
'remark-extract-frontmatter': '3.2.0'
'remark-mdx-frontmatter': &mdxfrontmatter '5.0.0'
'tailwindcss': &tailwindcss '3.4.3'
'yaml-loader': '0.8.1'
"@babel/preset-react": "^7.26.3"
lab:
_:
'@mdx-js/mdx': *mdx
'@mdx-js/react': *mdx
'@mdx-js/runtime': *mdxRuntime
'@tailwindcss/typography': *tailwindTypography
'algoliasearch': *algoliasearch
'd3-dispatch': &d3dispatch '3.0.1'
'd3-drag': &d3drag '3.0.0'
'd3-selection': &d3selection '3.0.0'
'daisyui': *daisyui
'i18next': &i18next '23.11.5'
'lodash.get': *_get
'lodash.orderby': *_orderby
'lodash.set': *_set
'next': *next
'next-i18next': &nextI18next '15.3.0'
'ora': *ora
'react': *react
'react-copy-to-clipboard': *reactCopyToClipboard
'react-hotkeys-hook': *reactHotkeysHook
'react-i18next': &reactI18next '14.1.2'
'react-instantsearch-dom': *reactInstantsearchDom
'react-swipeable': *reactSwipeable
'react-timeago': *reactTimeago
'rehype-autolink-headings': *rehypeAutolinkHeadings
'rehype-highlight': *rehypeHighlight
'rehype-sanitize': *rehypeSanitize
'rehype-slug': *rehypeSlug
'rehype-stringify': *rehypeStringify
'remark-copy-linked-files': *remarkCopyLinkedFiles
'remark-gfm': *remarkGfm
'remark-mdx-frontmatter': *mdxfrontmatter
dev:
*nextSiteDevDependencies
org:
_:
'@bugsnag/js': &bugsnag 7.23.0
'@bugsnag/plugin-react': 8.1.1
'@mdx-js/mdx': *mdx
'@mdx-js/react': *mdx
'@mdx-js/runtime': *mdxRuntime
"@tailwindcss/nesting": &twnesting "^0.0.0-insiders.565cd3e"
'@tailwindcss/typography': *tailwindTypography
'algoliasearch': *algoliasearch
'react-copy-to-clipboard': *reactCopyToClipboard
'daisyui': *daisyui
'echarts': &echarts 5.5.0
'echarts-for-react': &echartsReact 3.0.2
'jotai': &jotai '2.8.3'
'jotai-location': &jotai-location '0.5.5'
'lodash.get': *_get
'lodash.orderby': *_orderby
'lodash.set': *_set
'luxon': '3.5.0'
'next': *next
'next-i18next': *nextI18next
'ora': *ora
'react': *react
'react-dom': *react
'react-dropzone': &dropzone '14.2.3'
'react-hotkeys-hook': *reactHotkeysHook
"react-i18next": *reactI18next
'react-instantsearch-dom': *reactInstantsearchDom
'react-instantsearch-hooks-web': *reactInstantsearchHooksWeb
'react-swipeable': *reactSwipeable
'react-timeago': *reactTimeago
'react-zoom-pan-pinch': &zoompanpinch '3.4.4'
'rehype-autolink-headings': *rehypeAutolinkHeadings
'rehype-highlight': *rehypeHighlight
'rehype-sanitize': *rehypeSanitize
'rehype-slug': *rehypeSlug
'rehype-stringify': *rehypeStringify
'remark': *remark
'remark-copy-linked-files': *remarkCopyLinkedFiles
'remark-gfm': *remarkGfm
'remark-mdx-frontmatter': *mdxfrontmatter
'strip-markdown': *stripMarkdown
'use-local-storage-state': &use-local-storage-state 19.2.0
'yaml-loader': 0.8.1
dev: *nextSiteDevDependencies
sde:
_:
"@freesewing/core": *freesewing
"@freesewing/core-plugins": *freesewing
"@freesewing/brian": *freesewing
"@freesewing/bent": *freesewing
"@freesewing/titan": *freesewing
"@freesewing/bella": *freesewing
"@freesewing/breanna": *freesewing
"@freesewing/plugin-bust": *freesewing
"@freesewing/plugin-timing": *freesewing
"@freesewing/plugin-theme": *freesewing
"@freesewing/plugin-i18n": *freesewing
"@freesewing/snapseries": *freesewing
"@freesewing/react": *freesewing
'@mdx-js/mdx': *mdx
'@mdx-js/react': *mdx
'@mdx-js/runtime': *mdxRuntime
"@tailwindcss/nesting": *twnesting
'@tailwindcss/typography': *tailwindTypography
'autoprefixer': *autoprefixer
'axios': *axios
'd3-dispatch': *d3dispatch
'd3-drag': *d3drag
'd3-selection': *d3selection
'daisyui': *daisyui
'echarts': *echarts
'echarts-for-react': *echartsReact
'file-saver': latest
'i18next': *i18next
'jotai': *jotai
'jotai-location': *jotai-location
'js-yaml': *jsyaml
'lodash.debounce': latest
'lodash.get': *_get
'lodash.orderby': *_orderby
'lodash.set': *_set
'mustache': *mustache
"next": *next
'next-i18next': *nextI18next
'pdfkit': latest
'postcss-for': latest
"react": *react
"react-dom": *react
'react-copy-to-clipboard': *reactCopyToClipboard
'react-hotkeys-hook': *reactHotkeysHook
"react-i18next": *reactI18next
'react-dropzone': *dropzone
'react-swipeable': *reactSwipeable
'react-timeago': *reactTimeago
'react-zoom-pan-pinch': *zoompanpinch
'remark-gfm': *remarkGfm
'remark-frontmatter': latest
'remark-mdx-frontmatter': *mdxfrontmatter
'remark-smartypants': latest
"slugify": latest
'svg-to-pdfkit': latest
'tailwindcss': *tailwindcss
'tlds': latest
'use-local-storage-state': *use-local-storage-state
'web-worker': latest
lodash: "^4.17.21"
tlds: "^1.255.0"

View file

@ -79,7 +79,7 @@ packageJson:
"./components/Button": "./components/Button/index.mjs"
"./components/Collection": "./components/Collection/index.mjs"
"./components/Control": "./components/Control/index.mjs"
"./components/CopyToClipboard": "./components/CopyToClipboard/index.mjs"
"./components/CopyToClipboardButton": "./components/CopyToClipboardButton/index.mjs"
"./components/Design": "./components/Design/index.mjs"
"./components/Docusaurus": "./components/Docusaurus/index.mjs"
"./components/Editor": "./components/Editor/index.mjs"

View file

@ -8,7 +8,5 @@
"prettier-config": "FreeSewing's shared configuration for prettier",
"react": "React components, hooks and context by/for FreeSewing",
"snapseries": "A series of common sizes for elastics and other series to be used with snapped percentage options",
"utils": "A number of utilities, typically used by FreeSewing frontend code",
"rehype-jargon": "A Rehype plugin for jargon terms",
"rehype-highlight-lines": "A Rehype plugin to add highlighted lines to code blocks"
"utils": "A number of utilities, typically used by FreeSewing frontend code"
}

33002
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -60,7 +60,6 @@
"all-contributors-cli": "^6.26.1",
"axios": "^1.5.1",
"chalk": "^4.1.0",
"codecov": "^3.8.3",
"cross-env": "^7.0.2",
"eslint": "^8.23.1",
"eslint-plugin-jsonc": "^2.4.0",
@ -78,8 +77,6 @@
"nyc": "^15.1.0",
"prettier": "^3.0.0",
"pretty-quick": "^4.0.0",
"prop-types": "^15.7.2",
"react": "^18.2.0",
"rimraf": "^5.0.0",
"standard": "^17.0.0"
},
@ -98,7 +95,8 @@
"eslint-config-next": "^14.0.1",
"glob": "^10.3.10",
"rehype-format": "^5.0.0",
"rehype-stringify": "^10.0.1"
"rehype-stringify": "^10.0.1",
"tlds": "^1.255.0"
},
"engines": {
"node": ">=20.0"

View file

@ -24,15 +24,7 @@
"lint": "npx eslint 'lib/*.mjs'"
},
"peerDependencies": {},
"dependencies": {
"axios": "1.7.2",
"chalk": "5.3.0",
"execa": "9.2.0",
"mustache": "4.2.0",
"ora": "8.0.1",
"prompts": "2.4.2",
"recursive-readdir": "2.2.3"
},
"dependencies": {},
"devDependencies": {},
"files": [
"README.md",

View file

@ -29,7 +29,7 @@ import { ModalWrapper } from '@freesewing/react/components/Modal'
import { NumberCircle } from '@freesewing/react/components/Number'
import { StringInput, FormControl, ListInput } from '@freesewing/react/components/Input'
import { DisplayRow } from './shared.mjs'
import { CopyToClipboard } from '@freesewing/react/components/CopyToClipboard'
import { CopyToClipboardButton } from '@freesewing/react/components/CopyToClipboardButton'
import { TimeAgo, TimeToGo } from '@freesewing/react/components/Time'
import { KeyVal } from '@freesewing/react/components/KeyVal'
@ -303,12 +303,12 @@ const ShowNewApikey = ({ apikey }) => (
</div>
<h6 className="tw-flex tw-flex-row tw-items-center">
Key
<CopyToClipboard sup content={apikey.key} label="API key ID" />
<CopyToClipboardButton sup content={apikey.key} label="API key ID" />
</h6>
<pre>{apikey.key}</pre>
<h6 className="tw-flex tw-flex-row tw-items-center">
Secret
<CopyToClipboard sup content={apikey.secret} label="API key secret" />
<CopyToClipboardButton sup content={apikey.secret} label="API key secret" />
</h6>
<pre>{apikey.secret}</pre>
<Popout warning compact>

View file

@ -16,7 +16,7 @@ import { NoIcon, LockIcon } from '@freesewing/react/components/Icon'
import { PasswordInput } from '@freesewing/react/components/Input'
import { Popout } from '@freesewing/react/components/Popout'
import { NumberCircle } from '@freesewing/react/components/Number'
import { CopyToClipboard } from '@freesewing/react/components/CopyToClipboard'
import { CopyToClipboardButton } from '@freesewing/react/components/CopyToClipboardButton'
/*
* Component for the account/security/password page
@ -166,7 +166,7 @@ export const Mfa = ({ welcome = false, title = true }) => {
<div className="hljs tw-my-4">
<div className="tw-flex tw-flex-row tw-justify-between tw-items-center tw-text-xs tw-font-medium tw-text-warning tw-mt-1 tw-border-b tw-border-neutral-content tw-border-opacity-25 tw-px-4 tw-py-1 tw-mb-2 lg:tw-text-sm">
<span>MFA Scratch Codes</span>
<CopyToClipboard
<CopyToClipboardButton
content={
'FreeSewing MFA Scratch Codes:\n' +
scratchCodes.map((code) => code + '\n').join('')

View file

@ -42,7 +42,6 @@ import {
import { IconButton } from '@freesewing/react/components/Button'
import { ModalWrapper } from '@freesewing/react/components/Modal'
import { KeyVal } from '@freesewing/react/components/KeyVal'
import { CopyToClipboard as Copy } from 'react-copy-to-clipboard'
const filterAtom = atomWithHash('filter', { example: true })

View file

@ -1,7 +1,7 @@
import React, { useContext, useState } from 'react'
import { copyToClipboard } from '@freesewing/utils'
import ReactDOMServer from 'react-dom/server'
import { CopyIcon, OkIcon } from '@freesewing/react/components/Icon'
import { CopyToClipboard as Copy } from 'react-copy-to-clipboard'
import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus'
const strip = (html) =>
@ -9,7 +9,8 @@ const strip = (html) =>
? html
: new DOMParser().parseFromString(html, 'text/html').body.textContent || ''
const handleCopied = (setCopied, setLoadingStatus, label) => {
const handleCopied = (content, setCopied, setLoadingStatus, label) => {
copyToClipboard(content)
setCopied(true)
setLoadingStatus([
true,
@ -20,7 +21,7 @@ const handleCopied = (setCopied, setLoadingStatus, label) => {
setTimeout(() => setCopied(false), 1000)
}
export const CopyToClipboard = ({ content, label = false, sup = false }) => {
export const CopyToClipboardButton = ({ content, label = false, sup = false }) => {
const [copied, setCopied] = useState(false)
const { setLoadingStatus } = useContext(LoadingStatusContext)
@ -30,8 +31,10 @@ export const CopyToClipboard = ({ content, label = false, sup = false }) => {
const style = sup ? 'tw-w-4 tw-h-4 tw--mt-4' : 'tw-w-5 tw-h-5'
return (
<Copy text={text} onCopy={() => handleCopied(setCopied, setLoadingStatus, label)}>
<button className={copied ? 'tw-text-success' : ''}>
<button
className={copied ? 'tw-text-success' : ''}
onClick={() => handleCopied(content, setCopied, setLoadingStatus, label)}
>
{copied ? (
<OkIcon
className={`${style} tw-text-success-content tw-bg-success tw-rounded-full tw-p-1`}
@ -41,6 +44,5 @@ export const CopyToClipboard = ({ content, label = false, sup = false }) => {
<CopyIcon className={`${style} tw-text-inherit`} />
)}
</button>
</Copy>
)
}

View file

@ -1,67 +0,0 @@
import React, { useContext, useState } from 'react'
import ReactDOMServer from 'react-dom/server'
import { horFlexClasses } from '@freesewing/utils'
import { CopyIcon, OkIcon } from '@freesewing/react/components/Icon'
import { CopyToClipboard as Copy } from 'react-copy-to-clipboard'
const strip = (html) =>
typeof DOMParser === 'undefined'
? html
: new DOMParser().parseFromString(html, 'text/html').body.textContent || ''
const handleCopied = (setCopied, label, update) => {
setCopied(true)
update.notifySuccess(label ? `${label} c` : 'C' + 'opied to clipboard')
setTimeout(() => setCopied(false), 1000)
}
export const CopyToClipboard = ({ content, label = false, sup = false, update }) => {
const [copied, setCopied] = useState(false)
const text =
typeof content === 'string' ? content : strip(ReactDOMServer.renderToStaticMarkup(content))
const style = sup ? 'tw-w-4 tw-h-4 tw--mt-4' : 'tw-w-5 tw-h-5'
return (
<Copy text={text} onCopy={() => handleCopied(setCopied, label, update)}>
<button className={copied ? 'tw-text-success' : ''}>
{copied ? (
<OkIcon
className={`${style} tw-text-success-content tw-bg-success tw-rounded-full tw-p-1`}
stroke={4}
/>
) : (
<CopyIcon className={`${style} tw-text-inherit`} />
)}
</button>
</Copy>
)
}
export const CopyToClipboardButton = ({ content, label = false, update, children }) => {
const [copied, setCopied] = useState(false)
const text =
typeof content === 'string' ? content : strip(ReactDOMServer.renderToStaticMarkup(content))
const style = 'tw-w-6 tw-h-6'
return (
<Copy text={text} onCopy={() => handleCopied(setCopied, label, update)}>
<button
className={`${horFlexClasses} tw-daisy-btn ${copied ? 'tw-daisy-btn-success' : 'tw-daisy-btn-primary'}`}
>
{copied ? (
<OkIcon
className={`${style} tw-text-success-content tw-bg-success tw-rounded-full tw-p-1`}
stroke={4}
/>
) : (
<CopyIcon className={`${style} tw-text-inherit`} />
)}
<div>{children}</div>
</button>
</Copy>
)
}

View file

@ -0,0 +1,232 @@
// Dependencies
import { linkClasses, horFlexClasses, patternUrlFromState } from '@freesewing/utils'
import { exportTypes, handleExport } from '../../lib/export/index.mjs'
// Hooks
import React, { useState } from 'react'
// Components
import { H1, H2, H3, H5 } from '@freesewing/react/components/Heading'
import { Popout } from '@freesewing/react/components/Popout'
import { HeaderMenu } from '../HeaderMenu.mjs'
import { EditIcon, CodeIcon, TipIcon, PrintIcon } from '@freesewing/react/components/Icon'
import CodeMirror from '@uiw/react-codemirror'
/**
* This is the editSettings view
*
* @param {Object} props - All the props
* @param {Function} props.config - The editor configuration
* @param {Object} props.state - The editor state object
* @param {Object} props.update - Helper object for updating the editor state
*/
export const EditSettingsView = (props) => {
const [settings, setSettings] = useState(props.state.settings)
return (
<>
<HeaderMenu state={state} {...{ config, update }} />
<div className="tw-m-auto tw-mt-8 tw-max-w-2xl tw-px-4 tw-mb-8">
<H1>Documenation</H1>
<PrimedSettingsEditor {...props} {...{ runningSettings, dconf }} />
</div>
</>
)
}
/**
* This is the React component for the settings editor itself
*/
export const PrimedSettingsEditor = (props) => {
/*
* Destructure props
*/
const { runningSettings } = props
/*
* React state
*/
/* eslint-disable-next-line no-unused-vars */
const [mSettings, update, setMSettings] = useStateObject(runningSettings) // Holds the settings
const [validationReport, setValidationReport] = useState(false) // Holds the validatino report
const [showDelta, setShowDelta] = useState(false)
const [deployOngoing, setDeployOngoing] = useState(false)
const [doValidate, setDoValidate] = useState(false)
const [kiosk, setKiosk] = useState(false)
const [localJson, setLocalJson] = useState(JSON.stringify(runningSettings, null, 2)) // Holds the settings as JSON
const [localYaml, setLocalYaml] = useState(yaml.stringify(runningSettings)) // Holds the settings as YAML
/*
* Method to revert to running settings
*/
const revert = () => setMSettings(cloneAsPojo(runningSettings))
/*
* API client
*/
const { api } = useApi()
/*
* Loading context
*/
const { setLoadingStatus } = useContext(LoadingStatusContext)
/*
* Helper method to deploy the settings
*/
const deploy = async () => {
setLoadingStatus([true, 'Uploading settings'])
setDeployOngoing(true)
const result = await api.deploy(mSettings)
return result[1] === 204
? setLoadingStatus([true, 'Settings updated', true, true])
: setLoadingStatus([true, `Unable to deploy the settings`, true, false])
}
if (!mSettings.cluster) return null
/*
* Handle settings delta
*/
const delta =
diffCheck(yaml.stringify(runningSettings), yaml.stringify(mSettings)).length > 1 ? true : false
if (deployOngoing)
return (
<>
<Box color="success">
<div className="flex flex-row items-center gap-2 text-success-content">
<div className="w-6 h-6">
<OkIcon className="w-6 h-6 text-success-content" stroke={4} />
</div>
Settings are being deployed
</div>
</Box>
<p>Please wait as Morio applies the new settings.</p>
</>
)
const onChangeYaml = (input) => {
let newSettings
try {
newSettings = yaml.parse(input)
if (newSettings) {
setLocalYaml(input)
setMSettings(newSettings)
}
} catch (err) {
// This is fine
}
}
const onChangeJson = (input) => {
let newSettings
try {
newSettings = JSON.parse(input)
if (newSettings) {
setLocalJson(input)
setMSettings(newSettings)
}
} catch (err) {
console.log(err)
// This is fine
}
}
return (
<>
{mSettings.preseed?.base ? (
<Popout warning>
<h5>These settings are preseeded</h5>
<p>
This Morio deployment uses preseeded settings. This means the settings are loaded from a
remote system, typically a version control system like GitLab or GitHub.
</p>
<p>
While you <b>can</b> update the settings here, those settings will be lost next time
Morio is reseeded.
<br />
You probably should <b>update the preseeded setting instead</b>.
</p>
</Popout>
) : null}
{doValidate ? (
<>
<ShowSettingsValidation
{...{
api,
deploy,
mSettings,
setLoadingStatus,
setValidationReport,
validationReport,
}}
/>
<p className="text-right w-full">
<button
className="btn btn-primary btn-outline btn-s btn-sm"
onClick={() => setDoValidate(false)}
>
<NoteIcon /> Back to editor
</button>
</p>
</>
) : (
<div className={kiosk ? 'absolute top-12 left-0 w-screen h-screen z-50 bg-base-100' : ''}>
<Tabs tabs="YAML, JSON">
<Tab id="json" name="test" label="As YAML">
<CodeMirror
value={localYaml}
height={kiosk ? '90vh' : '70vh'}
onChange={onChangeYaml}
/>
</Tab>
<Tab id="yaml" label="As JSON">
<CodeMirror
value={localJson}
height={kiosk ? '90vh' : '70vh'}
extensions={[jsonLang()]}
onChange={onChangeJson}
/>
</Tab>
</Tabs>
<div className="my-2 w-full flex flex-row flex-wrap items-center gap-2 justify-center">
<button
className="btn btn-primary btn-outline flex flex-row items-center gap-2"
onClick={() => setKiosk(!kiosk)}
>
<ExpandIcon /> {kiosk ? 'Collapse' : 'Expand'}
</button>
<button className="btn btn-primary" onClick={() => setDoValidate(true)}>
Validate Settings
</button>
</div>
</div>
)}
{!doValidate && delta ? (
<Popout note>
<h4>You have made changes that are yet to be deployed</h4>
<p>The settings have been edited, and are now different from the deployed settings.</p>
{showDelta ? (
<div className="my-4 w-full overflow-scroll">
<DiffViewer
from={yaml.stringify(runningSettings)}
to={yaml.stringify(mSettings)}
fromTitle="Currently deployed settings"
toTitle="Your edits"
/>
</div>
) : null}
<div className="flex flex-row flex-wrap gap-2 justify-end w-full">
<button className="btn btn-warning btn-ghost" onClick={revert}>
Revert to Running Settings
</button>
<button
className="btn btn-primary btn-outline"
onClick={() => setShowDelta(!showDelta)}
>
{showDelta ? 'Hide' : 'Show'} Settings Delta
</button>
</div>
</Popout>
) : null}
</>
)
}

View file

@ -7,7 +7,7 @@ import React, { useState } from 'react'
import { H1, H2, H3, H5 } from '@freesewing/react/components/Heading'
import { Popout } from '@freesewing/react/components/Popout'
import { HeaderMenu } from '../HeaderMenu.mjs'
import { CopyToClipboardButton } from '../CopyToClipboard.mjs'
import { CopyToClipboardButton } from '@freesewing/react/components/CopyToClipboardButton'
import { Highlight } from '@freesewing/react/components/Highlight'
import { EditIcon, CodeIcon, TipIcon, PrintIcon } from '@freesewing/react/components/Icon'

View file

@ -8,6 +8,7 @@ import { ExportView } from './ExportView.mjs'
import { UndosView } from './UndosView.mjs'
import { LayoutView } from './LayoutView.mjs'
import { DocsView } from './DocsView.mjs'
import { EditSettingsView } from './EditSettingsView.mjs'
import { ErrorIcon } from '@freesewing/react/components/Icon'
import {
OptionsIcon,
@ -61,6 +62,7 @@ export const View = (props) => {
if (view === 'undos') return <UndosView {...props} />
if (view === 'layout') return <LayoutView {...props} />
if (view === 'docs') return <DocsView {...props} />
if (view === 'editSettings') return <EditSettingsView {...props} />
return <h1 className="tw-ext-center tw-my-12">No view component for view {props.view}</h1>
}

View file

@ -1,5 +1,5 @@
import React from 'react'
import { CopyToClipboard } from '@freesewing/react/components/CopyToClipboard'
import { CopyToClipboardButton } from '@freesewing/react/components/CopyToClipboardButton'
const defaultTitles = {
js: 'Javascript',
@ -48,7 +48,7 @@ export const Highlight = ({
`}
>
<span>{label}</span>
{noCopy ? null : <CopyToClipboard content={copy ? copy : children} label={label} />}
{noCopy ? null : <CopyToClipboardButton content={copy ? copy : children} label={label} />}
</div>
<pre {...preProps}>{children}</pre>
</div>

View file

@ -1,5 +1,5 @@
import React, { useState, useContext } from 'react'
import { CopyToClipboard as Copy } from 'react-copy-to-clipboard'
import { copyToClipboard } from '@freesewing/utils'
import { LoadingStatusContext } from '@freesewing/react/context/LoadingStatus'
export const KeyVal = ({
@ -47,9 +47,15 @@ export const KeyVal = ({
)
return onClick === false ? (
<Copy text={val} onCopy={() => (noCopy ? null : handleCopied(setCopied, setLoadingStatus, k))}>
<button className="tw-daisy-btn-ghost tw-p-0">{inner}</button>
</Copy>
<button
className="tw-daisy-btn-ghost tw-p-0"
onClick={() => {
copyToClipboard(val)
handleCopied(setCopied, setLoadingStatus, k)
}}
>
{inner}
</button>
) : (
<button
className="tw-daisy-btn-ghost tw-p-0"

View file

@ -1,7 +1,7 @@
import React, { useState } from 'react'
import { shortUuid } from '@freesewing/utils'
import { Link } from '@freesewing/react/components/Link'
import { CopyToClipboard } from '@freesewing/react/components/CopyToClipboard'
import { CopyToClipboardButton } from '@freesewing/react/components/CopyToClipboardButton'
/*
* Displays a UUID, but shorter

View file

@ -32,7 +32,7 @@
"./components/Button": "./components/Button/index.mjs",
"./components/Collection": "./components/Collection/index.mjs",
"./components/Control": "./components/Control/index.mjs",
"./components/CopyToClipboard": "./components/CopyToClipboard/index.mjs",
"./components/CopyToClipboardButton": "./components/CopyToClipboardButton/index.mjs",
"./components/Design": "./components/Design/index.mjs",
"./components/Docusaurus": "./components/Docusaurus/index.mjs",
"./components/Editor": "./components/Editor/index.mjs",
@ -79,18 +79,24 @@
"prettier": "npx prettier --write 'components/**/*.mjs' 'hooks/**/*.mjs' 'lib/**/*.mjs' 'context/**/*.mjs' 'config/**/*.mjs'"
},
"peerDependencies": {
"react": "^18.2.0"
"react": "^19.0.0"
},
"dependencies": {
"axios": "1.7.2",
"highlight.js": "^11.11.0",
"html-react-parser": "^5.0.7",
"@uiw/react-codemirror": "^4.23.8",
"d3-drag": "3.0.0",
"d3-selection": "3.0.0",
"file-saver": "^2.0.5",
"highlight.js": "^11.11.1",
"html-react-parser": "^5.2.2",
"jotai": "^2.12.1",
"jotai-location": "^0.5.5",
"luxon": "^3.5.0",
"nuqs": "^1.17.6",
"react-markdown": "^9.0.1",
"tlds": "^1.255.0",
"use-local-storage-state": "19.1.0",
"use-session-storage-state": "^19.0.0"
"pdfkit": "^0.16.0",
"react-dropzone": "^14.3.5",
"react-zoom-pan-pinch": "^3.7.0",
"svg-to-pdfkit": "^0.1.8",
"use-local-storage-state": "^19.5.0",
"web-worker": "^1.5.0"
},
"devDependencies": {},
"files": [

View file

@ -1,17 +0,0 @@
# Change log for: rehype-highlight-lines
## 3.0.0 (2023-09-30)
### Changed
- All FreeSewing packages are now ESM only.
- All FreeSewing packages now use named exports.
- Dropped support for NodeJS 14. NodeJS 18 (LTS/hydrogen) or more recent is now required.
This is the **initial release**, and the start of this change log.
> Prior to version 2, FreeSewing was not a JavaScript project.
> As such, that history is out of scope for this change log.

View file

@ -1,162 +0,0 @@
<p align='center'><a
href="https://www.npmjs.com/package/rehype-highlight-lines"
title="rehype-highlight-lines on NPM"
><img src="https://img.shields.io/npm/v/rehype-highlight-lines.svg"
alt="rehype-highlight-lines on NPM"/>
</a><a
href="https://opensource.org/licenses/MIT"
title="License: MIT"
><img src="https://img.shields.io/npm/l/rehype-highlight-lines.svg?label=License"
alt="License: MIT"/>
</a><a
href="https://deepscan.io/dashboard#view=project&tid=2114&pid=2993&bid=23256"
title="Code quality on DeepScan"
><img src="https://deepscan.io/api/teams/2114/projects/2993/branches/23256/badge/grade.svg"
alt="Code quality on DeepScan"/>
</a><a
href="https://github.com/freesewing/freesewing/issues?q=is%3Aissue+is%3Aopen+label%3Apkg%3Arehype-highlight-lines"
title="Open issues tagged pkg:rehype-highlight-lines"
><img src="https://img.shields.io/github/issues/freesewing/freesewing/pkg:rehype-highlight-lines.svg?label=Issues"
alt="Open issues tagged pkg:rehype-highlight-lines"/>
</a><a
href="#contributors-"
title="All Contributors"
><img src="https://img.shields.io/badge/all_contributors-131-pink.svg"
alt="All Contributors"/>
</a></p><p align='center'><a
href="https://twitter.com/freesewing_org"
title="Follow @freesewing_org on Twitter"
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Follow%20us-blue.svg?logo=twitter&logoColor=white&logoWidth=15"
alt="Follow @freesewing_org on Twitter"/>
</a><a
href="https://chat.freesewing.org"
title="Chat with us on Discord"
><img src="https://img.shields.io/discord/698854858052075530?label=Chat%20on%20Discord"
alt="Chat with us on Discord"/>
</a><a
href="https://freesewing.org/patrons/join"
title="Become a FreeSewing Patron"
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Support%20us-blueviolet.svg?logo=cash-app&logoColor=white&logoWidth=15"
alt="Become a FreeSewing Patron"/>
</a><a
href="https://instagram.com/freesewing_org"
title="Follow @freesewing_org on Twitter"
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Follow%20us-E4405F.svg?logo=instagram&logoColor=white&logoWidth=15"
alt="Follow @freesewing_org on Twitter"/>
</a></p>
# rehype-highlight-lines
A Rehype plugin to add highlighted lines to code blocks
# FreeSewing
> [!TIP]
>#### Support FreeSewing: Become a patron, or make a one-time donation 🥰
>
> FreeSewing is an open source project maintained by Joost De Cock and financially supported by the FreeSewing patrons.
>
> If you feel FreeSewing is worthwhile, and you can spend a few coins without
hardship, then you should [join us and become a patron](https://freesewing.org/community/join).
## What am I looking at? 🤔
This repository is the FreeSewing *monorepo* holding all FreeSewing's websites, documentation, designs, plugins, and other NPM packages.
This folder holds: rehype-highlight-lines
If you're not entirely sure what to do or how to start, type this command:
```
npm run tips
```
> [!NOTE]
> If you don't want to set up a dev environment, you can run it in your browser:
>
> [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/freesewing/freesewing)
>
> We recommend that you fork our repository and then
> put `gitpod.io/#<entire-url-of-your-fork` into a browser
> to start up a browser-based dev environment of your own.
## About FreeSewing 💀
Where the world of makers and developers collide, that's where you'll find FreeSewing.
If you're a maker, checkout [freesewing.org](https://freesewing.org/) where you can generate
sewing patterns adapted to your measurements.
If you're a developer, the FreeSewing documentation lives at [freesewing.dev](https://freesewing.dev/).
The FreeSewing [core library](https://freesewing.dev/reference/api/) is a *batteries-included* toolbox
for parametric design of sewing patterns. But FreeSewing also provides a range
of [plugins](https://freesewing.dev/reference/plugins/) that further extend the
functionality of the platform.
If you have NodeJS installed, you can try it right now by running:
```bash
npx @freesewing/new-design
```
Getting started guides are available for:
- [Linux](https://freesewing.dev/tutorials/getting-started-linux/)
- [MacOS](https://freesewing.dev/tutorials/getting-started-mac/)
- [Windows](https://freesewing.dev/tutorials/getting-started-windows/)
The [pattern design tutorial](https://freesewing.dev/tutorials/pattern-design/) will
show you how to create your first parametric design.
## Getting started ⚡
To get started with FreeSewing, you can spin up our development environment with:
```bash
npx @freesewing/new-design
```
To work with FreeSewing's monorepo, you'll need [NodeJS v20](https://nodejs.org) on your system.
Once you have that, clone (or fork) this repo and run `npm run kickstart`:
```bash
git clone git@github.com:freesewing/freesewing.git
cd freesewing
npm run kickstart
```
## Links 👩‍💻
**Official channels**
- 💻 Makers website: [FreeSewing.org](https://freesewing.org)
- 💻 Developers website: [FreeSewing.dev](https://freesewing.dev)
- ✅ [Support](https://github.com/freesewing/freesewing/issues/new/choose),
[Issues](https://github.com/freesewing/freesewing/issues) &
[Discussions](https://github.com/freesewing/freesewing/discussions) on
[GitHub](https://github.com/freesewing/freesewing)
**Social media**
- 🐦 Twitter: [@freesewing_org](https://twitter.com/freesewing_org)
- 📷 Instagram: [@freesewing_org](https://instagram.com/freesewing_org)
**Places the FreeSewing community hangs out**
- 💬 [Discord](https://discord.freesewing.org/)
- 💬 [Facebook](https://www.facebook.com/groups/627769821272714/)
- 💬 [Reddit](https://www.reddit.com/r/freesewing/)
## License: MIT 🤓
© [Joost De Cock](https://github.com/joostdecock).
See [the license file](https://github.com/freesewing/freesewing/blob/develop/LICENSE) for details.
## Where to get help 🤯
For [Support](https://github.com/freesewing/freesewing/issues/new/choose),
please use the [Issues](https://github.com/freesewing/freesewing/issues) &
[Discussions](https://github.com/freesewing/freesewing/discussions) on
[GitHub](https://github.com/freesewing/freesewing).

View file

@ -1,4 +0,0 @@
// This file is auto-generated | All changes you make will be overwritten.
export const name = 'rehype-highlight-lines'
export const version = '3.3.0-rc.1'
export const data = { name, version }

View file

@ -1,47 +0,0 @@
{
"name": "rehype-highlight-lines",
"version": "3.3.0-rc.1",
"description": "A Rehype plugin to add highlighted lines to code blocks",
"author": "Joost De Cock <joost@joost.at> (https://github.com/joostdecock)",
"homepage": "https://freesewing.org/",
"repository": "github:freesewing/freesewing",
"license": "MIT",
"bugs": {
"url": "https://github.com/freesewing/freesewing/issues"
},
"funding": {
"type": "individual",
"url": "https://freesewing.org/patrons/join"
},
"keywords": [
"freesewing",
"freesewing"
],
"type": "module",
"module": "src/index.mjs",
"exports": {
".": "./src/index.mjs"
},
"scripts": {
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -",
"test": "echo \"rehype-highlight-lines: No tests configured. Perhaps you could write some?\" && exit 0",
"tips": "node ../../scripts/help.mjs",
"lint": "npx eslint 'src/*.mjs'"
},
"peerDependencies": {},
"dependencies": {
"unist-util-remove": "4.0.0"
},
"devDependencies": {},
"files": [
"src/**",
"README.md"
],
"publishConfig": {
"access": "public",
"tag": "next"
},
"engines": {
"node": ">= 20"
}
}

View file

@ -1,155 +0,0 @@
import { visit } from 'unist-util-visit'
import { remove } from 'unist-util-remove'
const dflts = {
commentTag: 'span',
commentClass: 'hljs-comment',
openingCommentHighlight: 'highlight-start',
closingCommentHighlight: 'highlight-end',
openingCommentStrikeout: 'strikeout-start',
closingCommentStrikeout: 'strikeout-end',
highlightTag: 'section',
highlightClass: 'highlight-lines',
strikeoutClass: 'strikeout-lines',
swallow: true,
}
export default (userOptions = {}) => {
// Merge defaults with user-supplied options
const options = {
...dflts,
...userOptions,
}
const splitParams = (node) => {
if (node.children.length === 1 && node.children[0].type === 'text') {
const content = node.children[0].value.split('\n')
node.children = content.map((value) =>
value.includes('//')
? {
type: 'element',
tagName: 'span',
properties: {
className: options.commentClass,
},
children: [{ type: 'text', value }],
}
: { type: 'text', value: value + '\n', isParamLine: true }
)
}
}
// Keep track of whether we've opened a highlight block
let isOpen = 0
let children = {}
// Detect opening or closing comment
const isOpeningOrClosingComment = (node) => {
if (
node &&
node.tagName === options.commentTag &&
node.properties?.className.includes(options.commentClass)
) {
if (node.children[0].value.includes(options.openingCommentHighlight))
return ['opening', 'highlight']
if (node.children[0].value.includes(options.closingCommentHighlight))
return ['closing', 'highlight']
if (node.children[0].value.includes(options.openingCommentStrikeout))
return ['opening', 'strikeout']
if (node.children[0].value.includes(options.closingCommentStrikeout))
return ['closing', 'strikeout']
}
return [false, 'highlight']
}
// Visitor method
const visitor = (node, i, parent) => {
const [type, variant] = isOpeningOrClosingComment(node)
if (type) {
if (type === 'opening') {
isOpen = 1
// Deal with extra linebreaks in the element before the start
const prev = parent.children[i - 1]
if (prev?.type === 'text' && prev.value.includes('\n'))
prev.value = prev.value.replace(/\n/g, '') + '\n'
if (options.swallow) node.__remove_dupes = true
} else if (type === 'closing') {
// Deal with extra linebreaks in the element before the end
const prev = children[i - 1]
if (prev.type === 'text' && prev.value.includes('\n') && !node.isParamLine)
prev.value = prev.value.trimEnd()
isOpen = 0
const curNode = { ...node }
parent.children[i] = {
type: 'element',
tagName: options.highlightTag,
properties: {
className: Array.isArray(options[`${variant}Class`])
? options[`${variant}Class`]
: [options[`${variant}Class`]],
},
children: [
{
type: 'element',
tagName: 'div',
properties: {
className: ['code-section-inner'],
},
children: [...Object.values(children)],
},
],
}
if (!options.swallow) parent[i].children.push(curNode)
children = {}
}
} else if (isOpen) {
if (
parent.tagName === 'code' ||
(parent.tagName === 'span' &&
parent.properties?.className &&
parent.properties.className.includes('hljs-params'))
) {
if (node.type === 'text' && node.value === '\n') {
// Linebreak
node.type = 'element'
node.tagName = 'span'
node.children = [
{
type: 'text',
value: '\n',
},
{
type: 'element',
tagName: 'span',
properties: {
className: ['code-line-break'],
},
},
]
}
// On the first highlighted line, trim the previous linebreak (not for param lines)
if (isOpen === 1 && node.type === 'text' && !node.isParamLine)
node.value = node.value.replace('\n', '')
children[i] = { ...node }
isOpen++
node.__remove_dupes = true
}
}
}
const isParamsNode = (node) =>
node?.properties?.className && node.properties.className.includes('hljs-params')
const transform = (tree) => {
visit(tree, (node) => isParamsNode(node), splitParams)
visit(tree, () => true, visitor)
remove(tree, (node) => node.__remove_dupes === true)
}
return transform
}

View file

@ -1,17 +0,0 @@
# Change log for: rehype-jargon
## 3.0.0 (2023-09-30)
### Changed
- All FreeSewing packages are now ESM only.
- All FreeSewing packages now use named exports.
- Dropped support for NodeJS 14. NodeJS 18 (LTS/hydrogen) or more recent is now required.
This is the **initial release**, and the start of this change log.
> Prior to version 2, FreeSewing was not a JavaScript project.
> As such, that history is out of scope for this change log.

View file

@ -1,288 +0,0 @@
<p align='center'><a
href="https://www.npmjs.com/package/rehype-jargon"
title="rehype-jargon on NPM"
><img src="https://img.shields.io/npm/v/rehype-jargon.svg"
alt="rehype-jargon on NPM"/>
</a><a
href="https://opensource.org/licenses/MIT"
title="License: MIT"
><img src="https://img.shields.io/npm/l/rehype-jargon.svg?label=License"
alt="License: MIT"/>
</a><a
href="https://deepscan.io/dashboard#view=project&tid=2114&pid=2993&bid=23256"
title="Code quality on DeepScan"
><img src="https://deepscan.io/api/teams/2114/projects/2993/branches/23256/badge/grade.svg"
alt="Code quality on DeepScan"/>
</a><a
href="https://github.com/freesewing/freesewing/issues?q=is%3Aissue+is%3Aopen+label%3Apkg%3Arehype-jargon"
title="Open issues tagged pkg:rehype-jargon"
><img src="https://img.shields.io/github/issues/freesewing/freesewing/pkg:rehype-jargon.svg?label=Issues"
alt="Open issues tagged pkg:rehype-jargon"/>
</a><a
href="#contributors-"
title="All Contributors"
><img src="https://img.shields.io/badge/all_contributors-131-pink.svg"
alt="All Contributors"/>
</a></p><p align='center'><a
href="https://twitter.com/freesewing_org"
title="Follow @freesewing_org on Twitter"
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Follow%20us-blue.svg?logo=twitter&logoColor=white&logoWidth=15"
alt="Follow @freesewing_org on Twitter"/>
</a><a
href="https://chat.freesewing.org"
title="Chat with us on Discord"
><img src="https://img.shields.io/discord/698854858052075530?label=Chat%20on%20Discord"
alt="Chat with us on Discord"/>
</a><a
href="https://freesewing.org/patrons/join"
title="Become a FreeSewing Patron"
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Support%20us-blueviolet.svg?logo=cash-app&logoColor=white&logoWidth=15"
alt="Become a FreeSewing Patron"/>
</a><a
href="https://instagram.com/freesewing_org"
title="Follow @freesewing_org on Twitter"
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Follow%20us-E4405F.svg?logo=instagram&logoColor=white&logoWidth=15"
alt="Follow @freesewing_org on Twitter"/>
</a></p>
# rehype-jargon
A Rehype plugin for jargon terms
## About
This [Rehype](https://github.com/rehypejs/rehype) plugin allows you to use _jargon_ in your
markdown/mdx/html content and use a centrally managed file of jargon terms and their definitions.
![An example of this plugin being used on freesewing.org](example.png)
## Install
To install this plugin, run:
```
npm install --save rehype-jargon
```
## Getting started
> **Tip**: See https://github.com/joostdecock/rehype-jargon-example for a minimal repository that uses this plugin
### Create your jargon file
This plugin requires a _jargon file_ with terms defenitions. For example:
```js
export const jargon = {
rehype: "<b>rehype</b> is a tool that transforms HTML with plugins. These plugins can inspect and change the HTML. You can use rehype on the server, the client, CLIs, deno, etc.",
freesewing: "<b>FreeSewing</b> is an open source platform for made-to-measure sewing patterns. See <a href='https://freesewing.org/'>freesewing.org</a>"
}
```
### Import the plugin
Now import the plugin, and pass it your jargon:
```js
var remark = require('remark')
var html = require('remark-html')
var plugin = require('remark-jargon')
var jargon = require('./jargon.js')
remark()
.use(html)
.use(plugin, { jargon: jargon })
.process('This is a plugin for _remark_ originally written for _freesewing_.', function (err, file) {
console.log(String(file))
})
```
> **Note**
>
> This plugin will only add markup to your jargon if you _emphasize_ it.
### Style your jargon
You will need to add CSS to style your jargon properly, and hide the definition by default.
Below is an example to get you started:
```css
// Add a dashed line under jargon terms
.jargon-term {
text-decoration: underline dotted #228be6
}
// Add a question mark behind/above jargon terms
.jargon-term::after {
content: "?";
font-weight: bold;
display: inline-block;
transform: translate(0, -0.5em);
font-size: 75%;
color: #228be6;
margin-left: 3px;
}
// Hover behavior for the therm itself
.jargon-term:hover {
position: relative;
text-decoration: none;
cursor: help;
}
// Hide info by default
.jargon-term .jargon-info {
display: none
}
// Show info on hover
.jargon-term:hover .jargon-info {
display: block;
position: absolute;
top: 1.5em;
left: 0;
background: #F8F8F8;
border: 1px solid #DCDCDC;
padding: 1rem;
border-radius: 4px;
font-size: 90%;
min-width: 250px;
max-width: 450px;
z-index: 1;
}
```
## Tips for using jargon
### Lowercase your terms in the jargon file
When looking for terms to match, we lowercase the term your emphazised.
So in the jargon file, you should use `msf`, but in your text, you can use `MSF`, `Msf`, or `msf`.
### If you use HTML, only use inline elements
Your jargon term definition can contain HTML, but only inline elements.
Typically, you will want to stick to:
- Making things **bold**
- Inserting [links](#)
## Getting help
This plugin is written by/for [FreeSewing](https://github.com/freesewing).
For help or feedback, please stop by [the FreeSewing chat room](https://gitter.im/freesewing/development) or
[create an issue](https://github.com/freesewing/freesewing/issues/new).
## Use with Gatsby
Please see [gatsby-remark-jargon](https://github.com/freesewing/freesewing/tree/develop/packages/gatsby-remark-jargon) for
info and instructions on how to use this plugin with [Gatsby](https://www.gatsbyjs.org/).
# FreeSewing
> [!TIP]
>#### Support FreeSewing: Become a patron, or make a one-time donation 🥰
>
> FreeSewing is an open source project maintained by Joost De Cock and financially supported by the FreeSewing patrons.
>
> If you feel FreeSewing is worthwhile, and you can spend a few coins without
hardship, then you should [join us and become a patron](https://freesewing.org/community/join).
## What am I looking at? 🤔
This repository is the FreeSewing *monorepo* holding all FreeSewing's websites, documentation, designs, plugins, and other NPM packages.
This folder holds: rehype-jargon
If you're not entirely sure what to do or how to start, type this command:
```
npm run tips
```
> [!NOTE]
> If you don't want to set up a dev environment, you can run it in your browser:
>
> [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/freesewing/freesewing)
>
> We recommend that you fork our repository and then
> put `gitpod.io/#<entire-url-of-your-fork` into a browser
> to start up a browser-based dev environment of your own.
## About FreeSewing 💀
Where the world of makers and developers collide, that's where you'll find FreeSewing.
If you're a maker, checkout [freesewing.org](https://freesewing.org/) where you can generate
sewing patterns adapted to your measurements.
If you're a developer, the FreeSewing documentation lives at [freesewing.dev](https://freesewing.dev/).
The FreeSewing [core library](https://freesewing.dev/reference/api/) is a *batteries-included* toolbox
for parametric design of sewing patterns. But FreeSewing also provides a range
of [plugins](https://freesewing.dev/reference/plugins/) that further extend the
functionality of the platform.
If you have NodeJS installed, you can try it right now by running:
```bash
npx @freesewing/new-design
```
Getting started guides are available for:
- [Linux](https://freesewing.dev/tutorials/getting-started-linux/)
- [MacOS](https://freesewing.dev/tutorials/getting-started-mac/)
- [Windows](https://freesewing.dev/tutorials/getting-started-windows/)
The [pattern design tutorial](https://freesewing.dev/tutorials/pattern-design/) will
show you how to create your first parametric design.
## Getting started ⚡
To get started with FreeSewing, you can spin up our development environment with:
```bash
npx @freesewing/new-design
```
To work with FreeSewing's monorepo, you'll need [NodeJS v20](https://nodejs.org) on your system.
Once you have that, clone (or fork) this repo and run `npm run kickstart`:
```bash
git clone git@github.com:freesewing/freesewing.git
cd freesewing
npm run kickstart
```
## Links 👩‍💻
**Official channels**
- 💻 Makers website: [FreeSewing.org](https://freesewing.org)
- 💻 Developers website: [FreeSewing.dev](https://freesewing.dev)
- ✅ [Support](https://github.com/freesewing/freesewing/issues/new/choose),
[Issues](https://github.com/freesewing/freesewing/issues) &
[Discussions](https://github.com/freesewing/freesewing/discussions) on
[GitHub](https://github.com/freesewing/freesewing)
**Social media**
- 🐦 Twitter: [@freesewing_org](https://twitter.com/freesewing_org)
- 📷 Instagram: [@freesewing_org](https://instagram.com/freesewing_org)
**Places the FreeSewing community hangs out**
- 💬 [Discord](https://discord.freesewing.org/)
- 💬 [Facebook](https://www.facebook.com/groups/627769821272714/)
- 💬 [Reddit](https://www.reddit.com/r/freesewing/)
## License: MIT 🤓
© [Joost De Cock](https://github.com/joostdecock).
See [the license file](https://github.com/freesewing/freesewing/blob/develop/LICENSE) for details.
## Where to get help 🤯
For [Support](https://github.com/freesewing/freesewing/issues/new/choose),
please use the [Issues](https://github.com/freesewing/freesewing/issues) &
[Discussions](https://github.com/freesewing/freesewing/discussions) on
[GitHub](https://github.com/freesewing/freesewing).

View file

@ -1,4 +0,0 @@
// This file is auto-generated | All changes you make will be overwritten.
export const name = 'rehype-jargon'
export const version = '3.3.0-rc.1'
export const data = { name, version }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

View file

@ -1,126 +0,0 @@
## About
This [Rehype](https://github.com/rehypejs/rehype) plugin allows you to use _jargon_ in your
markdown/mdx/html content and use a centrally managed file of jargon terms and their definitions.
![An example of this plugin being used on freesewing.org](example.png)
## Install
To install this plugin, run:
```
npm install --save rehype-jargon
```
## Getting started
> **Tip**: See https://github.com/joostdecock/rehype-jargon-example for a minimal repository that uses this plugin
### Create your jargon file
This plugin requires a _jargon file_ with terms defenitions. For example:
```js
export const jargon = {
rehype: "<b>rehype</b> is a tool that transforms HTML with plugins. These plugins can inspect and change the HTML. You can use rehype on the server, the client, CLIs, deno, etc.",
freesewing: "<b>FreeSewing</b> is an open source platform for made-to-measure sewing patterns. See <a href='https://freesewing.org/'>freesewing.org</a>"
}
```
### Import the plugin
Now import the plugin, and pass it your jargon:
```js
var remark = require('remark')
var html = require('remark-html')
var plugin = require('remark-jargon')
var jargon = require('./jargon.js')
remark()
.use(html)
.use(plugin, { jargon: jargon })
.process('This is a plugin for _remark_ originally written for _freesewing_.', function (err, file) {
console.log(String(file))
})
```
> **Note**
>
> This plugin will only add markup to your jargon if you _emphasize_ it.
### Style your jargon
You will need to add CSS to style your jargon properly, and hide the definition by default.
Below is an example to get you started:
```css
// Add a dashed line under jargon terms
.jargon-term {
text-decoration: underline dotted #228be6
}
// Add a question mark behind/above jargon terms
.jargon-term::after {
content: "?";
font-weight: bold;
display: inline-block;
transform: translate(0, -0.5em);
font-size: 75%;
color: #228be6;
margin-left: 3px;
}
// Hover behavior for the therm itself
.jargon-term:hover {
position: relative;
text-decoration: none;
cursor: help;
}
// Hide info by default
.jargon-term .jargon-info {
display: none
}
// Show info on hover
.jargon-term:hover .jargon-info {
display: block;
position: absolute;
top: 1.5em;
left: 0;
background: #F8F8F8;
border: 1px solid #DCDCDC;
padding: 1rem;
border-radius: 4px;
font-size: 90%;
min-width: 250px;
max-width: 450px;
z-index: 1;
}
```
## Tips for using jargon
### Lowercase your terms in the jargon file
When looking for terms to match, we lowercase the term your emphazised.
So in the jargon file, you should use `msf`, but in your text, you can use `MSF`, `Msf`, or `msf`.
### If you use HTML, only use inline elements
Your jargon term definition can contain HTML, but only inline elements.
Typically, you will want to stick to:
- Making things **bold**
- Inserting [links](#)
## Getting help
This plugin is written by/for [FreeSewing](https://github.com/freesewing).
For help or feedback, please stop by [the FreeSewing chat room](https://gitter.im/freesewing/development) or
[create an issue](https://github.com/freesewing/freesewing/issues/new).
## Use with Gatsby
Please see [gatsby-remark-jargon](https://github.com/freesewing/freesewing/tree/develop/packages/gatsby-remark-jargon) for
info and instructions on how to use this plugin with [Gatsby](https://www.gatsbyjs.org/).

View file

@ -1,48 +0,0 @@
{
"name": "rehype-jargon",
"version": "3.3.0-rc.1",
"description": "A Rehype plugin for jargon terms",
"author": "Joost De Cock <joost@joost.at> (https://github.com/joostdecock)",
"homepage": "https://freesewing.org/",
"repository": "github:freesewing/freesewing",
"license": "MIT",
"bugs": {
"url": "https://github.com/freesewing/freesewing/issues"
},
"funding": {
"type": "individual",
"url": "https://freesewing.org/patrons/join"
},
"keywords": [
"freesewing",
"freesewing"
],
"type": "module",
"module": "src/index.mjs",
"exports": {
".": "./src/index.mjs"
},
"scripts": {
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -",
"test": "echo \"rehype-jargon: No tests configured. Perhaps you could write some?\" && exit 0",
"tips": "node ../../scripts/help.mjs",
"lint": "npx eslint 'src/*.mjs'"
},
"peerDependencies": {},
"dependencies": {
"unist-util-visit": "5.0.0",
"hast-util-from-html": "2.0.1"
},
"devDependencies": {},
"files": [
"src/**",
"README.md"
],
"publishConfig": {
"access": "public",
"tag": "next"
},
"engines": {
"node": ">= 20"
}
}

View file

@ -1,46 +0,0 @@
import { visit } from 'unist-util-visit'
import { fromHtml } from 'hast-util-from-html'
const jargonTransform = (term, html) =>
`<span class="jargon-term">${term}<span class="jargon-info">${html}</span></span>`
export default (options) => {
// Don't bother if we don't have any jargon
if (!options || !options.jargon) {
throw Error('Required "jargon" option is missing in remark-jargon configuration')
}
// Allow passing in a custom transform method
if (!options.transform) options.transform = jargonTransform
// Detect jargon nodes
const isJargon = (node) => {
if (
node.tagName === 'em' &&
node.children.every((n) => n.type === 'text') &&
Object.keys(options.jargon).indexOf(node.children[0].value.toLowerCase()) !== -1
)
return true
return false
}
// Visitor method
const visitor = (node) => {
if (isJargon(node)) {
const termTree = fromHtml(
options.transform(
node.children[0].value,
options.jargon[node.children[0].value.toLowerCase()]
),
{ fragment: true }
)
node.children = termTree.children
}
}
const transform = (tree) => {
visit(tree, 'element', visitor)
}
return transform
}

View file

@ -26,7 +26,10 @@
"lint": "npx eslint 'src/**' 'tests/*.mjs'"
},
"peerDependencies": {},
"dependencies": {},
"dependencies": {
"lodash": "^4.17.21",
"tlds": "^1.255.0"
},
"devDependencies": {},
"files": [
"src/**",

View file

@ -569,3 +569,41 @@ export function validateTld(email) {
if (tlds.indexOf(tld) === -1) return tld
else return true
}
/**
* Copies a string to the clipboard using the clipboard API
*
* @param {string} text - The text to copy to the clipboard
*/
export function copyToClipboard(text) {
const textToCopy = text
/*
* This is only available in a secure browser context
* So when we are running a localhost dev instance,
* this won't work, and we fall back to the one further down.
*/
if (navigator?.clipboard) {
navigator.clipboard.writeText(text).catch((error) => {
console.error('Failed to use the clipboard API to copy text to clipboard:', error)
copyToClipboardFallback(text)
})
} else {
copyToClipboardFallback(text)
}
}
/**
* Copies a string to the clipboard using DOM manipulation
*
* @param {string} text - The text to copy to the clipboard
*/
function copyToClipboardFallback(text) {
const textarea = document.createElement('textarea')
textarea.value = text
textarea.style.position = 'fixed'
document.body.appendChild(textarea)
textarea.select()
document.execCommand('copy')
document.body.removeChild(textarea)
}

View file

@ -14,20 +14,20 @@
"write-heading-ids": "docusaurus write-heading-ids"
},
"dependencies": {
"@docusaurus/core": "3.5.2",
"@docusaurus/preset-classic": "3.5.2",
"@docusaurus/core": "3.7.0",
"@docusaurus/preset-classic": "3.7.0",
"@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0",
"prism-react-renderer": "^2.3.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-markdown": "^9.0.1",
"tailwindcss": "^3.4.13"
},
"devDependencies": {
"@babel/preset-react": "^7.26.3",
"@docusaurus/module-type-aliases": "3.5.2",
"@docusaurus/types": "3.5.2"
"@docusaurus/module-type-aliases": "3.7.0",
"@docusaurus/types": "3.7.0"
},
"browserslist": {
"production": [

View file

@ -0,0 +1,5 @@
---
title: FreeSewing Pattern Editor
---
FIXME: Document v4 editor here

View file

@ -24,10 +24,12 @@
"@mdx-js/react": "^3.0.0",
"autoprefixer": "^10.4.20",
"clsx": "^2.0.0",
"daisyui": "^4.12.23",
"lodash": "^4.17.21",
"postcss": "^8.4.47",
"prism-react-renderer": "^2.3.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-markdown": "^9.0.1",
"tailwindcss": "^3.4.14"
},

View file

@ -1,4 +1,4 @@
import orderBy from 'lodash.orderby'
import orderBy from 'lodash/orderBy.js'
import set from 'lodash.set'
import { mergeOptions } from '@freesewing/core'

View file

@ -1,5 +0,0 @@
# The FreeSewing stand-alone development environment
This is the environment that we ship in the @freesewing/new-design package.
You can use it inside the monorepo, but that's not its intended purpose.

View file

@ -1,3 +0,0 @@
// __SDEFILE__ - This file is a dependency for the stand-alone environment
// SDE does not support this
export const examples = false

View file

@ -1,13 +0,0 @@
import { Popout } from 'shared/components/popout/index.mjs'
import { WebLink } from 'shared/components/link.mjs'
// This is how we skip the docs in the sde
export const DynamicOrgDocs = () => (
<Popout note>
<h5>The FreeSewing stand-alone development environment does not include documentation</h5>
<p>
Go to <WebLink href="https://freesewing.org/" txt="FreeSewing.org" /> if you want all features
enabled.
</p>
</Popout>
)

View file

@ -1,6 +0,0 @@
/*
* Placeholder feeds component that does nothing
* but allows us to re-use code that expects this
* to be here
*/
export const Feeds = () => null

View file

@ -1,36 +0,0 @@
// Dependencies
import { useTranslation } from 'next-i18next'
import { collection } from 'site/hooks/use-design.mjs'
// Components
import { ModalWrapper } from 'shared/components/wrappers/modal.mjs'
import { Link } from 'shared/components/link.mjs'
export const ns = ['sde']
export const ModalDesignPicker = () => {
const { t } = useTranslation(ns)
return (
<ModalWrapper flex="col" justify="top lg:justify-center" slideFrom="left">
<div className="max-w-xl">
<h2>{t('sde:chooseATemplate')}</h2>
<div className="flex flex-row p-4 w-full flex-wrap gap-2">
{collection.map((d) => (
<Link
href={`/design/${d}`}
key={d}
className={`btn w-64 btn-secondary flex flex-col flex-nowrap items-start
gap-2 py-2 h-auto border border-secondary justify-start text-left bg-opacity-30
hover:bg-opacity-20 hover:bg-secondary btn-ghost
border border-secondary hover:border hover:border-secondary
`}
>
<div className="text-lg font-bold">{t(`sde:${d}.t`)}</div>
<div className={`normal-case text-base-content`}>{t(`sde:${d}.d`)}</div>
</Link>
))}
</div>
</div>
</ModalWrapper>
)
}

View file

@ -1,102 +0,0 @@
import { nsMerge } from 'shared/utils.mjs'
// Hooks
import { useContext } from 'react'
import { useTranslation } from 'next-i18next'
import { useTheme } from 'shared/hooks/use-theme.mjs'
// Context
import { ModalContext } from 'shared/context/modal-context.mjs'
// Components
import {
DocsIcon,
LockIcon,
ThemeIcon,
I18nIcon,
GitHubIcon,
HelpIcon,
HomeIcon,
RocketIcon,
} from 'shared/components/icons.mjs'
import { HeaderWrapper } from 'shared/components/wrappers/header.mjs'
import { ModalThemePicker, ns as themeNs } from 'shared/components/modal/theme-picker.mjs'
import { ModalLocalePicker, ns as localeNs } from 'shared/components/modal/locale-picker.mjs'
import { ModalDesignPicker } from './design-picker.mjs'
import { NavButton, NavSpacer } from 'shared/components/header.mjs'
export const ns = nsMerge('sde', 'header', 'sections', 'susi', themeNs, localeNs)
const NavIcons = ({ setModal }) => {
const { t } = useTranslation(['header'])
const { spectrum } = useTheme()
const iconSize = 'h-6 w-6 lg:h-12 lg:w-12'
return (
<>
<NavButton href="/" label={t('header:home')} color={spectrum[1]}>
<HomeIcon className={iconSize} />
</NavButton>
<NavSpacer />
<NavButton
onClick={() => setModal(<ModalDesignPicker />)}
label={t('sde:design')}
color={spectrum[2]}
>
<RocketIcon className={iconSize} />
</NavButton>
<NavButton href="https://freesewing.dev/" label={t('sde:docs')} color={spectrum[3]}>
<DocsIcon className={iconSize} />
</NavButton>
<NavButton
href="http://github.com/freesewing/freesewing"
label={t('sde:code')}
color={spectrum[4]}
>
<GitHubIcon className={iconSize} />
</NavButton>
<NavButton href="https://freesewing.org/support" label={t('sde:support')} color={spectrum[5]}>
<HelpIcon className={iconSize} />
</NavButton>
<NavSpacer />
<NavButton
onClick={() => setModal(<ModalThemePicker />)}
label={t('header:theme')}
color={spectrum[6]}
>
<ThemeIcon className={iconSize} />
</NavButton>
<NavButton
onClick={() => setModal(<ModalLocalePicker />)}
label={t('header:language')}
color={spectrum[7]}
>
<I18nIcon className={iconSize} />
</NavButton>
<NavSpacer />
<NavButton href="/signin" label={t('susi:signIn')} color={spectrum[8]}>
<LockIcon className={iconSize} />
</NavButton>
</>
)
}
export const Header = ({ setSearch, show }) => {
const { setModal } = useContext(ModalContext)
return (
<HeaderWrapper {...{ setSearch, show }}>
<div className="m-auto md:px-8">
<div className="p-0 flex flex-row gap-2 justify-between text-neutral-content items-center">
{/* Non-mobile content */}
<div className="hidden lg:flex lg:flex-row lg:justify-between items-center xl:justify-center w-full">
<NavIcons setModal={setModal} setSearch={setSearch} />
</div>
{/* Mobile content */}
<div className="flex lg:hidden flex-row items-center justify-between w-full">
<NavIcons setModal={setModal} setSearch={setSearch} />
</div>
</div>
</div>
</HeaderWrapper>
)
}

View file

@ -1,3 +0,0 @@
export const ns = ['']
export const BareLayout = ({ children }) => children

View file

@ -1,5 +0,0 @@
export const ns = ['']
export const DefaultLayout = ({ children }) => (
<div className="max-w-2xl m-auto px-2 py-8">{children}</div>
)

View file

@ -1,7 +0,0 @@
export const ns = []
export const WorkbenchLayout = (props) => (
<section id="fs-workbench" className="m-0 p-0">
{props.children}
</section>
)

View file

@ -1,28 +0,0 @@
// Components
import { SectionsMenu, ns as sectionsNs } from 'shared/components/navigation/sections-menu.mjs'
import { ModalWrapper } from 'shared/components/wrappers/modal.mjs'
import { ChoiceLink } from 'shared/components/choice-link.mjs'
export const ns = sectionsNs
export const ModalMenu = () => (
<ModalWrapper flex="col" justify="top" slideFrom="left">
<div className="max-w-full">
<div
className={`
py-4 w-full m-auto
flex flex-col-reverse gap-0 flex-wrap justify-between
lg:max-w-6xl lg:flex-nowrap lg:gap-8 lg:flex-row
`}
>
<div className="w-full">
<SectionsMenu />
<ChoiceLink href="/sitemap" title="Sitemap">
The sitemap lists all pages on this website. It can give you a good idea of what you can
find here.
</ChoiceLink>
</div>
</div>
</div>
</ModalWrapper>
)

View file

@ -1,2 +0,0 @@
export const ns = []
export const Search = () => null

View file

@ -1,45 +0,0 @@
// Hooks
import { useEffect } from 'react'
import { useSwipeable } from 'react-swipeable'
import { useRouter } from 'next/router'
// Components
import { LayoutWrapper } from 'site/components/wrappers/layout.mjs'
/* This component should wrap all page content */
export const PageWrapper = ({
title = 'FIXME: No title set',
app = false,
layout = false,
children = [],
}) => {
const swipeHandlers = useSwipeable({
onSwipedLeft: () => (app.primaryMenu ? app.setPrimaryMenu(false) : null),
onSwipedRight: () => (app.primaryMenu ? null : app.setPrimaryMenu(true)),
trackMouse: true,
})
const router = useRouter()
const slug = router.asPath.slice(1)
useEffect(() => app.setSlug(slug), [slug])
const childProps = {
app: app,
title: title,
}
const Layout = layout
return (
<div
ref={swipeHandlers.ref}
onMouseDown={swipeHandlers.onMouseDown}
data-theme={app.theme}
key={app.theme} // Thiis forces the data-theme update
>
<LayoutWrapper {...childProps}>
{Layout ? <Layout {...childProps}>{children}</Layout> : children}
</LayoutWrapper>
</div>
)
}

View file

@ -1,7 +0,0 @@
{
"t": "From Bella",
"d": "This design extends Bella",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "From Bella",
"d": "This design extends Bella",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "From Bella",
"d": "This design extends Bella",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "From Bella",
"d": "This design extends Bella",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "From Bella",
"d": "This design extends Bella",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,8 +0,0 @@
import en from './en.json' assert { type: 'json' }
import de from './de.json' assert { type: 'json' }
import es from './es.json' assert { type: 'json' }
import fr from './fr.json' assert { type: 'json' }
import nl from './nl.json' assert { type: 'json' }
import uk from './uk.json' assert { type: 'json' }
export const i18n = { en, de, es, fr, nl, uk }

View file

@ -1,7 +0,0 @@
{
"t": "From Bella",
"d": "This design extends Bella",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "From Bella",
"d": "This design extends Bella",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,14 +0,0 @@
import { back as bellaBack } from '@freesewing/bella'
function draftBack({ part }) {
// Do your magic here
return part
}
export const back = {
name: 'frombella.back',
from: bellaBack,
draft: draftBack,
hide: { from: true },
}

View file

@ -1,16 +0,0 @@
import { frontSideDart as bellaFront } from '@freesewing/bella'
function draftFront({ part }) {
/*
* Do your magic here
*/
return part
}
export const front = {
name: 'frombella.front',
from: bellaFront,
draft: draftFront,
hide: { from: true },
}

View file

@ -1,23 +0,0 @@
import { Design, mergeI18n } from '@freesewing/core'
import { i18n as ourI18n } from '../i18n/index.mjs'
import { i18n as bellaI18n } from '@freesewing/bella'
import { back } from './back.mjs'
import { front } from './front.mjs'
/*
* Create the design
*/
const FromBella = new Design({
data: {
name: 'fromBella',
version: '0.0.1',
},
parts: [back, front],
})
/*
* Merge translations
*/
const i18n = mergeI18n([bellaI18n, ourI18n])
export { back, front, FromBella, i18n }

View file

@ -1,7 +0,0 @@
{
"t": "From Bent",
"d": "This design extends Bent",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "From Bent",
"d": "This design extends Bent",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "From Bent",
"d": "This design extends Bent",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "From Bent",
"d": "This design extends Bent",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,8 +0,0 @@
import en from './en.json' assert { type: 'json' }
import de from './de.json' assert { type: 'json' }
import es from './es.json' assert { type: 'json' }
import fr from './fr.json' assert { type: 'json' }
import nl from './nl.json' assert { type: 'json' }
import uk from './uk.json' assert { type: 'json' }
export const i18n = { en, de, es, fr, nl, uk }

View file

@ -1,7 +0,0 @@
{
"t": "From Bent",
"d": "This design extends Bent",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "From Bent",
"d": "This design extends Bent",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,14 +0,0 @@
import { back as bentBack } from '@freesewing/bent'
function draftBack({ part }) {
// Do your magic here
return part
}
export const back = {
name: 'frombent.back',
from: bentBack,
draft: draftBack,
hide: { from: true },
}

View file

@ -1,16 +0,0 @@
import { front as bentFront } from '@freesewing/bent'
function draftFront({ part }) {
/*
* Do your magic here
*/
return part
}
export const front = {
name: 'frombent.front',
from: bentFront,
draft: draftFront,
hide: { from: true },
}

View file

@ -1,25 +0,0 @@
import { Design, mergeI18n } from '@freesewing/core'
import { i18n as ourI18n } from '../i18n/index.mjs'
import { i18n as bentI18n } from '@freesewing/bent'
import { back } from './back.mjs'
import { front } from './front.mjs'
import { topSleeve } from './top-sleeve.mjs'
import { underSleeve } from './under-sleeve.mjs'
/*
* Create the design
*/
const FromBent = new Design({
data: {
name: 'fromBent',
version: '0.0.1',
},
parts: [back, front, topSleeve, underSleeve],
})
/*
* Merge translations
*/
const i18n = mergeI18n([bentI18n, ourI18n])
export { back, front, topSleeve, underSleeve, FromBent, i18n }

View file

@ -1,16 +0,0 @@
import { topSleeve as bentTopSleeve } from '@freesewing/bent'
function draftTopSleeve({ part }) {
/*
* Do your magic here
*/
return part
}
export const topSleeve = {
name: 'frombent.topSleeve',
from: bentTopSleeve,
draft: draftTopSleeve,
hide: { from: true },
}

View file

@ -1,16 +0,0 @@
import { underSleeve as bentUnderSleeve } from '@freesewing/bent'
function draftUnderSleeve({ part }) {
/*
* Do your magic here
*/
return part
}
export const underSleeve = {
name: 'frombent.underSleeve',
from: bentUnderSleeve,
draft: draftUnderSleeve,
hide: { from: true },
}

View file

@ -1,7 +0,0 @@
{
"t": "From Breanna",
"d": "This design extends Breanna",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "From Breanna",
"d": "This design extends Breanna",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "From Breanna",
"d": "This design extends Breanna",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "From Breanna",
"d": "This design extends Breanna",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,8 +0,0 @@
import en from './en.json' assert { type: 'json' }
import de from './de.json' assert { type: 'json' }
import es from './es.json' assert { type: 'json' }
import fr from './fr.json' assert { type: 'json' }
import nl from './nl.json' assert { type: 'json' }
import uk from './uk.json' assert { type: 'json' }
export const i18n = { en, de, es, fr, nl, uk }

View file

@ -1,7 +0,0 @@
{
"t": "From Breanna",
"d": "This design extends Breanna",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "From Breanna",
"d": "This design extends Breanna",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,14 +0,0 @@
import { back as breannaBack } from '@freesewing/breanna'
function draftBack({ part }) {
// Do your magic here
return part
}
export const back = {
name: 'frombreanna.back',
from: breannaBack,
draft: draftBack,
hide: { from: true },
}

View file

@ -1,16 +0,0 @@
import { front as breannaFront } from '@freesewing/breanna'
function draftFront({ part }) {
/*
* Do your magic here
*/
return part
}
export const front = {
name: 'frombreanna.front',
from: breannaFront,
draft: draftFront,
hide: { from: true },
}

View file

@ -1,24 +0,0 @@
import { Design, mergeI18n } from '@freesewing/core'
import { i18n as ourI18n } from '../i18n/index.mjs'
import { i18n as breannaI18n } from '@freesewing/breanna'
import { back } from './back.mjs'
import { front } from './front.mjs'
import { sleeve } from './sleeve.mjs'
/*
* Create the design
*/
const FromBreanna = new Design({
data: {
name: 'fromBreanna',
version: '0.0.1',
},
parts: [back, front, sleeve],
})
/*
* Merge translations
*/
const i18n = mergeI18n([breannaI18n, ourI18n])
export { back, front, sleeve, FromBreanna, i18n }

View file

@ -1,16 +0,0 @@
import { sleeve as breannaSleeve } from '@freesewing/breanna'
function draftSleeve({ part }) {
/*
* Do your magic here
*/
return part
}
export const sleeve = {
name: 'frombreanna.sleeve',
from: breannaSleeve,
draft: draftSleeve,
hide: { from: true },
}

View file

@ -1,7 +0,0 @@
{
"t": "From Brian",
"d": "This design extends Brian",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "From Brian",
"d": "This design extends Brian",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "From Brian",
"d": "This design extends Brian",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "From Brian",
"d": "This design extends Brian",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,8 +0,0 @@
import en from './en.json' assert { type: 'json' }
import de from './de.json' assert { type: 'json' }
import es from './es.json' assert { type: 'json' }
import fr from './fr.json' assert { type: 'json' }
import nl from './nl.json' assert { type: 'json' }
import uk from './uk.json' assert { type: 'json' }
export const i18n = { en, de, es, fr, nl, uk }

View file

@ -1,7 +0,0 @@
{
"t": "From Brian",
"d": "This design extends Brian",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "From Brian",
"d": "This design extends Brian",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,14 +0,0 @@
import { back as brianBack } from '@freesewing/brian'
function draftBack({ part }) {
// Do your magic here
return part
}
export const back = {
name: 'frombrian.back',
from: brianBack,
draft: draftBack,
hide: { from: true },
}

View file

@ -1,16 +0,0 @@
import { front as brianFront } from '@freesewing/brian'
function draftFront({ part }) {
/*
* Do your magic here
*/
return part
}
export const front = {
name: 'frombrian.front',
from: brianFront,
draft: draftFront,
hide: { from: true },
}

View file

@ -1,24 +0,0 @@
import { Design, mergeI18n } from '@freesewing/core'
import { i18n as ourI18n } from '../i18n/index.mjs'
import { i18n as brianI18n } from '@freesewing/brian'
import { back } from './back.mjs'
import { front } from './front.mjs'
import { sleeve } from './sleeve.mjs'
/*
* Create the design
*/
const FromBrian = new Design({
data: {
name: 'fromBrian',
version: '0.0.1',
},
parts: [back, front, sleeve],
})
/*
* Merge translations
*/
const i18n = mergeI18n([brianI18n, ourI18n])
export { back, front, sleeve, FromBrian, i18n }

View file

@ -1,14 +0,0 @@
import { sleeve as brianSleeve } from '@freesewing/brian'
function draftSleeve({ part }) {
// Do your magic here
return part
}
export const sleeve = {
name: 'frombrian.sleeve',
from: brianSleeve,
draft: draftSleeve,
hide: { from: true },
}

View file

@ -1,7 +0,0 @@
{
"t": "Your Design",
"d": "This is your own design, from scratch",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,9 +0,0 @@
{
"t": "Your Design",
"d": "This is your own design, from scratch",
"p": {},
"s": {
"whatWillYouCreateToday": "What will you create today?"
},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "Your Design",
"d": "This is your own design, from scratch",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "Your Design",
"d": "This is your own design, from scratch",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,8 +0,0 @@
import en from './en.json' assert { type: 'json' }
import de from './de.json' assert { type: 'json' }
import es from './es.json' assert { type: 'json' }
import fr from './fr.json' assert { type: 'json' }
import nl from './nl.json' assert { type: 'json' }
import uk from './uk.json' assert { type: 'json' }
export const i18n = { en, de, es, fr, nl, uk }

View file

@ -1,7 +0,0 @@
{
"t": "Your Design",
"d": "This is your own design, from scratch",
"p": {},
"s": {},
"o": {}
}

View file

@ -1,7 +0,0 @@
{
"t": "Your Design",
"d": "This is your own design, from scratch",
"p": {},
"s": {},
"o": {}
}

Some files were not shown because too many files have changed in this diff Show more