feat(org): Switched to better dynamic mdx
This commit is contained in:
parent
166c8bc03b
commit
90afd3e28e
36 changed files with 267 additions and 267 deletions
12
markdown/org/docs/site/patterns/goto/en.md
Normal file
12
markdown/org/docs/site/patterns/goto/en.md
Normal file
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
title: What to do after saving a new pattern?
|
||||
---
|
||||
|
||||
When you create a new pattern in FreeSewing's pattern editor, you have the option to save the pattern to your account.
|
||||
|
||||
After you save the pattern to your account, there are several options for what you might want to do next:
|
||||
|
||||
- Continue editing the saved patter
|
||||
- Display the pattern information page
|
||||
|
||||
Because we cannot read your mind, you can choose what you would like to happen when you save a new pattern to your account.
|
8
markdown/org/docs/site/patterns/img/en.md
Normal file
8
markdown/org/docs/site/patterns/img/en.md
Normal file
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
title: "Patterns: Image"
|
||||
---
|
||||
|
||||
If you'd like you can add an **image** to your pattern, for example of the finished make.
|
||||
|
||||
This can help you remember exactly what this pattern was, which can be useful as you can end up having many patterns saved to your account.
|
||||
|
8
markdown/org/docs/site/patterns/public/en.md
Normal file
8
markdown/org/docs/site/patterns/public/en.md
Normal file
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
title: "Patterns: Public"
|
||||
---
|
||||
|
||||
This settings controls whether your pattern will accessible by the **public** or not.
|
||||
|
||||
By default, patterns are private and only you can access your own patterns.
|
||||
If you'd like to share your pattern with others -- perhaps because they showed an interest or you are loooking for input -- you should first make it public.
|
|
@ -1,14 +0,0 @@
|
|||
//import { DynamicOrgDocs as Component } from 'shared/components/dynamic-docs/org.mjs'
|
||||
|
||||
export const DynamicOrgDocs = () => <p>No longer supported</p>
|
||||
|
||||
// (
|
||||
// <Popout note>
|
||||
// <h5>The FreeSewing lab does not include documentation</h5>
|
||||
// <p>
|
||||
// Go to <WebLink href="https://freesewing.org/" txt="FreeSewing.org" /> if you want all features
|
||||
// enabled.
|
||||
// </p>
|
||||
// </Popout>
|
||||
//)
|
||||
//export const DynamicOrgDocs = Component
|
|
@ -8,8 +8,9 @@ import { loadMdxAsStaticProps } from 'shared/mdx/load.mjs'
|
|||
import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs'
|
||||
import { MdxWrapper } from 'shared/components/wrappers/mdx.mjs'
|
||||
import { DocsLayout, ns as layoutNs } from 'site/components/layouts/docs.mjs'
|
||||
import { ns as designNs } from 'shared/components/designs/info.mjs'
|
||||
|
||||
export const ns = nsMerge(pageNs, layoutNs, 'designs', 'account', 'tags')
|
||||
export const ns = nsMerge(pageNs, layoutNs, designNs)
|
||||
|
||||
/**
|
||||
* A page to display documentation markdown
|
||||
|
|
|
@ -1,21 +1,25 @@
|
|||
// Dependencies
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
// Hooks
|
||||
import { useCallback } from 'react'
|
||||
import { useDynamicMdx } from 'shared/hooks/use-dynamic-mdx.mjs'
|
||||
import { loadMdxAsStaticProps } from 'shared/mdx/load.mjs'
|
||||
import { nsMerge } from 'shared/utils.mjs'
|
||||
// Components
|
||||
import { Page, ns } from './[...slug].mjs'
|
||||
import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs'
|
||||
import { MdxWrapper } from 'shared/components/wrappers/mdx.mjs'
|
||||
import { DocsLayout, ns as layoutNs } from 'site/components/layouts/docs.mjs'
|
||||
|
||||
const DocsHomePage = ({ page, slug, locale }) => {
|
||||
const loader = useCallback(
|
||||
() =>
|
||||
import(/* webpackInclude: /docs\/\w+\.md/ */ `../../../../markdown/org/docs/${locale}.md`),
|
||||
[locale]
|
||||
)
|
||||
const { frontmatter, MDX } = useDynamicMdx(loader)
|
||||
export const ns = nsMerge('docs', pageNs, layoutNs)
|
||||
|
||||
return <Page {...{ page, slug, frontmatter, MDX, locale }} />
|
||||
}
|
||||
const DocsHomePage = ({ page, locale, frontmatter, mdx, mdxSlug }) => (
|
||||
<PageWrapper
|
||||
{...page}
|
||||
locale={locale}
|
||||
title={frontmatter.title}
|
||||
intro={frontmatter.intro || frontmatter.lead}
|
||||
layout={(props) => <DocsLayout {...props} {...{ slug: page.path.join('/'), frontmatter }} />}
|
||||
>
|
||||
<MdxWrapper mdx={mdx} site="org" slug={mdxSlug} />
|
||||
</PageWrapper>
|
||||
)
|
||||
|
||||
export default DocsHomePage
|
||||
|
||||
|
@ -26,7 +30,12 @@ export default DocsHomePage
|
|||
export async function getStaticProps({ locale }) {
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations('en', ['docs', ...ns])),
|
||||
...(await serverSideTranslations(locale, ns)),
|
||||
...(await loadMdxAsStaticProps({
|
||||
language: locale,
|
||||
site: 'org',
|
||||
slug: 'docs',
|
||||
})),
|
||||
slug: 'docs',
|
||||
locale,
|
||||
page: {
|
||||
|
|
|
@ -16,7 +16,7 @@ import { Popout } from 'shared/components/popout/index.mjs'
|
|||
import { LeftIcon, PlusIcon, CopyIcon, RightIcon, TrashIcon } from 'shared/components/icons.mjs'
|
||||
import { PageLink, Link } from 'shared/components/link.mjs'
|
||||
import { StringInput, ListInput, FormControl } from 'shared/components/inputs.mjs'
|
||||
import { DynamicOrgDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
||||
|
||||
export const ns = ['account', 'status']
|
||||
|
||||
|
@ -149,10 +149,9 @@ const NewKey = ({ account, setGenerate, backend }) => {
|
|||
const [apikey, setApikey] = useState(false)
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
// FIXME: implement a solution for loading docs dynamically the is simple and work as expected
|
||||
const docs = {}
|
||||
for (const option of ['name', 'expiry', 'level']) {
|
||||
docs[option] = <DynamicOrgDocs language={i18n.language} path={`site/apikeys/${option}`} />
|
||||
docs[option] = <DynamicMdx language={i18n.language} slug={`docs/site/apikeys/${option}`} />
|
||||
}
|
||||
|
||||
const levels = account.role === 'admin' ? [0, 1, 2, 3, 4, 5, 6, 7, 8] : [0, 1, 2, 3, 4]
|
||||
|
|
|
@ -11,7 +11,7 @@ import { Icons, welcomeSteps, BackToAccountButton } from './shared.mjs'
|
|||
import { SaveSettingsButton } from 'shared/components/buttons/save-settings-button.mjs'
|
||||
import { ContinueButton } from 'shared/components/buttons/continue-button.mjs'
|
||||
import { MarkdownInput } from 'shared/components/inputs.mjs'
|
||||
import { DynamicOrgDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
||||
import { TipIcon } from 'shared/components/icons.mjs'
|
||||
|
||||
export const ns = ['account', 'status']
|
||||
|
@ -60,7 +60,7 @@ export const BioSettings = ({ welcome = false }) => {
|
|||
update={setBio}
|
||||
current={bio}
|
||||
placeholder={t('bioTitle')}
|
||||
docs={<DynamicOrgDocs language={i18n.language} path={`site/account/bio`} />}
|
||||
docs={<DynamicMdx language={i18n.language} slug={`docs/site/account/bio`} />}
|
||||
labelBL={
|
||||
<span className="flex flex-row items-center gap-1">
|
||||
<TipIcon className="w-6 h-6 text-success" />
|
||||
|
|
|
@ -11,7 +11,7 @@ import { PlusIcon, TrashIcon, LeftIcon } from 'shared/components/icons.mjs'
|
|||
import { PageLink, WebLink, Link } from 'shared/components/link.mjs'
|
||||
import { DisplayRow } from './shared.mjs'
|
||||
import { StringInput } from 'shared/components/inputs.mjs'
|
||||
import { DynamicOrgDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
||||
|
||||
export const ns = ['account', 'status']
|
||||
|
||||
|
@ -47,10 +47,9 @@ export const NewBookmark = () => {
|
|||
const router = useRouter()
|
||||
const backend = useBackend()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
// FIXME: implement a solution for loading docs dynamically the is simple and work as expected
|
||||
const docs = {}
|
||||
for (const option of ['title', 'location', 'type']) {
|
||||
docs[option] = <DynamicOrgDocs language={i18n.language} path={`site/bookmarks/${option}`} />
|
||||
docs[option] = <DynamicMdx language={i18n.language} slug={`docs/site/bookmarks/${option}`} />
|
||||
}
|
||||
|
||||
// State
|
||||
|
|
|
@ -11,7 +11,7 @@ import { Icons, welcomeSteps, BackToAccountButton } from './shared.mjs'
|
|||
import { ContinueButton } from 'shared/components/buttons/continue-button.mjs'
|
||||
import { ListInput } from 'shared/components/inputs.mjs'
|
||||
import { OkIcon, NoIcon } from 'shared/components/icons.mjs'
|
||||
import { DynamicOrgDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
||||
|
||||
export const ns = ['account', 'status']
|
||||
|
||||
|
@ -67,7 +67,7 @@ export const CompareSettings = ({ welcome = false }) => {
|
|||
}))}
|
||||
current={selection}
|
||||
update={update}
|
||||
docs={<DynamicOrgDocs language={i18n.language} path={`site/account/compare`} />}
|
||||
docs={<DynamicMdx language={i18n.language} slug={`docs/site/account/compare`} />}
|
||||
/>
|
||||
{welcome ? (
|
||||
<>
|
||||
|
|
|
@ -11,8 +11,8 @@ import { useBackend } from 'shared/hooks/use-backend.mjs'
|
|||
import { BackToAccountButton, Icons, welcomeSteps } from './shared.mjs'
|
||||
import { ContinueButton } from 'shared/components/buttons/continue-button.mjs'
|
||||
import { ListInput } from 'shared/components/inputs.mjs'
|
||||
import { DynamicOrgDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import { ControlScore } from 'shared/components/control/score.mjs'
|
||||
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
||||
|
||||
export const ns = ['account', 'status']
|
||||
|
||||
|
@ -78,7 +78,7 @@ export const ControlSettings = ({ welcome = false, noBack = false }) => {
|
|||
}))}
|
||||
current={selection}
|
||||
update={update}
|
||||
docs={<DynamicOrgDocs language={i18n.language} path={`site/account/control`} />}
|
||||
docs={<DynamicMdx language={i18n.language} slug="docs/site/account/control" />}
|
||||
/>
|
||||
{welcome ? (
|
||||
<>
|
||||
|
|
|
@ -12,7 +12,7 @@ import { validateEmail, validateTld } from 'shared/utils.mjs'
|
|||
import { BackToAccountButton } from './shared.mjs'
|
||||
import { Popout } from 'shared/components/popout/index.mjs'
|
||||
import { EmailInput } from 'shared/components/inputs.mjs'
|
||||
import { DynamicOrgDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
||||
|
||||
export const ns = ['account', 'status']
|
||||
|
||||
|
@ -59,7 +59,7 @@ export const EmailSettings = () => {
|
|||
current={email}
|
||||
original={account.email}
|
||||
valid={() => valid}
|
||||
docs={<DynamicOrgDocs language={i18n.language} path={`site/account/email`} />}
|
||||
docs={<DynamicMdx language={i18n.language} slug={`docs/site/account/email`} />}
|
||||
/>
|
||||
<button
|
||||
className="btn mt-4 btn-primary w-full"
|
||||
|
|
|
@ -9,7 +9,7 @@ import { useBackend } from 'shared/hooks/use-backend.mjs'
|
|||
import { BackToAccountButton } from './shared.mjs'
|
||||
import { SaveSettingsButton } from 'shared/components/buttons/save-settings-button.mjs'
|
||||
import { StringInput } from 'shared/components/inputs.mjs'
|
||||
import { DynamicOrgDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
||||
|
||||
export const ns = ['account', 'status']
|
||||
|
||||
|
@ -44,7 +44,7 @@ export const GithubSettings = () => {
|
|||
update={setGithubEmail}
|
||||
valid={(val) => val.length > 0}
|
||||
placeholder={'joostdecock'}
|
||||
docs={<DynamicOrgDocs language={i18n.language} path={`site/account/github`} />}
|
||||
docs={<DynamicMdx language={i18n.language} slug={`docs/site/account/github`} />}
|
||||
/>
|
||||
<StringInput
|
||||
id="account-github-username"
|
||||
|
@ -53,7 +53,7 @@ export const GithubSettings = () => {
|
|||
update={setGithubUsername}
|
||||
valid={(val) => val.length > 0}
|
||||
placeholder={'joost@joost.at'}
|
||||
docs={<DynamicOrgDocs language={i18n.language} path={`site/account/github`} />}
|
||||
docs={<DynamicOrgDocs language={i18n.language} path={`docs/site/account/github`} />}
|
||||
/>
|
||||
<SaveSettingsButton btnProps={{ onClick: save }} />
|
||||
<BackToAccountButton />
|
||||
|
|
|
@ -12,7 +12,7 @@ import { Icons, welcomeSteps, BackToAccountButton } from './shared.mjs'
|
|||
import { ContinueButton } from 'shared/components/buttons/continue-button.mjs'
|
||||
import { SaveSettingsButton } from 'shared/components/buttons/save-settings-button.mjs'
|
||||
import { PassiveImageInput } from 'shared/components/inputs.mjs'
|
||||
import { DynamicOrgDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
||||
|
||||
export const ns = ['account', 'status']
|
||||
|
||||
|
@ -51,7 +51,7 @@ export const ImgSettings = ({ welcome = false }) => {
|
|||
update={setImg}
|
||||
current={img}
|
||||
valid={(val) => val.length > 0}
|
||||
docs={<DynamicOrgDocs language={i18n.language} path={`site/account/img`} />}
|
||||
docs={<DynamicMdx language={i18n.language} slug={`docs/site/account/img`} />}
|
||||
/>
|
||||
{welcome ? (
|
||||
<>
|
||||
|
|
|
@ -9,7 +9,7 @@ import { useBackend } from 'shared/hooks/use-backend.mjs'
|
|||
import { Icons, welcomeSteps, BackToAccountButton, NumberBullet } from './shared.mjs'
|
||||
import { ContinueButton } from 'shared/components/buttons/continue-button.mjs'
|
||||
import { ListInput } from 'shared/components/inputs.mjs'
|
||||
import { DynamicOrgDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
||||
|
||||
export const ns = ['account', 'status']
|
||||
|
||||
|
@ -59,7 +59,7 @@ export const ImperialSettings = ({ welcome = false }) => {
|
|||
}))}
|
||||
current={selection}
|
||||
update={update}
|
||||
docs={<DynamicOrgDocs language={i18n.language} path={`site/account/units`} />}
|
||||
docs={<DynamicMdx language={i18n.language} slug={`docs/site/account/units`} />}
|
||||
/>
|
||||
{welcome ? (
|
||||
<>
|
||||
|
|
|
@ -8,7 +8,7 @@ import { useBackend } from 'shared/hooks/use-backend.mjs'
|
|||
// Components
|
||||
import { BackToAccountButton, NumberBullet } from './shared.mjs'
|
||||
import { ListInput } from 'shared/components/inputs.mjs'
|
||||
import { DynamicOrgDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
||||
// Config
|
||||
import { siteConfig as conf } from 'site/site.config.mjs'
|
||||
|
||||
|
@ -58,7 +58,7 @@ export const LanguageSettings = () => {
|
|||
}))}
|
||||
current={language}
|
||||
update={update}
|
||||
docs={<DynamicOrgDocs language={i18n.language} path={`site/account/language`} />}
|
||||
docs={<DynamicMdx language={i18n.language} slug={`docs/site/account/language`} />}
|
||||
/>
|
||||
<BackToAccountButton />
|
||||
</div>
|
||||
|
|
|
@ -9,7 +9,7 @@ import { useBackend } from 'shared/hooks/use-backend.mjs'
|
|||
import { BackToAccountButton, Icons, welcomeSteps } from './shared.mjs'
|
||||
import { ContinueButton } from 'shared/components/buttons/continue-button.mjs'
|
||||
import { ListInput } from 'shared/components/inputs.mjs'
|
||||
import { DynamicOrgDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
||||
import { OkIcon, NoIcon } from 'shared/components/icons.mjs'
|
||||
|
||||
export const ns = ['account', 'status']
|
||||
|
@ -63,7 +63,7 @@ export const NewsletterSettings = ({ welcome = false, bare = false }) => {
|
|||
}))}
|
||||
current={selection}
|
||||
update={update}
|
||||
docs={<DynamicOrgDocs language={i18n.language} path={`site/account/newsletter`} />}
|
||||
docs={<DynamicMdx language={i18n.language} slug={`account/site/account/newsletter`} />}
|
||||
/>
|
||||
{welcome ? (
|
||||
<>
|
||||
|
|
|
@ -13,7 +13,7 @@ import { SaveSettingsButton } from 'shared/components/buttons/save-settings-butt
|
|||
import { Popout } from 'shared/components/popout/index.mjs'
|
||||
import { RightIcon } from 'shared/components/icons.mjs'
|
||||
import { PasswordInput } from 'shared/components/inputs.mjs'
|
||||
import { DynamicOrgDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
||||
|
||||
export const ns = ['account', 'status']
|
||||
|
||||
|
@ -46,7 +46,7 @@ export const PasswordSettings = ({ welcome = false }) => {
|
|||
update={setPassword}
|
||||
valid={(val) => val.length > 0}
|
||||
placeholder={t('passwordTitle')}
|
||||
docs={<DynamicOrgDocs language={i18n.language} path={`site/account/password`} />}
|
||||
docs={<DynamicMdx language={i18n.language} slug={`docs/site/account/password`} />}
|
||||
/>
|
||||
<SaveSettingsButton btnProps={{ onClick: save, disabled: password.length < 4 }} />
|
||||
{!welcome && <BackToAccountButton />}
|
||||
|
|
|
@ -48,9 +48,9 @@ import { ModalWrapper } from 'shared/components/wrappers/modal.mjs'
|
|||
import Markdown from 'react-markdown'
|
||||
import Timeago from 'react-timeago'
|
||||
import { TableWrapper } from 'shared/components/wrappers/table.mjs'
|
||||
import { DynamicOrgDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import { PatternReactPreview } from 'shared/components/pattern/preview.mjs'
|
||||
import { Lightbox } from 'shared/components/lightbox.mjs'
|
||||
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
||||
|
||||
export const ns = ['account', 'patterns', 'status']
|
||||
|
||||
|
@ -165,11 +165,6 @@ export const Pattern = ({ id }) => {
|
|||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const backend = useBackend()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
// FIXME: implement a solution for loading docs dynamically
|
||||
const docs = {}
|
||||
for (const option of ['name', 'units', 'public', 'notes', 'image']) {
|
||||
docs[option] = <DynamicOrgDocs language={i18n.language} path={`site/patterns/${option}`} />
|
||||
}
|
||||
|
||||
// Context
|
||||
const { setModal } = useContext(ModalContext)
|
||||
|
@ -380,9 +375,9 @@ export const Pattern = ({ id }) => {
|
|||
update={setName}
|
||||
current={name}
|
||||
original={pattern.name}
|
||||
docs={docs.name}
|
||||
placeholder="Maurits Cornelis Escher"
|
||||
valid={(val) => val && val.length > 0}
|
||||
docs={<DynamicMdx language={i18n.language} slug="docs/site/patterns/name" />}
|
||||
/>
|
||||
|
||||
{/* img: Control level determines whether or not to show this */}
|
||||
|
@ -393,8 +388,8 @@ export const Pattern = ({ id }) => {
|
|||
label={t('image')}
|
||||
update={setImage}
|
||||
current={image}
|
||||
docs={docs.image}
|
||||
valid={(val) => val.length > 0}
|
||||
docs={<DynamicMdx language={i18n.language} slug="docs/site/patterns/image" />}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
|
@ -405,7 +400,6 @@ export const Pattern = ({ id }) => {
|
|||
id="pattern-public"
|
||||
label={t('public')}
|
||||
update={setIsPublic}
|
||||
docs={docs.public}
|
||||
list={[
|
||||
{
|
||||
val: true,
|
||||
|
@ -432,6 +426,7 @@ export const Pattern = ({ id }) => {
|
|||
},
|
||||
]}
|
||||
current={isPublic}
|
||||
docs={<DynamicMdx language={i18n.language} slug="docs/site/patterns/public" />}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
|
@ -442,9 +437,9 @@ export const Pattern = ({ id }) => {
|
|||
id="pattern-notes"
|
||||
label={t('notes')}
|
||||
update={setNotes}
|
||||
docs={docs.notes}
|
||||
current={notes}
|
||||
placeholder={t('mdSupport')}
|
||||
docs={<DynamicMdx language={i18n.language} slug="docs/site/patterns/notes" />}
|
||||
/>
|
||||
) : null}
|
||||
<button
|
||||
|
|
|
@ -9,7 +9,7 @@ import { useBackend } from 'shared/hooks/use-backend.mjs'
|
|||
import { BackToAccountButton } from './shared.mjs'
|
||||
import { SaveSettingsButton } from 'shared/components/buttons/save-settings-button.mjs'
|
||||
import { StringInput } from 'shared/components/inputs.mjs'
|
||||
import { DynamicOrgDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
||||
|
||||
export const ns = ['account', 'status']
|
||||
|
||||
|
@ -46,7 +46,7 @@ export const PlatformSettings = ({ platform }) => {
|
|||
update={setPlatformId}
|
||||
valid={(val) => val.length > 0}
|
||||
placeholder={'joostdecock'}
|
||||
docs={<DynamicOrgDocs language={i18n.language} path={`site/account/platform`} />}
|
||||
docs={<DynamicMdx language={i18n.language} slug={`docs/site/account/platform`} />}
|
||||
/>
|
||||
<SaveSettingsButton btnProps={{ onClick: save }} />
|
||||
<BackToAccountButton />
|
||||
|
|
|
@ -43,7 +43,6 @@ import { ModalWrapper } from 'shared/components/wrappers/modal.mjs'
|
|||
import Markdown from 'react-markdown'
|
||||
import Timeago from 'react-timeago'
|
||||
import { DisplayRow } from './shared.mjs'
|
||||
import { DynamicOrgDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import {
|
||||
StringInput,
|
||||
PassiveImageInput,
|
||||
|
@ -54,6 +53,7 @@ import {
|
|||
ns as inputNs,
|
||||
} from 'shared/components/inputs.mjs'
|
||||
import { BookmarkButton } from 'shared/components/bookmarks.mjs'
|
||||
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
||||
|
||||
export const ns = [inputNs, 'account', 'patterns', 'status', 'measurements', 'sets']
|
||||
|
||||
|
@ -192,16 +192,6 @@ export const Mset = ({ id, publicOnly = false }) => {
|
|||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
const backend = useBackend()
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
// FIXME: implement a solution for loading docs dynamically the is simple and work as expected
|
||||
const docs = {}
|
||||
for (const option of ['name', 'units', 'public', 'notes', 'image']) {
|
||||
docs[option] = <DynamicOrgDocs language={i18n.language} path={`site/sets/${option}`} />
|
||||
}
|
||||
// FIXME: implement a solution for loading docs dynamically the is simple and work as expected
|
||||
const measieDocs = {}
|
||||
for (const m of measurements) {
|
||||
measieDocs[m] = <DynamicOrgDocs language={i18n.language} path={`measurements/${m}`} />
|
||||
}
|
||||
|
||||
// Context
|
||||
const { setModal } = useContext(ModalContext)
|
||||
|
@ -293,6 +283,11 @@ export const Mset = ({ id, publicOnly = false }) => {
|
|||
} else setLoadingStatus([true, 'backendError', true, false])
|
||||
}
|
||||
|
||||
const docs = {}
|
||||
for (const option of ['name', 'units', 'public', 'notes', 'image']) {
|
||||
docs[option] = <DynamicMdx language={i18n.language} slug={`docs/site/sets/${option}`} />
|
||||
}
|
||||
|
||||
const heading = (
|
||||
<>
|
||||
<div className="flex flex-wrap md:flex-nowrap flex-row gap-2 w-full">
|
||||
|
@ -490,17 +485,6 @@ export const Mset = ({ id, publicOnly = false }) => {
|
|||
label={t('filterByDesign')}
|
||||
current={filter}
|
||||
firstOption={<option value="">{t('noFilter')}</option>}
|
||||
docs={
|
||||
<div className="max-w-prose">
|
||||
<h2>
|
||||
{t('measies')}: {t('filterByDesign')}
|
||||
</h2>
|
||||
<p>
|
||||
If you have a specific design in mind, you can <b>filter by design</b> to only list
|
||||
those measurements that are required for this design.
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
{filterMeasurements().map((mplus) => {
|
||||
|
@ -511,12 +495,14 @@ export const Mset = ({ id, publicOnly = false }) => {
|
|||
id={`measie-${m}`}
|
||||
key={m}
|
||||
m={m}
|
||||
docs={measieDocs[m]}
|
||||
imperial={mset.imperial}
|
||||
label={translated}
|
||||
current={mset.measies[m]}
|
||||
original={mset.measies[m]}
|
||||
update={updateMeasies}
|
||||
docs={
|
||||
<DynamicMdx language={i18n.language} slug={`docs/measurements/${m.toLowerCase()}`} />
|
||||
}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
|
@ -531,9 +517,9 @@ export const Mset = ({ id, publicOnly = false }) => {
|
|||
update={setName}
|
||||
current={name}
|
||||
original={mset.name}
|
||||
docs={docs.name}
|
||||
placeholder="Georg Cantor"
|
||||
valid={(val) => val && val.length > 0}
|
||||
docs={docs.name}
|
||||
/>
|
||||
|
||||
{/* img: Control level determines whether or not to show this */}
|
||||
|
@ -544,8 +530,8 @@ export const Mset = ({ id, publicOnly = false }) => {
|
|||
label={t('image')}
|
||||
update={setImage}
|
||||
current={image}
|
||||
docs={docs.image}
|
||||
valid={(val) => val.length > 0}
|
||||
docs={docs.image}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
|
@ -556,7 +542,6 @@ export const Mset = ({ id, publicOnly = false }) => {
|
|||
id="set-public"
|
||||
label={t('public')}
|
||||
update={setIsPublic}
|
||||
docs={docs.public}
|
||||
list={[
|
||||
{
|
||||
val: true,
|
||||
|
@ -583,6 +568,7 @@ export const Mset = ({ id, publicOnly = false }) => {
|
|||
},
|
||||
]}
|
||||
current={isPublic}
|
||||
docs={docs.public}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
|
@ -592,7 +578,6 @@ export const Mset = ({ id, publicOnly = false }) => {
|
|||
<ListInput
|
||||
id="set-units"
|
||||
label={t('units')}
|
||||
docs={docs.units}
|
||||
update={setImperial}
|
||||
list={[
|
||||
{
|
||||
|
@ -617,6 +602,7 @@ export const Mset = ({ id, publicOnly = false }) => {
|
|||
},
|
||||
]}
|
||||
current={imperial}
|
||||
docs={docs.units}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
|
@ -627,9 +613,9 @@ export const Mset = ({ id, publicOnly = false }) => {
|
|||
id="set-notes"
|
||||
label={t('notes')}
|
||||
update={setNotes}
|
||||
docs={docs.notes}
|
||||
current={notes}
|
||||
placeholder={t('mdSupport')}
|
||||
docs={docs.notes}
|
||||
/>
|
||||
) : null}
|
||||
<button
|
||||
|
|
|
@ -10,7 +10,7 @@ import { Icons, welcomeSteps, BackToAccountButton } from './shared.mjs'
|
|||
import { OkIcon, NoIcon } from 'shared/components/icons.mjs'
|
||||
import { ContinueButton } from 'shared/components/buttons/continue-button.mjs'
|
||||
import { StringInput } from 'shared/components/inputs.mjs'
|
||||
import { DynamicOrgDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
||||
|
||||
export const ns = ['account', 'status']
|
||||
|
||||
|
@ -72,7 +72,7 @@ export const UsernameSettings = ({ welcome = false }) => {
|
|||
)}
|
||||
</span>
|
||||
}
|
||||
docs={<DynamicOrgDocs language={i18n.language} path={`site/account/username`} />}
|
||||
docs={<DynamicMdx language={i18n.language} slug={`docs/site/account/username`} />}
|
||||
/>
|
||||
<button className={btnClasses} disabled={!available} onClick={save}>
|
||||
<span className="flex flex-row items-center gap-2">
|
||||
|
|
|
@ -21,7 +21,6 @@ import { ns as designNs } from 'shared/components/designs/design.mjs'
|
|||
import { Difficulty } from 'shared/components/designs/difficulty.mjs'
|
||||
import { PageLink, AnchorLink, Link } from 'shared/components/link.mjs'
|
||||
import { DocsLink, DocsTitle } from 'shared/components/mdx/docs-helpers.mjs'
|
||||
import { DynamicOrgDocs as DynamicDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import { Popout } from 'shared/components/popout/index.mjs'
|
||||
import { NewPatternIcon } from 'shared/components/icons.mjs'
|
||||
|
||||
|
@ -40,10 +39,7 @@ export const ns = nsMerge(
|
|||
const Option = ({ id, option, t, design }) =>
|
||||
optionType(option) === 'constant' ? null : (
|
||||
<li key={option.name}>
|
||||
<PageLink
|
||||
txt={t(`${design}:${option.name}.t`)}
|
||||
href={`/docs/designs/${design}/options/${id.toLowerCase()}`}
|
||||
/>
|
||||
<DocsLink site="org" slug={`docs/designs/${design}/options/${id.toLowerCase()}`} />
|
||||
</li>
|
||||
)
|
||||
|
||||
|
@ -168,7 +164,6 @@ export const DesignInfo = ({ design, docs = false, workbench = false }) => {
|
|||
format={(t) => t.split(':').pop().trim()}
|
||||
/>
|
||||
</h2>
|
||||
<DynamicDocs path={`designs/${design}/notes`} language={language} noFooter noTitle />
|
||||
</>
|
||||
)}
|
||||
{docs ? docsContent : null}
|
||||
|
@ -229,12 +224,6 @@ export const DesignInfo = ({ design, docs = false, workbench = false }) => {
|
|||
format={(t) => t.split(':').pop().trim()}
|
||||
/>
|
||||
</h2>
|
||||
<DynamicDocs
|
||||
path={`designs/${design}/${page}`}
|
||||
language={language}
|
||||
noFooter
|
||||
noTitle
|
||||
/>
|
||||
</Fragment>
|
||||
))}
|
||||
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
import dynamic from 'next/dynamic'
|
||||
import { useState } from 'react'
|
||||
import { Spinner } from 'shared/components/spinner.mjs'
|
||||
import { MdxWrapper } from './wrapper.mjs'
|
||||
import { components } from 'shared/components/mdx/index.mjs'
|
||||
|
||||
const orgComponents = components()
|
||||
export const loaders = {
|
||||
en: (path) => import(`orgmarkdown/docs/${path}/en.md`),
|
||||
de: (path) => import(`orgmarkdown/docs/${path}/de.md`),
|
||||
fr: (path) => import(`orgmarkdown/docs/${path}/fr.md`),
|
||||
es: (path) => import(`orgmarkdown/docs/${path}/es.md`),
|
||||
nl: (path) => import(`orgmarkdown/docs/${path}/nl.md`),
|
||||
uk: (path) => import(`orgmarkdown/docs/${path}/uk.md`),
|
||||
}
|
||||
/*
|
||||
* Webpack will check on disk for all possible files matching this
|
||||
* dynamic import. So unless we divide it up a bit your computer
|
||||
* will melt when running this in development mode
|
||||
*
|
||||
* This will return a language-specific component
|
||||
*/
|
||||
|
||||
function DynamicDocs({ path, lang, noFooter = false, noTitle = false }) {
|
||||
const [frontmatter, setFrontmatter] = useState({})
|
||||
const mdx = dynamic(
|
||||
() =>
|
||||
loaders[lang](path).then((mod) => {
|
||||
setFrontmatter(mod.frontmatter)
|
||||
return mod
|
||||
}),
|
||||
{ ssr: false }
|
||||
)
|
||||
const MDX = mdx ? mdx : <Spinner className="w16 h-16 animate-spin text-primary" />
|
||||
|
||||
return (
|
||||
<MdxWrapper
|
||||
path={path}
|
||||
language={lang}
|
||||
noFooter={noFooter}
|
||||
title={noTitle ? false : frontmatter.title}
|
||||
>
|
||||
<MDX components={orgComponents} />
|
||||
</MdxWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
* Return language-specific component
|
||||
*/
|
||||
export const DynamicOrgDocs = ({
|
||||
path = false,
|
||||
language = 'en',
|
||||
noTitle = false,
|
||||
noFooter = false,
|
||||
}) => {
|
||||
if (!path) return null
|
||||
return <DynamicDocs lang={language} {...{ path, noTitle, noFooter }} />
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
import { PageLink } from 'shared/components/link.mjs'
|
||||
import { DocsIcon } from 'shared/components/icons.mjs'
|
||||
|
||||
export const MdxWrapper = ({ title = false, path, language, children, noFooter = false }) => {
|
||||
const slug = `${language === 'en' ? '' : '/' + language}/docs/${path}`
|
||||
|
||||
return (
|
||||
<>
|
||||
{title ? <h1>{title}</h1> : null}
|
||||
<div className="mdx text-base-content">{children}</div>
|
||||
{noFooter ? null : (
|
||||
<div
|
||||
className={`flex flex-row gap-1 text-sm opacity-70 justify-end items-center
|
||||
border border-solid border-neutral border-b-0 border-r-0 border-l-0 pt-1 mt-2`}
|
||||
>
|
||||
<DocsIcon className="w-5 h-5" />
|
||||
<PageLink txt={slug} href={slug} />
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
import dynamic from 'next/dynamic'
|
||||
import { MDXProvider } from '@mdx-js/react'
|
||||
import { useState } from 'react'
|
||||
import { Spinner } from 'shared/components/spinner.mjs'
|
||||
import { PageLink } from 'shared/components/link.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { components } from 'shared/components/mdx/index.mjs'
|
||||
|
||||
export const ns = ['modal']
|
||||
|
||||
export const MdxWrapper = ({ title = false, path, language, children }) => {
|
||||
const { t } = useTranslation(ns)
|
||||
const slug = `${language === 'en' ? '' : '/' + language}/docs/${path}`
|
||||
|
||||
return (
|
||||
<>
|
||||
{title ? <h1>{title}</h1> : null}
|
||||
<div className="mdx text-base-content text-base">
|
||||
<MDXProvider components={components}>{children}</MDXProvider>
|
||||
</div>
|
||||
<div
|
||||
className={`flex flex-row gap-1 text-sm opacity-70 justify-end items-center
|
||||
border border-solid border-neutral border-b-0 border-r-0 border-l-0 pt-1 mt-2`}
|
||||
>
|
||||
<span>{t('modal:source')}:</span>
|
||||
<PageLink txt={slug} href={slug} />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export const DynamicMdx = ({ path = false, language = 'en' }) => {
|
||||
// Extract frontmatter from mdx
|
||||
const [frontmatter, setFrontmatter] = useState({})
|
||||
|
||||
// Dynamic import of the MDX content
|
||||
const mdx = dynamic(
|
||||
() =>
|
||||
import(`markdown/docs/${path}/${language}.md`).then((mod) => {
|
||||
setFrontmatter(mod.frontmatter)
|
||||
return mod
|
||||
}),
|
||||
{ ssr: false }
|
||||
)
|
||||
|
||||
const MDX = mdx ? mdx : <Spinner className="w16 h-16 animate-spin text-primary" />
|
||||
|
||||
return (
|
||||
<MdxWrapper {...{ path, language, ...frontmatter }}>
|
||||
<MDX components={components} />
|
||||
</MdxWrapper>
|
||||
)
|
||||
}
|
51
sites/shared/components/mdx/dynamic.mjs
Normal file
51
sites/shared/components/mdx/dynamic.mjs
Normal file
|
@ -0,0 +1,51 @@
|
|||
// Dependencies
|
||||
import { compileMdx } from 'shared/mdx/browser-compile.mjs'
|
||||
import * as runtime from 'react/jsx-runtime'
|
||||
import { run } from '@mdx-js/mdx'
|
||||
// Hooks
|
||||
import { useState, useEffect } from 'react'
|
||||
// Components
|
||||
import { MdxWrapper } from 'shared/components/wrappers/mdx.mjs'
|
||||
import { Loading } from 'shared/components/spinner.mjs'
|
||||
|
||||
const ghPrefix = 'https://raw.githubusercontent.com/freesewing/freesewing/develop/markdown'
|
||||
const fromGithub = true
|
||||
|
||||
const titles = {
|
||||
1: ({ title }) => <h1>{title}</h1>,
|
||||
2: ({ title }) => <h2>{title}</h2>,
|
||||
3: ({ title }) => <h3>{title}</h3>,
|
||||
4: ({ title }) => <h4>{title}</h4>,
|
||||
5: ({ title }) => <h5>{title}</h5>,
|
||||
6: ({ title }) => <h6>{title}</h6>,
|
||||
}
|
||||
|
||||
const NoTitle = () => null
|
||||
|
||||
export const DynamicMdx = ({ site = 'org', slug, language, title = 1 }) => {
|
||||
const [mdx, setMdx] = useState(false)
|
||||
const [frontmatter, setFrontmatter] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
const loadMdx = async () => {
|
||||
const response = await fetch(`${ghPrefix}/${site}/${slug}/${language}.md`)
|
||||
const md = await response.text()
|
||||
const mdx = await compileMdx({ site, slug, language, md, fromGithub })
|
||||
const { frontmatter: fm } = await run(mdx, runtime)
|
||||
setMdx(mdx)
|
||||
setFrontmatter(fm)
|
||||
}
|
||||
if (!mdx) loadMdx()
|
||||
}, [site, slug, language])
|
||||
|
||||
const Title = title && frontmatter?.title && titles[Number(title)] ? titles[title] : () => null
|
||||
|
||||
return mdx ? (
|
||||
<>
|
||||
<Title title={frontmatter?.title} />
|
||||
<MdxWrapper {...{ mdx, site, slug }} />
|
||||
</>
|
||||
) : (
|
||||
<Loading />
|
||||
)
|
||||
}
|
|
@ -10,10 +10,10 @@ import { EditIcon } from 'shared/components/icons.mjs'
|
|||
import { useAccount } from 'shared/hooks/use-account.mjs'
|
||||
// Components
|
||||
import { PageLink } from 'shared/components/link.mjs'
|
||||
import { TimeAgo } from 'shared/components/timeago/index.mjs'
|
||||
import { TimeAgo, ns as timeagoNs } from 'shared/components/timeago/index.mjs'
|
||||
import { BookmarkButton } from 'shared/components/bookmarks.mjs'
|
||||
|
||||
export const ns = 'account'
|
||||
export const ns = ['account', timeagoNs]
|
||||
|
||||
const PersonList = ({ list }) =>
|
||||
list ? (
|
||||
|
|
|
@ -11,7 +11,7 @@ import Link from 'next/link'
|
|||
import { Robot } from 'shared/components/robot/index.mjs'
|
||||
import { StringInput, PasswordInput } from 'shared/components/inputs.mjs'
|
||||
import { FreeSewingAnimation } from 'shared/components/animations/freesewing.mjs'
|
||||
import { DynamicOrgDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
||||
|
||||
// Translation namespaces used on this page
|
||||
export const ns = ['signup', 'errros', 'account']
|
||||
|
@ -114,7 +114,7 @@ export const Migrate = () => {
|
|||
current={username}
|
||||
update={setUsername}
|
||||
valid={(val) => val.length > 1}
|
||||
docs={<DynamicOrgDocs language={i18n.language} path={`site/account/username`} />}
|
||||
docs={<DynamicMdx language={i18n.language} slug={`docs/site/account/username`} />}
|
||||
/>
|
||||
<PasswordInput
|
||||
id="migrate-password"
|
||||
|
@ -123,7 +123,7 @@ export const Migrate = () => {
|
|||
current={password}
|
||||
update={setPassword}
|
||||
valid={(val) => val.length > 1}
|
||||
docs={<DynamicOrgDocs language={i18n.language} path={`site/account/password`} />}
|
||||
docs={<DynamicMdx language={i18n.language} slug={`docs/site/account/password`} />}
|
||||
/>
|
||||
<button
|
||||
className="btn btn-primary btn-lg w-full mt-4"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import { nsMerge } from 'shared/utils.mjs'
|
||||
import { MeasieInput, ns as inputNs } from 'shared/components/inputs.mjs'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import { DynamicOrgDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
||||
|
||||
export const ns = nsMerge('workbench', inputNs)
|
||||
|
||||
|
@ -22,8 +22,10 @@ export const MeasiesEditor = ({ Design, settings, update }) => {
|
|||
imperial={settings.units === 'umperial' ? true : false}
|
||||
original={settings.measurements?.[m]}
|
||||
update={(m, newVal) => onUpdate(m, newVal)}
|
||||
docs={<DynamicOrgDocs language={i18n.language} path={`measurements/${m}`} />}
|
||||
id={`edit-${m}`}
|
||||
docs={
|
||||
<DynamicMdx language={i18n.language} slug={`docs/measurements/${m.toLowerCase()}`} />
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
@ -28,13 +28,13 @@ import {
|
|||
} from 'shared/components/icons.mjs'
|
||||
import { Popout } from 'shared/components/popout/index.mjs'
|
||||
import { PageLink } from 'shared/components/link.mjs'
|
||||
import { DynamicOrgDocs } from 'site/components/dynamic-org-docs.mjs'
|
||||
import { DynamicMdx } from 'shared/components/mdx/dynamic.mjs'
|
||||
|
||||
export const ns = ['workbench', 'status']
|
||||
|
||||
export const SaveView = ({ design, settings, setView, saveAs }) => {
|
||||
// Hooks
|
||||
const { t } = useTranslation(ns)
|
||||
const { t, i18n } = useTranslation(ns)
|
||||
const backend = useBackend()
|
||||
const router = useRouter()
|
||||
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||
|
@ -112,6 +112,11 @@ export const SaveView = ({ design, settings, setView, saveAs }) => {
|
|||
} else setLoadingStatus([true, 'backendError', true, false])
|
||||
}
|
||||
|
||||
const docs = {}
|
||||
for (const field of ['name', 'notes', 'goto']) {
|
||||
docs[field] = <DynamicMdx language={i18n.language} slug={`docs/site/patterns/${field}`} />
|
||||
}
|
||||
|
||||
return (
|
||||
<AuthWrapper>
|
||||
<div className="m-auto mt-8 max-w-2xl px-4">
|
||||
|
@ -154,7 +159,7 @@ export const SaveView = ({ design, settings, setView, saveAs }) => {
|
|||
current={name}
|
||||
update={setName}
|
||||
valid={notEmpty}
|
||||
docs={<DynamicOrgDocs language={router.locale} path={`site/patterns/name`} />}
|
||||
docs={docs.name}
|
||||
/>
|
||||
|
||||
{withNotes ? (
|
||||
|
@ -162,7 +167,7 @@ export const SaveView = ({ design, settings, setView, saveAs }) => {
|
|||
label={t('workbench:notes')}
|
||||
current={notes}
|
||||
update={setNotes}
|
||||
docs={<DynamicOrgDocs language={router.locale} path={`site/patterns/notes`} />}
|
||||
docs={docs.notes}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
|
@ -170,6 +175,7 @@ export const SaveView = ({ design, settings, setView, saveAs }) => {
|
|||
update={setEditAfterSaveAs}
|
||||
label={t('workbench:whereToGoAfterSaveAs')}
|
||||
current={editAfterSaveAs}
|
||||
docs={docs.goto}
|
||||
list={[
|
||||
{
|
||||
val: true,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// __SDEFILE__ - This file is a dependency for the stand-alone environment
|
||||
// Dependencies
|
||||
import * as runtime from 'react/jsx-runtime'
|
||||
import { runSync } from '@mdx-js/mdx'
|
||||
import { run, runSync } from '@mdx-js/mdx'
|
||||
import { useState, useEffect } from 'react'
|
||||
// Components that are available in MDX content
|
||||
import { components as baseComponents } from 'shared/components/mdx/index.mjs'
|
||||
|
@ -14,7 +14,7 @@ import { Loading } from 'shared/components/spinner.mjs'
|
|||
* This is the default async version
|
||||
*/
|
||||
const runMdx = async (mdx) => {
|
||||
const { default: Content } = await runSync(mdx, runtime)
|
||||
const { default: Content } = await run(mdx, runtime)
|
||||
|
||||
return Content
|
||||
}
|
||||
|
|
36
sites/shared/mdx/browser-compile.mjs
Normal file
36
sites/shared/mdx/browser-compile.mjs
Normal file
|
@ -0,0 +1,36 @@
|
|||
// MDX compiler
|
||||
import { compile } from '@mdx-js/mdx'
|
||||
// Remark plugins from the ecosystem
|
||||
import remarkFrontmatter from 'remark-frontmatter'
|
||||
import remarkMdxFrontmatter from 'remark-mdx-frontmatter'
|
||||
import remarkGfm from 'remark-gfm'
|
||||
import smartypants from 'remark-smartypants'
|
||||
// FreeSewing custom remark plugins
|
||||
import { remarkGithubImages } from './remark-github-images.mjs'
|
||||
|
||||
/*
|
||||
* Compiles markdown/mdx to a function body
|
||||
*/
|
||||
export const compileMdx = async ({
|
||||
md, // A string holding the markdown
|
||||
site, // The site folder, one of 'org' or 'dev'
|
||||
slug, // The slug to the page below the folder (like 'guides/plugins')
|
||||
jargon, // An object of jargon definitions. See rehype-jargon
|
||||
fromGithub = false, // Set this to true when dynamically loading mdx from Github
|
||||
}) => {
|
||||
const mdx = String(
|
||||
await compile(md, {
|
||||
outputFormat: 'function-body',
|
||||
development: false,
|
||||
remarkPlugins: [
|
||||
remarkFrontmatter,
|
||||
remarkMdxFrontmatter,
|
||||
remarkGfm,
|
||||
smartypants,
|
||||
[remarkGithubImages, { site, slug }],
|
||||
],
|
||||
})
|
||||
)
|
||||
|
||||
return mdx
|
||||
}
|
|
@ -11,6 +11,7 @@ import smartypants from 'remark-smartypants'
|
|||
// FreeSewing custom remark plugins
|
||||
import { remarkIntroAsFrontmatter } from './remark-intro-as-frontmatter.mjs'
|
||||
import { remarkTocAsFrontmatter } from './remark-toc-as-frontmatter.mjs'
|
||||
import { remarkGithubImages } from './remark-github-images.mjs'
|
||||
// Rehype plugins from the ecosystem
|
||||
import rehypeHighlight from 'rehype-highlight'
|
||||
import rehypeAutolinkHeadings from 'rehype-autolink-headings'
|
||||
|
@ -28,6 +29,7 @@ export const compileMdx = async ({
|
|||
site, // The site folder, one of 'org' or 'dev'
|
||||
slug, // The slug to the page below the folder (like 'guides/plugins')
|
||||
jargon, // An object of jargon definitions. See rehype-jargon
|
||||
fromGithub = false, // Set this to true when dynamically loading mdx from Github
|
||||
}) => {
|
||||
const mdx = String(
|
||||
await compile(md, {
|
||||
|
@ -38,7 +40,9 @@ export const compileMdx = async ({
|
|||
remarkMdxFrontmatter,
|
||||
remarkGfm,
|
||||
smartypants,
|
||||
[
|
||||
fromGithub
|
||||
? remarkGithubImages
|
||||
: [
|
||||
remarkCopyLinkedFiles,
|
||||
{
|
||||
destinationDir: path.resolve(`../${site}/public/mdx`),
|
||||
|
|
|
@ -2,6 +2,7 @@ import fs from 'fs'
|
|||
import path from 'path'
|
||||
import { compileMdx } from './compile.mjs'
|
||||
import { jargon } from 'shared/jargon/index.mjs'
|
||||
import { ghPrefix } from './remark-github-images.mjs'
|
||||
|
||||
/*
|
||||
* Loads markdown/mdx from disk
|
||||
|
@ -13,6 +14,20 @@ export const loadMdxFromDisk = async ({
|
|||
}) =>
|
||||
await fs.promises.readFile(path.resolve(`../../markdown/${site}/${slug}/${language}.md`), 'utf-8')
|
||||
|
||||
/*
|
||||
* Loads markdown/mdx from Github
|
||||
*/
|
||||
export const loadMdxFromGithub = async ({
|
||||
language, // The language code of the markdown to load (like 'en')
|
||||
site, // The site folder, one of 'dev' or 'org'
|
||||
slug, // The slug below that folder, like 'guides/plugins'
|
||||
}) => {
|
||||
const response = await fetch(`${ghPrefix}/${site}/${slug}/${language}.md`)
|
||||
const md = await response.text()
|
||||
|
||||
return md
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads markdown/mdx from disk and compiles it for use
|
||||
* in static props.
|
||||
|
@ -24,7 +39,7 @@ export const loadMdxAsStaticProps = async ({
|
|||
slugs = {}, // An object where key is an ID and value the slug to load
|
||||
}) => {
|
||||
const result = {}
|
||||
if (slug) result.default = slug
|
||||
if (slug) slugs.default = slug
|
||||
for (const [key, val] of Object.entries(slugs)) {
|
||||
const md = await loadMdxFromDisk({ language, site, slug: val })
|
||||
const mdx = await compileMdx({
|
||||
|
@ -33,7 +48,7 @@ export const loadMdxAsStaticProps = async ({
|
|||
slug: val,
|
||||
jargon: jargon[language],
|
||||
})
|
||||
result[key] = { mdx, slug: val }
|
||||
result[key] = { ...mdx, slug: val }
|
||||
}
|
||||
|
||||
return slug ? result.default : result
|
||||
|
|
28
sites/shared/mdx/remark-github-images.mjs
Normal file
28
sites/shared/mdx/remark-github-images.mjs
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* This is a remark plugin that will update the src of local images to
|
||||
* load them from Github. It is used when we load markdown/mdx dynamically
|
||||
* from Github rather than from disk.
|
||||
*/
|
||||
import { visit } from 'unist-util-visit'
|
||||
|
||||
export const ghPrefix = 'https://raw.githubusercontent.com/freesewing/freesewing/develop/markdown'
|
||||
|
||||
const convertUrl = ({ site, slug, url }) => {
|
||||
if (url.slice(0, 1) === 'http://') return url
|
||||
if (url.slice(0, 7) === 'http://') return url
|
||||
if (url.slice(0, 8) === 'https://') return url
|
||||
|
||||
return `${ghPrefix}/${site}/${slug}/${url}`
|
||||
}
|
||||
|
||||
export function remarkGithubImages({ site, slug }) {
|
||||
return (tree) => {
|
||||
visit(tree, function (node, index, parent) {
|
||||
if (node.type === 'image') node.url = convertUrl({ site, slug, url: node.url })
|
||||
|
||||
return node
|
||||
})
|
||||
|
||||
return tree
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue