diff --git a/.gitignore b/.gitignore index b043e185492..6e84504b04f 100644 --- a/.gitignore +++ b/.gitignore @@ -94,6 +94,10 @@ sites/dev/public/mstile-150x150.png sites/dev/public/safari-pinned-tab.svg sites/dev/public/site.webmanifest +# react docs +packages/react/docs + + # Node dependencies node_modules diff --git a/packages/react/components/Button/index.mjs b/packages/react/components/Button/index.mjs index 1ad53d64c68..a37709f036c 100644 --- a/packages/react/components/Button/index.mjs +++ b/packages/react/components/Button/index.mjs @@ -1,32 +1,45 @@ import React from 'react' /** - * A button with an icon and a label. Common across our UI + * A button with an icon and a label, something which we commonly use across our UI. * - * @param {object} props - All React props - * @param {string} title - The button title - * @param {string} className - Any EXTRA classes to add - * @param {string} color - The main button color - * @param {string} href - Set this to make it a link + * @component + * @param {object} props - All component props + * @param {string} [props.btnProps={}] - Any props to pass to the button + * @param {string} [props.children=[]] - The button children (content) + * @param {string} [props.className=''] - Any extra classes to add to the button + * @param {string} [props.title=''] - The button title + * @param {string} [props.color='primary'] - The main button color, one of DaisyUI's named colors + * @param {string} [props.href=false] - Set this to render a link instead of a button + * @param {function} [props.onClick=false] - Set this to render a button instead of a link + * @returns {JSX.Element} */ export const IconButton = ({ - title = '', - className = '', - onClick = false, - href = false, - color = 'primary', - children = [], btnProps = {}, + children = [], + className = '', + color = 'primary', + href = false, + onClick = false, + title = '', }) => { const allProps = { - className: `${staticLinkClasses} tw:daisy-btn-${color} hover:tw:text-${color}-content ${className}`, + className: `tw:daisy-btn-${color} hover:tw:text-${color}-content ${className}`, title: title, ...btnProps, } if (onClick) allProps.onClick = onClick else if (href) allProps.href = href - return onClick ? : {children} + return onClick ? ( + + ) : ( + +
{children}
+
+ ) } const staticLinkClasses = diff --git a/packages/react/components/Tab/index.mjs b/packages/react/components/Tab/index.mjs index fe86382d93c..7c430fbe0f3 100644 --- a/packages/react/components/Tab/index.mjs +++ b/packages/react/components/Tab/index.mjs @@ -31,10 +31,10 @@ export const Tabs = ({ tabs = '', active = 0, children, withModal = false }) => ) return ( -
-
+
+
{tablist.map((title, tabId) => { - const btnClasses = `tw:text-lg tw:font-bold tw:capitalize tw:daisy-tab tw:h-auto tw:daisy-tabs-bordered tw:grow tw:py-1 ${ + const btnClasses = `tw:text-lg tw:font-bold tw:capitalize tw:daisy-tab tw:h-auto tw:grow tw:py-1 ${ activeTab === tabId ? 'tw:daisy-tab-active' : '' } tw:border-b-2 tw:border-solid tw:border-x-0 tw:border-t-0 tw:bg-transparent` @@ -66,7 +66,7 @@ export const Tabs = ({ tabs = '', active = 0, children, withModal = false }) => ) })}
-
{childrenWithTabSetter}
+
{childrenWithTabSetter}
) } diff --git a/packages/react/jsdoc.json b/packages/react/jsdoc.json new file mode 100644 index 00000000000..152bfae45dc --- /dev/null +++ b/packages/react/jsdoc.json @@ -0,0 +1,30 @@ +{ + "plugins": [ ], + "recurseDepth": 10, + "source":{ + "includePattern": ".+\\.mjs$", + "excludePattern": "(^|\\/|\\\\)_" + }, + "sourceType": "module", + "tags":{ + "allowUnknownTags": true, + "dictionaries":[ + "jsdoc", + "closure" + ] + }, + "templates":{ + "monospaceLinks": false, + "cleverLinks": false, + "default":{ + "outputSourceFiles": true + } + }, + "opts":{ + "_":[ ], + "debug": false, + "encoding": "utf8", + "explain": true, + "recurse": true + } +} diff --git a/packages/react/mkdocs.sh b/packages/react/mkdocs.sh new file mode 100755 index 00000000000..68e7bfd7fe0 --- /dev/null +++ b/packages/react/mkdocs.sh @@ -0,0 +1,5 @@ +#!/bin/bash +mkdir -p ./docs/components + +jsdoc -c jsdoc.json components/Account/ > ../../sites/dev/prebuild/jsdoc/react/components/account.json +jsdoc -c jsdoc.json components/Button/ > ../../sites/dev/prebuild/jsdoc/react/components/button.json diff --git a/sites/dev/docs/reference/packages/react/components/button/readme.mdx b/sites/dev/docs/reference/packages/react/components/button/readme.mdx index 94f1901cfdb..e6e419cec6b 100644 --- a/sites/dev/docs/reference/packages/react/components/button/readme.mdx +++ b/sites/dev/docs/reference/packages/react/components/button/readme.mdx @@ -2,6 +2,18 @@ title: Button --- -:::note -This page is yet to be created -::: +import { DocusaurusDoc } from '@freesewing/react/components/Docusaurus' +import { jsdocIconButton } from '@site/prebuild/jsdoc/components.button.mjs' +import { ComponentDocs } from '@site/src/components/component-docs.js' + + + +The **Button** component family provides the following components: + +- [IconButton](#iconbutton) + +## IconButton + + + + diff --git a/sites/dev/package.json b/sites/dev/package.json index 77dc1aed1e7..2a6bf7c88cb 100644 --- a/sites/dev/package.json +++ b/sites/dev/package.json @@ -10,6 +10,9 @@ "deploy": "docusaurus deploy", "clear": "docusaurus clear", "serve": "docusaurus serve", + "prebuild": "./scripts/prebuild.sh", + "predev": "npm run prebuild", + "prestart": "npm run prebuild", "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids" }, diff --git a/sites/dev/scripts/prebuild.mjs b/sites/dev/scripts/prebuild.mjs new file mode 100644 index 00000000000..a943d6bc5c7 --- /dev/null +++ b/sites/dev/scripts/prebuild.mjs @@ -0,0 +1,60 @@ +import { root, globDir, readJsonFile, writeFile } from '../../../scripts/fs.mjs' +import path from 'path' + +const prefix = 'packages/react' +const cdir = ['prebuild', 'jsdoc', 'react', 'components'] +const components = await globDir(cdir, '**/*.json') + +for (const file of components) { + const data = await processJsdocFile(file) + await writeJsdocFiles(data) +} + +async function processJsdocFile(file) { + const all = { + components: {}, + } + const data = await readJsonFile([...cdir, path.basename(file)]) + const family = path.basename(file.slice(0, -5)) + all.components[family] = [] + for (const entry of data) { + // Is it a component? + const yes = entry.tags + ? entry.tags.filter((tag) => tag.title === 'component').length > 0 + : false + if (yes) + all.components[family].push({ + family, + name: entry.name, + file: relativePath(entry.meta.filename, entry.meta.path), + line: entry.meta.lineno, + importAs: `import { ${entry.name} } from "${importPath(entry.meta.path)}"`, + desc: entry.description, + params: entry.params, + return: entry.returns, + }) + } + + return all +} + +async function writeJsdocFiles(data) { + for (const [family, d] of Object.entries(data.components)) { + const code = d.map( + (entry) => `export const jsdoc${entry.name} = ${JSON.stringify(entry)}` + '\n' + ) + await writeFile(['prebuild', 'jsdoc', `components.${family}.mjs`], code) + } +} + +function importPath(folder) { + return `@freesewing/react` + folder.split(prefix).pop() +} + +function relativePath(filename, folder) { + return prefix + folder.split(prefix).pop() + '/' + filename +} + +function componentFamily(folder) { + return folder.split(`${prefix}/components/`).pop() +} diff --git a/sites/dev/scripts/prebuild.sh b/sites/dev/scripts/prebuild.sh new file mode 100755 index 00000000000..b3e36262fb8 --- /dev/null +++ b/sites/dev/scripts/prebuild.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +cd ../../packages/react +./mkdocs.sh +cd - +node scripts/prebuild.mjs diff --git a/sites/dev/src/components/component-docs.js b/sites/dev/src/components/component-docs.js new file mode 100644 index 00000000000..2ac64695f00 --- /dev/null +++ b/sites/dev/src/components/component-docs.js @@ -0,0 +1,102 @@ +import React from 'react' +import { Highlight } from '@freesewing/react/components/Highlight' +import { Tabs, Tab } from '@freesewing/react/components/Tab' +import { FingerprintIcon, WarningIcon } from '@freesewing/react/components/Icon' +import { IconButton } from '@freesewing/react/components/Button' +import { MiniNote } from '@freesewing/react/components/Mini' + +export const ComponentDocs = ({ docs }) => { + return ( + <> +

{docs.desc}

+ + +

+ You can import the {docs.name} component from the {docs.family}{' '} + component family in the @freesewing/react package: +

+ {docs.importAs} +
+ +

+ The {docs.name} component takes the following props: +

+ +
+ + + Note that this component will take up the full width made available to it. + + + {[ + `import { FingerprintIcon, WarningIcon } from '@freesewing/react/components/Icon'`, + `import { IconButton } from '@freesewing/react/components/Button'`, + ``, + ``, + ` `, + ` Primary (default)`, + ``, + `
`, + ``, + ` `, + ` Warning`, + ``, + ].join('\n')} +
+ + + Primary (default) + +
+ + + Warning + +
+ +

+ The {docs.name} component is defined{' '} + + on{' '} + + line + {docs.line} + {' '} + in {docs.file} + + . +

+
+
+ + ) +} + +const PropsTable = ({ docs }) => ( + + + + + + + + + + + + {docs.params.map((prop, i) => ( + + + + + + + + ))} + +
NameTypeDescriptionOptionalDefault Value
{prop.name}{prop.type.names}{prop.description}{prop.optional ? 'yes' : 'no'} + {prop.defaultvalue} +
+)