diff --git a/packages/framework-react/package.json b/packages/framework-react/package.json index dd903736..4366b101 100644 --- a/packages/framework-react/package.json +++ b/packages/framework-react/package.json @@ -52,6 +52,7 @@ "find-up": "^5.0.0", "magic-string": "^0.30.17", "react-docgen": "^7.1.0", + "react-docgen-typescript": "^2.2.2", "resolve": "^1.22.10", "storybook-builder-rsbuild": "workspace:*", "tsconfig-paths": "^4.2.0" @@ -59,6 +60,7 @@ "devDependencies": { "@rsbuild/core": "^1.1.13", "@storybook/types": "8.5.0-beta.8", + "@types/react": "^18.3.18", "@types/resolve": "^1.20.6", "react": "18.3.1", "react-dom": "18.3.1", diff --git a/packages/framework-react/src/plugins/docgen-handlers/actualNameHandler.ts b/packages/framework-react/src/plugins/docgen-handlers/actualNameHandler.ts deleted file mode 100644 index 58c09352..00000000 --- a/packages/framework-react/src/plugins/docgen-handlers/actualNameHandler.ts +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Code taken from https://github.com/storybookjs/storybook/tree/next/code/frameworks/react-vite/src/plugins - */ - -/** - * This is heavily based on the react-docgen `displayNameHandler` - * (https://github.com/reactjs/react-docgen/blob/26c90c0dd105bf83499a83826f2a6ff7a724620d/src/handlers/displayNameHandler.ts) - * but instead defines an `actualName` property on the generated docs that is taken first from the component's actual name. - * This addresses an issue where the name that the generated docs are stored under is incorrectly named with the `displayName` - * and not the component's actual name. - * - * This is inspired by `actualNameHandler` from https://github.com/storybookjs/babel-plugin-react-docgen, but is modified - * directly from displayNameHandler, using the same approach as babel-plugin-react-docgen. - */ - -import type { Handler, NodePath, babelTypes as t } from 'react-docgen' -import { utils } from 'react-docgen' - -const { getNameOrValue, isReactForwardRefCall } = utils - -const actualNameHandler: Handler = function actualNameHandler( - documentation, - componentDefinition, -) { - documentation.set('definedInFile', componentDefinition.hub.file.opts.filename) - - if ( - (componentDefinition.isClassDeclaration() || - componentDefinition.isFunctionDeclaration()) && - componentDefinition.has('id') - ) { - documentation.set( - 'actualName', - getNameOrValue(componentDefinition.get('id') as NodePath), - ) - } else if ( - componentDefinition.isArrowFunctionExpression() || - componentDefinition.isFunctionExpression() || - isReactForwardRefCall(componentDefinition) - ) { - let currentPath: NodePath = componentDefinition - - while (currentPath.parentPath) { - if (currentPath.parentPath.isVariableDeclarator()) { - documentation.set( - 'actualName', - getNameOrValue(currentPath.parentPath.get('id')), - ) - return - } - if (currentPath.parentPath.isAssignmentExpression()) { - const leftPath = currentPath.parentPath.get('left') - - if (leftPath.isIdentifier() || leftPath.isLiteral()) { - documentation.set('actualName', getNameOrValue(leftPath)) - return - } - } - - currentPath = currentPath.parentPath - } - // Could not find an actual name - documentation.set('actualName', '') - } -} - -export default actualNameHandler diff --git a/packages/framework-react/src/plugins/docgen-resolver.ts b/packages/framework-react/src/plugins/docgen-resolver.ts deleted file mode 100644 index 83a023fb..00000000 --- a/packages/framework-react/src/plugins/docgen-resolver.ts +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Code taken from https://github.com/storybookjs/storybook/tree/next/code/frameworks/react-vite/src/plugins - */ - -import { extname } from 'node:path' -import resolve from 'resolve' - -export class ReactDocgenResolveError extends Error { - // the magic string that react-docgen uses to check if a module is ignored - readonly code = 'MODULE_NOT_FOUND' - - constructor(filename: string) { - super(`'${filename}' was ignored by react-docgen.`) - } -} - -/* The below code was copied from: - * https://github.com/reactjs/react-docgen/blob/df2daa8b6f0af693ecc3c4dc49f2246f60552bcb/packages/react-docgen/src/importer/makeFsImporter.ts#L14-L63 - * because it wasn't exported from the react-docgen package. - * watch out: when updating this code, also update the code in code/presets/react-webpack/src/loaders/docgen-resolver.ts - */ - -// These extensions are sorted by priority -// resolve() will check for files in the order these extensions are sorted -export const RESOLVE_EXTENSIONS = [ - '.js', - '.cts', // These were originally not in the code, I added them - '.mts', // These were originally not in the code, I added them - '.ctsx', // These were originally not in the code, I added them - '.mtsx', // These were originally not in the code, I added them - '.ts', - '.tsx', - '.mjs', - '.cjs', - '.mts', - '.cts', - '.jsx', -] - -export function defaultLookupModule(filename: string, basedir: string): string { - const resolveOptions = { - basedir, - extensions: RESOLVE_EXTENSIONS, - // we do not need to check core modules as we cannot import them anyway - includeCoreModules: false, - } - - try { - return resolve.sync(filename, resolveOptions) - } catch (error) { - const ext = extname(filename) - let newFilename: string - - // if we try to import a JavaScript file it might be that we are actually pointing to - // a TypeScript file. This can happen in ES modules as TypeScript requires to import other - // TypeScript files with .js extensions - // https://www.typescriptlang.org/docs/handbook/esm-node.html#type-in-packagejson-and-new-extensions - switch (ext) { - case '.js': - case '.mjs': - case '.cjs': - newFilename = `${filename.slice(0, -2)}ts` - break - - case '.jsx': - newFilename = `${filename.slice(0, -3)}tsx` - break - default: - throw error - } - - return resolve.sync(newFilename, { - ...resolveOptions, - // we already know that there is an extension at this point, so no need to check other extensions - extensions: [], - }) - } -} diff --git a/packages/framework-react/src/plugins/react-docgen-typescript/README.md b/packages/framework-react/src/plugins/react-docgen-typescript/README.md new file mode 100644 index 00000000..838e1720 --- /dev/null +++ b/packages/framework-react/src/plugins/react-docgen-typescript/README.md @@ -0,0 +1,20 @@ +# The code in this directory is copied and modified from [@joshwooding/vite-plugin-react-docgen-typescript](https://github.com/joshwooding/vite-plugin-react-docgen-typescript/tree/bf0ea3a603fb388bc28104c65aea49beb236aa6c) under MIT license. + +# @joshwooding/vite-plugin-react-docgen-typescript + +[![npm](https://img.shields.io/npm/v/@joshwooding/vite-plugin-react-docgen-typescript.svg)](https://www.npmjs.com/package/@joshwooding/vite-plugin-react-docgen-typescript) +[![Code style: Prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier) + +> A vite plugin to inject react typescript docgen information + +  + +### Usage + +```ts +import reactDocgenTypescript from '@joshwooding/vite-plugin-react-docgen-typescript' + +export default { + plugins: [reactDocgenTypescript()], +} +``` diff --git a/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/DefaultExport.tsx b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/DefaultExport.tsx new file mode 100644 index 00000000..b2303992 --- /dev/null +++ b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/DefaultExport.tsx @@ -0,0 +1,15 @@ +import * as React from 'react' + +interface DefaultExportComponentProps { + /** Button color. */ + color: 'blue' | 'green' +} + +/** + * A simple component. + */ +const DefaultExportComponent: React.FC = ( + props, +) => + +export default DefaultExportComponent diff --git a/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/DefaultExportWithDisplayName.tsx b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/DefaultExportWithDisplayName.tsx new file mode 100644 index 00000000..7e1f06a2 --- /dev/null +++ b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/DefaultExportWithDisplayName.tsx @@ -0,0 +1,17 @@ +import * as React from 'react' + +interface DefaultExportComponentProps { + /** Button color. */ + color: 'blue' | 'green' +} + +/** + * A simple component. + */ +const DefaultExportComponent: React.FC = ( + props, +) => + +DefaultExportComponent.displayName = 'DefaultExportComponentWithDisplayName' + +export default DefaultExportComponent diff --git a/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/DefaultPropValue.tsx b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/DefaultPropValue.tsx new file mode 100644 index 00000000..87fdfb40 --- /dev/null +++ b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/DefaultPropValue.tsx @@ -0,0 +1,37 @@ +import * as React from 'react' + +interface DefaultPropValueComponentProps { + /** + * Button color. + * + * @default blue + **/ + color: 'blue' | 'green' + + /** + * Button counter. + */ + counter: number + + /** + * Button disabled. + */ + disabled: boolean +} + +/** + * Component with a prop with a default value. + */ +export const DefaultPropValueComponent: React.FC< + DefaultPropValueComponentProps +> = (props) => ( + +) + +DefaultPropValueComponent.defaultProps = { + counter: 123, + disabled: false, +} diff --git a/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/HyphenatedPropName.tsx b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/HyphenatedPropName.tsx new file mode 100644 index 00000000..2725f3dd --- /dev/null +++ b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/HyphenatedPropName.tsx @@ -0,0 +1,17 @@ +import * as React from 'react' + +interface HyphenatedPropNameProps { + /** Button color. */ + 'button-color': 'blue' | 'green' +} + +/** + * A component with a hyphenated prop name. + */ +export const HyphenatedPropNameComponent: React.FC = ( + props, +) => ( + +) diff --git a/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/MultiProps.tsx b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/MultiProps.tsx new file mode 100644 index 00000000..4b12b821 --- /dev/null +++ b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/MultiProps.tsx @@ -0,0 +1,16 @@ +import * as React from 'react' + +interface MultiPropsComponentProps { + /** Button color. */ + color: 'blue' | 'green' + + /** Button size. */ + size: 'small' | 'large' +} + +/** + * This is a component with multiple props. + */ +export const MultiPropsComponent: React.FC = ( + props, +) => diff --git a/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/MultilineDescription.tsx b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/MultilineDescription.tsx new file mode 100644 index 00000000..4a486221 --- /dev/null +++ b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/MultilineDescription.tsx @@ -0,0 +1,17 @@ +import * as React from 'react' + +interface MultilineDescriptionProps { + /** Button color. */ + color: 'blue' | 'green' +} + +/** + * A component with a multiline description. + * + * Second line. + */ +export const MultilineDescriptionComponent: React.FC< + MultilineDescriptionProps +> = (props) => ( + +) diff --git a/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/MultilinePropDescription.tsx b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/MultilinePropDescription.tsx new file mode 100644 index 00000000..0f46e553 --- /dev/null +++ b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/MultilinePropDescription.tsx @@ -0,0 +1,19 @@ +import * as React from 'react' + +interface MultilinePropDescriptionComponentProps { + /** + * This is a multiline prop description. + * + * Second line. + */ + color: 'blue' | 'green' +} + +/** + * A component with multiline prop description. + */ +export const MultilinePropDescriptionComponent: React.FC< + MultilinePropDescriptionComponentProps +> = (props) => ( + +) diff --git a/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/Simple.tsx b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/Simple.tsx new file mode 100644 index 00000000..38dbd219 --- /dev/null +++ b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/Simple.tsx @@ -0,0 +1,13 @@ +import * as React from 'react' + +interface SimpleComponentProps { + /** Button color. */ + color: 'blue' | 'green' +} + +/** + * A simple component. + */ +export const SimpleComponent: React.FC = (props) => ( + +) diff --git a/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/SimpleWithDisplayName.tsx b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/SimpleWithDisplayName.tsx new file mode 100644 index 00000000..ce2b0266 --- /dev/null +++ b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/SimpleWithDisplayName.tsx @@ -0,0 +1,15 @@ +import * as React from 'react' + +interface SimpleComponentProps { + /** Button color. */ + color: 'blue' | 'green' +} + +/** + * A simple component. + */ +export const SimpleComponent: React.FC = (props) => ( + +) + +SimpleComponent.displayName = 'SimpleComponentWithDisplayName' diff --git a/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/TextOnlyComponent.tsx b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/TextOnlyComponent.tsx new file mode 100644 index 00000000..52a3feab --- /dev/null +++ b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__fixtures__/TextOnlyComponent.tsx @@ -0,0 +1,10 @@ +import * as React from 'react' + +/** + * A component with only text content wrapped in a div. + * + * Ref: https://github.com/strothj/react-docgen-typescript-loader/issues/7 + */ +export const SimpleComponent: React.FC> = () => ( +
Test only component
+) diff --git a/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__snapshots__/index.test.ts.snap b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__snapshots__/index.test.ts.snap new file mode 100644 index 00000000..ad6ef678 --- /dev/null +++ b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/__snapshots__/index.test.ts.snap @@ -0,0 +1,456 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`component fixture > DefaultExport.tsx has code block generated 1`] = ` +{ + "code": "import * as React from 'react' + +interface DefaultExportComponentProps { + /** Button color. */ + color: 'blue' | 'green' +} + +/** + * A simple component. + */ +const DefaultExportComponent: React.FC = ( + props, +) => + +export default DefaultExportComponent +try { + // @ts-ignore + DefaultExport.displayName = "DefaultExport"; + // @ts-ignore + DefaultExport.__docgenInfo = { "description": "A simple component.", "displayName": "DefaultExport", "props": { "color": { "defaultValue": null, "description": "Button color.", "name": "color", "required": true, "type": { "name": "\\"blue\\" | \\"green\\"" } } } }; +} +catch (__react_docgen_typescript_loader_error) { }", + "map": SourceMap { + "file": undefined, + "mappings": "AAAA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;", + "names": [], + "sources": [ + "", + ], + "sourcesContent": undefined, + "version": 3, + }, +} +`; + +exports[`component fixture > DefaultExportWithDisplayName.tsx has code block generated 1`] = ` +{ + "code": "import * as React from 'react' + +interface DefaultExportComponentProps { + /** Button color. */ + color: 'blue' | 'green' +} + +/** + * A simple component. + */ +const DefaultExportComponent: React.FC = ( + props, +) => + +DefaultExportComponent.displayName = 'DefaultExportComponentWithDisplayName' + +export default DefaultExportComponent +try { + // @ts-ignore + DefaultExportComponentWithDisplayName.displayName = "DefaultExportComponentWithDisplayName"; + // @ts-ignore + DefaultExportComponentWithDisplayName.__docgenInfo = { "description": "A simple component.", "displayName": "DefaultExportComponentWithDisplayName", "props": { "color": { "defaultValue": null, "description": "Button color.", "name": "color", "required": true, "type": { "name": "\\"blue\\" | \\"green\\"" } } } }; +} +catch (__react_docgen_typescript_loader_error) { }", + "map": SourceMap { + "file": undefined, + "mappings": "AAAA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;", + "names": [], + "sources": [ + "", + ], + "sourcesContent": undefined, + "version": 3, + }, +} +`; + +exports[`component fixture > DefaultPropValue.tsx has code block generated 1`] = ` +{ + "code": "import * as React from 'react' + +interface DefaultPropValueComponentProps { + /** + * Button color. + * + * @default blue + **/ + color: 'blue' | 'green' + + /** + * Button counter. + */ + counter: number + + /** + * Button disabled. + */ + disabled: boolean +} + +/** + * Component with a prop with a default value. + */ +export const DefaultPropValueComponent: React.FC< + DefaultPropValueComponentProps +> = (props) => ( + +) + +DefaultPropValueComponent.defaultProps = { + counter: 123, + disabled: false, +} +try { + // @ts-ignore + DefaultPropValueComponent.displayName = "DefaultPropValueComponent"; + // @ts-ignore + DefaultPropValueComponent.__docgenInfo = { "description": "Component with a prop with a default value.", "displayName": "DefaultPropValueComponent", "props": { "color": { "defaultValue": { value: "blue" }, "description": "Button color.", "name": "color", "required": true, "type": { "name": "\\"blue\\" | \\"green\\"" } }, "counter": { "defaultValue": { value: 123 }, "description": "Button counter.", "name": "counter", "required": false, "type": { "name": "number" } }, "disabled": { "defaultValue": { value: false }, "description": "Button disabled.", "name": "disabled", "required": false, "type": { "name": "boolean" } } } }; +} +catch (__react_docgen_typescript_loader_error) { }", + "map": SourceMap { + "file": undefined, + "mappings": "AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;", + "names": [], + "sources": [ + "", + ], + "sourcesContent": undefined, + "version": 3, + }, +} +`; + +exports[`component fixture > HyphenatedPropName.tsx has code block generated 1`] = ` +{ + "code": "import * as React from 'react' + +interface HyphenatedPropNameProps { + /** Button color. */ + 'button-color': 'blue' | 'green' +} + +/** + * A component with a hyphenated prop name. + */ +export const HyphenatedPropNameComponent: React.FC = ( + props, +) => ( + +) +try { + // @ts-ignore + HyphenatedPropNameComponent.displayName = "HyphenatedPropNameComponent"; + // @ts-ignore + HyphenatedPropNameComponent.__docgenInfo = { "description": "A component with a hyphenated prop name.", "displayName": "HyphenatedPropNameComponent", "props": { "button-color": { "defaultValue": null, "description": "Button color.", "name": "button-color", "required": true, "type": { "name": "\\"blue\\" | \\"green\\"" } } } }; +} +catch (__react_docgen_typescript_loader_error) { }", + "map": SourceMap { + "file": undefined, + "mappings": "AAAA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;", + "names": [], + "sources": [ + "", + ], + "sourcesContent": undefined, + "version": 3, + }, +} +`; + +exports[`component fixture > MultiProps.tsx has code block generated 1`] = ` +{ + "code": "import * as React from 'react' + +interface MultiPropsComponentProps { + /** Button color. */ + color: 'blue' | 'green' + + /** Button size. */ + size: 'small' | 'large' +} + +/** + * This is a component with multiple props. + */ +export const MultiPropsComponent: React.FC = ( + props, +) => +try { + // @ts-ignore + MultiPropsComponent.displayName = "MultiPropsComponent"; + // @ts-ignore + MultiPropsComponent.__docgenInfo = { "description": "This is a component with multiple props.", "displayName": "MultiPropsComponent", "props": { "color": { "defaultValue": null, "description": "Button color.", "name": "color", "required": true, "type": { "name": "\\"blue\\" | \\"green\\"" } }, "size": { "defaultValue": null, "description": "Button size.", "name": "size", "required": true, "type": { "name": "\\"small\\" | \\"large\\"" } } } }; +} +catch (__react_docgen_typescript_loader_error) { }", + "map": SourceMap { + "file": undefined, + "mappings": "AAAA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;", + "names": [], + "sources": [ + "", + ], + "sourcesContent": undefined, + "version": 3, + }, +} +`; + +exports[`component fixture > MultilineDescription.tsx has code block generated 1`] = ` +{ + "code": "import * as React from 'react' + +interface MultilineDescriptionProps { + /** Button color. */ + color: 'blue' | 'green' +} + +/** + * A component with a multiline description. + * + * Second line. + */ +export const MultilineDescriptionComponent: React.FC< + MultilineDescriptionProps +> = (props) => ( + +) +try { + // @ts-ignore + MultilineDescriptionComponent.displayName = "MultilineDescriptionComponent"; + // @ts-ignore + MultilineDescriptionComponent.__docgenInfo = { "description": "A component with a multiline description.\\n\\nSecond line.", "displayName": "MultilineDescriptionComponent", "props": { "color": { "defaultValue": null, "description": "Button color.", "name": "color", "required": true, "type": { "name": "\\"blue\\" | \\"green\\"" } } } }; +} +catch (__react_docgen_typescript_loader_error) { }", + "map": SourceMap { + "file": undefined, + "mappings": "AAAA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;", + "names": [], + "sources": [ + "", + ], + "sourcesContent": undefined, + "version": 3, + }, +} +`; + +exports[`component fixture > MultilinePropDescription.tsx has code block generated 1`] = ` +{ + "code": "import * as React from 'react' + +interface MultilinePropDescriptionComponentProps { + /** + * This is a multiline prop description. + * + * Second line. + */ + color: 'blue' | 'green' +} + +/** + * A component with multiline prop description. + */ +export const MultilinePropDescriptionComponent: React.FC< + MultilinePropDescriptionComponentProps +> = (props) => ( + +) +try { + // @ts-ignore + MultilinePropDescriptionComponent.displayName = "MultilinePropDescriptionComponent"; + // @ts-ignore + MultilinePropDescriptionComponent.__docgenInfo = { "description": "A component with multiline prop description.", "displayName": "MultilinePropDescriptionComponent", "props": { "color": { "defaultValue": null, "description": "This is a multiline prop description.\\n\\nSecond line.", "name": "color", "required": true, "type": { "name": "\\"blue\\" | \\"green\\"" } } } }; +} +catch (__react_docgen_typescript_loader_error) { }", + "map": SourceMap { + "file": undefined, + "mappings": "AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;", + "names": [], + "sources": [ + "", + ], + "sourcesContent": undefined, + "version": 3, + }, +} +`; + +exports[`component fixture > Simple.tsx has code block generated 1`] = ` +{ + "code": "import * as React from 'react' + +interface SimpleComponentProps { + /** Button color. */ + color: 'blue' | 'green' +} + +/** + * A simple component. + */ +export const SimpleComponent: React.FC = (props) => ( + +) +try { + // @ts-ignore + SimpleComponent.displayName = "SimpleComponent"; + // @ts-ignore + SimpleComponent.__docgenInfo = { "description": "A simple component.", "displayName": "SimpleComponent", "props": { "color": { "defaultValue": null, "description": "Button color.", "name": "color", "required": true, "type": { "name": "\\"blue\\" | \\"green\\"" } } } }; +} +catch (__react_docgen_typescript_loader_error) { }", + "map": SourceMap { + "file": undefined, + "mappings": "AAAA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;", + "names": [], + "sources": [ + "", + ], + "sourcesContent": undefined, + "version": 3, + }, +} +`; + +exports[`component fixture > SimpleWithDisplayName.tsx has code block generated 1`] = ` +{ + "code": "import * as React from 'react' + +interface SimpleComponentProps { + /** Button color. */ + color: 'blue' | 'green' +} + +/** + * A simple component. + */ +export const SimpleComponent: React.FC = (props) => ( + +) + +SimpleComponent.displayName = 'SimpleComponentWithDisplayName' +try { + // @ts-ignore + SimpleComponentWithDisplayName.displayName = "SimpleComponentWithDisplayName"; + // @ts-ignore + SimpleComponentWithDisplayName.__docgenInfo = { "description": "A simple component.", "displayName": "SimpleComponentWithDisplayName", "props": { "color": { "defaultValue": null, "description": "Button color.", "name": "color", "required": true, "type": { "name": "\\"blue\\" | \\"green\\"" } } } }; +} +catch (__react_docgen_typescript_loader_error) { }", + "map": SourceMap { + "file": undefined, + "mappings": "AAAA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;", + "names": [], + "sources": [ + "", + ], + "sourcesContent": undefined, + "version": 3, + }, +} +`; + +exports[`component fixture > TextOnlyComponent.tsx has code block generated 1`] = ` +{ + "code": "import * as React from 'react' + +/** + * A component with only text content wrapped in a div. + * + * Ref: https://github.com/strothj/react-docgen-typescript-loader/issues/7 + */ +export const SimpleComponent: React.FC> = () => ( +
Test only component
+) +try { + // @ts-ignore + SimpleComponent.displayName = "SimpleComponent"; + // @ts-ignore + SimpleComponent.__docgenInfo = { "description": "A component with only text content wrapped in a div.\\n\\nRef: https://github.com/strothj/react-docgen-typescript-loader/issues/7", "displayName": "SimpleComponent", "props": {} }; +} +catch (__react_docgen_typescript_loader_error) { }", + "map": SourceMap { + "file": undefined, + "mappings": "AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;", + "names": [], + "sources": [ + "", + ], + "sourcesContent": undefined, + "version": 3, + }, +} +`; + +exports[`generates value info for enums 1`] = ` +{ + "code": "import * as React from 'react' + +interface DefaultPropValueComponentProps { + /** + * Button color. + * + * @default blue + **/ + color: 'blue' | 'green' + + /** + * Button counter. + */ + counter: number + + /** + * Button disabled. + */ + disabled: boolean +} + +/** + * Component with a prop with a default value. + */ +export const DefaultPropValueComponent: React.FC< + DefaultPropValueComponentProps +> = (props) => ( + +) + +DefaultPropValueComponent.defaultProps = { + counter: 123, + disabled: false, +} +try { + // @ts-ignore + DefaultPropValueComponent.displayName = "DefaultPropValueComponent"; + // @ts-ignore + DefaultPropValueComponent.__docgenInfo = { "description": "Component with a prop with a default value.", "displayName": "DefaultPropValueComponent", "props": { "color": { "defaultValue": { value: "blue" }, "description": "Button color.", "name": "color", "required": true, "type": { "name": "enum", "value": [{ "value": "\\"blue\\"" }, { "value": "\\"green\\"" }] } }, "counter": { "defaultValue": { value: 123 }, "description": "Button counter.", "name": "counter", "required": false, "type": { "name": "number" } }, "disabled": { "defaultValue": { value: false }, "description": "Button disabled.", "name": "disabled", "required": false, "type": { "name": "boolean" } } } }; +} +catch (__react_docgen_typescript_loader_error) { }", + "map": SourceMap { + "file": undefined, + "mappings": "AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;", + "names": [], + "sources": [ + "", + ], + "sourcesContent": undefined, + "version": 3, + }, +} +`; diff --git a/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/index.test.ts b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/index.test.ts new file mode 100644 index 00000000..66db9365 --- /dev/null +++ b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/index.test.ts @@ -0,0 +1,76 @@ +import { readFileSync, readdirSync } from 'node:fs' +import { basename, join, resolve } from 'node:path' +import { describe, expect, it } from 'vitest' +import reactDocgenTypescript from '../index' + +const tsconfigPathForTest = resolve(__dirname, 'tsconfig.test.json') +const fixturesPath = resolve(__dirname, '__fixtures__') + +const fixtureTests = readdirSync(fixturesPath) + .map((filename) => join(fixturesPath, filename)) + .map((filename) => ({ + id: filename, + code: readFileSync(filename, 'utf-8'), + })) + +const defaultPropValueFixture = fixtureTests.find( + (f) => basename(f.id) === 'DefaultPropValue.tsx', +) + +// A simple mocked Rsbuild hook api to get test result. +const createMockApi = (fixture: any) => { + const preHandlers: any[] = [] + let resultHandler: any + + const api = { + modifyRsbuildConfig: async (fn: any) => { + preHandlers.push(fn) + }, + transform: async (filter: any, handler: any) => { + resultHandler = handler + }, + onCloseBuild: () => {}, + } + + const runTasks = async () => { + for (const handler of preHandlers) { + await handler() + } + + const res = await resultHandler({ + code: fixture.code, + resource: fixture.id, + }) + + return res + } + + return { api, runTasks } +} + +describe('component fixture', () => { + for (const fixture of fixtureTests) { + it(`${basename(fixture.id)} has code block generated`, async () => { + const plugin = reactDocgenTypescript({ + tsconfigPath: tsconfigPathForTest, + }) + + const { api, runTasks } = createMockApi(fixture) + plugin.setup(api as any) + const res = await runTasks() + expect(res).toMatchSnapshot() + }) + } +}) + +it('generates value info for enums', async () => { + const plugin = reactDocgenTypescript({ + tsconfigPath: tsconfigPathForTest, + shouldExtractLiteralValuesFromEnum: true, + }) + + const { api, runTasks } = createMockApi(defaultPropValueFixture) + plugin.setup(api as any) + const res = await runTasks() + expect(res).toMatchSnapshot() +}) diff --git a/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/tsconfig.test.json b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/tsconfig.test.json new file mode 100644 index 00000000..ec601b49 --- /dev/null +++ b/packages/framework-react/src/plugins/react-docgen-typescript/__tests__/tsconfig.test.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ES2018", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + "moduleResolution": "Bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "esModuleInterop": true, + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true, + "strictNullChecks": true + }, + "include": ["./**/*"], + "exclude": [] +} diff --git a/packages/framework-react/src/plugins/react-docgen-typescript/index.ts b/packages/framework-react/src/plugins/react-docgen-typescript/index.ts new file mode 100644 index 00000000..10b7facc --- /dev/null +++ b/packages/framework-react/src/plugins/react-docgen-typescript/index.ts @@ -0,0 +1,159 @@ +import { createFilter } from '@rollup/pluginutils' +import type { RsbuildPlugin } from '@rsbuild/core' +import type { FileParser } from 'react-docgen-typescript' +import type { CompilerOptions, Program } from 'typescript' +import { defaultPropFilter } from './utils/filter' +import type { Options } from './utils/options' + +type Filepath = string +type InvalidateModule = () => void +type CloseWatch = () => void + +const getDocgen = async (config: Options) => { + const docGen = await import('react-docgen-typescript') + + const { + tsconfigPath, + compilerOptions, + propFilter = defaultPropFilter, + setDisplayName, + typePropName, + ...rest + } = config + + const docgenOptions = { + propFilter, + ...rest, + } + + return docGen.withCompilerOptions( + // Compiler Options are passed in to the custom program. + {}, + docgenOptions, + ) +} + +const startWatch = async ( + config: Options, + onProgramCreatedOrUpdated: (program: Program) => void, +) => { + const { default: ts } = await import('typescript') + const { getTSConfigFile } = await import('./utils/typescript') + + let compilerOptions: CompilerOptions = { + jsx: ts.JsxEmit.React, + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.Latest, + } + + const tsconfigPath = config.tsconfigPath ?? './tsconfig.json' + + if (config.compilerOptions) { + compilerOptions = { + ...compilerOptions, + ...config.compilerOptions, + } + } else { + const { options: tsOptions } = getTSConfigFile(tsconfigPath) + compilerOptions = { ...compilerOptions, ...tsOptions } + } + + const host = ts.createWatchCompilerHost( + tsconfigPath, + compilerOptions, + ts.sys, + ts.createSemanticDiagnosticsBuilderProgram, + undefined, + () => { + /* suppress message */ + }, + ) + host.afterProgramCreate = (program) => { + onProgramCreatedOrUpdated(program.getProgram()) + } + + return new Promise<[Program, CloseWatch]>((resolve) => { + const watch = ts.createWatchProgram(host) + resolve([watch.getProgram().getProgram(), watch.close]) + }) +} + +export default (config: Options = {}): RsbuildPlugin => { + let tsProgram: Program + let docGenParser: FileParser + // biome-ignore format: prevent trailing commas being added. + let generateDocgenCodeBlock: typeof import( + "./utils/generate" + )["generateDocgenCodeBlock"]; + let generateOptions: ReturnType< + typeof import('./utils/options')['getGenerateOptions'] + > + let filter: ReturnType + const moduleInvalidationQueue: Map = new Map() + let closeWatch: CloseWatch + + return { + name: 'rsbuild-plugin-react-docgen-typescript', + setup(api) { + api.modifyRsbuildConfig(async () => { + const { getGenerateOptions } = await import('./utils/options') + generateDocgenCodeBlock = (await import('./utils/generate')) + .generateDocgenCodeBlock + + docGenParser = await getDocgen(config) + generateOptions = getGenerateOptions(config) + ;[tsProgram, closeWatch] = await startWatch(config, (program) => { + tsProgram = program + + for (const [ + filepath, + invalidateModule, + ] of moduleInvalidationQueue.entries()) { + invalidateModule() + moduleInvalidationQueue.delete(filepath) + } + }) + + filter = createFilter( + config.include ?? ['**/**.tsx'], + config.exclude ?? ['**/**.stories.tsx'], + ) + }) + + api.transform( + { + test: (id) => { + return filter(id) + }, + }, + async ({ code: src, resource: id }) => { + try { + const componentDocs = docGenParser.parseWithProgramProvider( + id, + () => tsProgram, + ) + + if (!componentDocs.length) { + return { code: src } + } + + const res = generateDocgenCodeBlock({ + filename: id, + source: src, + componentDocs, + ...generateOptions, + }) + + return res + } catch (e) { + return src + } + }, + ) + + api.onCloseBuild(() => { + closeWatch() + }) + }, + } +} diff --git a/packages/framework-react/src/plugins/react-docgen-typescript/utils/filter.ts b/packages/framework-react/src/plugins/react-docgen-typescript/utils/filter.ts new file mode 100644 index 00000000..385ba6f2 --- /dev/null +++ b/packages/framework-react/src/plugins/react-docgen-typescript/utils/filter.ts @@ -0,0 +1,5 @@ +import type { PropFilter } from 'react-docgen-typescript/lib/parser' + +export const defaultPropFilter: PropFilter = (prop) => { + return !prop.parent?.fileName.includes('node_modules') +} diff --git a/packages/framework-react/src/plugins/react-docgen-typescript/utils/generate.ts b/packages/framework-react/src/plugins/react-docgen-typescript/utils/generate.ts new file mode 100644 index 00000000..4facdb69 --- /dev/null +++ b/packages/framework-react/src/plugins/react-docgen-typescript/utils/generate.ts @@ -0,0 +1,320 @@ +/** + * Copied from https://github.com/storybookjs/react-docgen-typescript-plugin/blob/74bb959f468fd6dee7cbc7c8b68cc01e4bcb343c/src/generateDocgenCodeBlock.ts + * But refactored to remove deprecated functions. + **/ + +import MagicString, { type SourceMap } from 'magic-string' +import type { ComponentDoc, PropItem } from 'react-docgen-typescript' +import ts from 'typescript' + +export interface GeneratorOptions { + filename: string + source: string + componentDocs: ComponentDoc[] + setDisplayName: boolean + typePropName: string +} + +function createLiteral( + value: string | number | boolean, +): ts.StringLiteral | ts.NumericLiteral | ts.BooleanLiteral { + switch (typeof value) { + case 'string': + return ts.factory.createStringLiteral(value) + case 'number': + return ts.factory.createNumericLiteral(value) + case 'boolean': + return value ? ts.factory.createTrue() : ts.factory.createFalse() + } +} + +/** + * Inserts a ts-ignore comment above the supplied statement. + * + * It is used to work around type errors related to fields like __docgenInfo not + * being defined on types. It also prevents compile errors related to attempting + * to assign to nonexistent components, which can happen due to incorrect + * detection of component names when using the parser. + * ``` + * // @ts-ignore + * ``` + * @param statement + */ +function insertTsIgnoreBeforeStatement(statement: ts.Statement): ts.Statement { + ts.setSyntheticLeadingComments(statement, [ + { + text: ' @ts-ignore', // Leading space is important here + kind: ts.SyntaxKind.SingleLineCommentTrivia, + pos: -1, + end: -1, + }, + ]) + return statement +} + +/** + * Set component display name. + * + * ``` + * SimpleComponent.displayName = "SimpleComponent"; + * ``` + */ +function setDisplayName(d: ComponentDoc): ts.Statement { + return insertTsIgnoreBeforeStatement( + ts.factory.createExpressionStatement( + ts.factory.createBinaryExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(d.displayName), + ts.factory.createIdentifier('displayName'), + ), + ts.SyntaxKind.EqualsToken, + ts.factory.createStringLiteral(d.displayName), + ), + ), + ) +} + +/** + * Set a component prop description. + * ``` + * SimpleComponent.__docgenInfo.props.someProp = { + * defaultValue: "blue", + * description: "Prop description.", + * name: "someProp", + * required: true, + * type: "'blue' | 'green'", + * } + * ``` + * + * @param propName Prop name + * @param prop Prop definition from `ComponentDoc.props` + * @param options Generator options. + */ +function createPropDefinition( + propName: string, + prop: PropItem, + options: GeneratorOptions, +) { + /** + * Set default prop value. + * + * ``` + * SimpleComponent.__docgenInfo.props.someProp.defaultValue = null; + * SimpleComponent.__docgenInfo.props.someProp.defaultValue = { + * value: "blue", + * }; + * ``` + * + * @param defaultValue Default prop value or null if not set. + */ + const setDefaultValue = (defaultValue: { value: unknown } | null) => + ts.factory.createPropertyAssignment( + ts.factory.createStringLiteral('defaultValue'), + // Use a more extensive check on defaultValue. Sometimes the parser + // returns an empty object. + defaultValue?.value !== undefined && + (typeof defaultValue.value === 'string' || + typeof defaultValue.value === 'number' || + typeof defaultValue.value === 'boolean') + ? ts.factory.createObjectLiteralExpression([ + ts.factory.createPropertyAssignment( + ts.factory.createIdentifier('value'), + createLiteral(defaultValue.value), + ), + ]) + : ts.factory.createNull(), + ) + + /** Set a property with a string value */ + const setStringLiteralField = (fieldName: string, fieldValue: string) => + ts.factory.createPropertyAssignment( + ts.factory.createStringLiteral(fieldName), + ts.factory.createStringLiteral(fieldValue), + ) + + /** + * ``` + * SimpleComponent.__docgenInfo.props.someProp.description = "Prop description."; + * ``` + * @param description Prop description. + */ + const setDescription = (description: string) => + setStringLiteralField('description', description) + + /** + * ``` + * SimpleComponent.__docgenInfo.props.someProp.name = "someProp"; + * ``` + * @param name Prop name. + */ + const setName = (name: string) => setStringLiteralField('name', name) + + /** + * ``` + * SimpleComponent.__docgenInfo.props.someProp.required = true; + * ``` + * @param required Whether prop is required or not. + */ + const setRequired = (required: boolean) => + ts.factory.createPropertyAssignment( + ts.factory.createStringLiteral('required'), + required ? ts.factory.createTrue() : ts.factory.createFalse(), + ) + + /** + * ``` + * SimpleComponent.__docgenInfo.props.someProp.type = { + * name: "enum", + * value: [ { value: "\"blue\"" }, { value: "\"green\""} ] + * } + * ``` + * @param [typeValue] Prop value (for enums) + */ + const setValue = (typeValue?: any[]) => + Array.isArray(typeValue) && + typeValue.every((value) => typeof value.value === 'string') + ? ts.factory.createPropertyAssignment( + ts.factory.createStringLiteral('value'), + ts.factory.createArrayLiteralExpression( + typeValue.map((value) => + ts.factory.createObjectLiteralExpression([ + setStringLiteralField('value', value.value), + ]), + ), + ), + ) + : undefined + + /** + * ``` + * SimpleComponent.__docgenInfo.props.someProp.type = { name: "'blue' | 'green'"} + * ``` + * @param typeName Prop type name. + * @param [typeValue] Prop value (for enums) + */ + const setType = (typeName: string, typeValue?: unknown[]) => { + const objectFields = [setStringLiteralField('name', typeName)] + const valueField = setValue(typeValue) + + if (valueField) { + objectFields.push(valueField) + } + + return ts.factory.createPropertyAssignment( + ts.factory.createStringLiteral(options.typePropName), + ts.factory.createObjectLiteralExpression(objectFields), + ) + } + + return ts.factory.createPropertyAssignment( + ts.factory.createStringLiteral(propName), + ts.factory.createObjectLiteralExpression([ + setDefaultValue(prop.defaultValue), + setDescription(prop.description), + setName(prop.name), + setRequired(prop.required), + setType(prop.type.name, prop.type.value), + ]), + ) +} + +/** + * Sets the field `__docgenInfo` for the component specified by the component + * doc with the docgen information. + * + * ``` + * SimpleComponent.__docgenInfo = { + * description: ..., + * displayName: ..., + * props: ..., + * } + * ``` + * + * @param d Component doc. + * @param options Generator options. + */ +function setComponentDocGen( + d: ComponentDoc, + options: GeneratorOptions, +): ts.Statement { + return insertTsIgnoreBeforeStatement( + ts.factory.createExpressionStatement( + ts.factory.createBinaryExpression( + // SimpleComponent.__docgenInfo + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier(d.displayName), + ts.factory.createIdentifier('__docgenInfo'), + ), + ts.SyntaxKind.EqualsToken, + ts.factory.createObjectLiteralExpression([ + // SimpleComponent.__docgenInfo.description + ts.factory.createPropertyAssignment( + ts.factory.createStringLiteral('description'), + ts.factory.createStringLiteral(d.description), + ), + // SimpleComponent.__docgenInfo.displayName + ts.factory.createPropertyAssignment( + ts.factory.createStringLiteral('displayName'), + ts.factory.createStringLiteral(d.displayName), + ), + // SimpleComponent.__docgenInfo.props + ts.factory.createPropertyAssignment( + ts.factory.createStringLiteral('props'), + ts.factory.createObjectLiteralExpression( + Object.entries(d.props).map(([propName, prop]) => + createPropDefinition(propName, prop, options), + ), + ), + ), + ]), + ), + ), + ) +} + +export function generateDocgenCodeBlock(options: GeneratorOptions): { + code: string + map: SourceMap +} { + const sourceFile = ts.createSourceFile( + options.filename, + options.source, + ts.ScriptTarget.ESNext, + ) + + const wrapInTryStatement = (statements: ts.Statement[]): ts.TryStatement => + ts.factory.createTryStatement( + ts.factory.createBlock(statements, true), + ts.factory.createCatchClause( + ts.factory.createVariableDeclaration( + ts.factory.createIdentifier('__react_docgen_typescript_loader_error'), + ), + ts.factory.createBlock([]), + ), + undefined, + ) + + const codeBlocks = options.componentDocs.map((d) => + wrapInTryStatement( + [ + options.setDisplayName ? setDisplayName(d) : null, + setComponentDocGen(d, options), + ].filter((s) => s !== null) as ts.Statement[], + ), + ) + + const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }) + const printNode = (sourceNode: ts.Node) => + printer.printNode(ts.EmitHint.Unspecified, sourceNode, sourceFile) + + const s = new MagicString(options.source) + + for (const node of codeBlocks) { + s.append(printNode(node)) + } + + return { + code: s.toString(), + map: s.generateMap(), + } +} diff --git a/packages/framework-react/src/plugins/react-docgen-typescript/utils/options.ts b/packages/framework-react/src/plugins/react-docgen-typescript/utils/options.ts new file mode 100644 index 00000000..dc1b8037 --- /dev/null +++ b/packages/framework-react/src/plugins/react-docgen-typescript/utils/options.ts @@ -0,0 +1,59 @@ +import type { ParserOptions } from 'react-docgen-typescript' +import type { CompilerOptions } from 'typescript' +import type { GeneratorOptions } from './generate' + +interface LoaderOptions { + /** + * Automatically set the component's display name. If you want to set display + * names yourself or are using another plugin to do this, you should disable + * this option. + * + * ``` + * class MyComponent extends React.Component { + * ... + * } + * + * MyComponent.displayName = "MyComponent"; + * ``` + * + * @default true + */ + setDisplayName?: boolean + + /** + * Specify the name of the property for docgen info prop type. + * + * @default "type" + */ + typePropName?: string +} + +interface TypescriptOptions { + /** + * Specify the location of the tsconfig.json to use. Can not be used with + * compilerOptions. + **/ + tsconfigPath?: string + /** Specify TypeScript compiler options. Can not be used with tsconfigPath. */ + compilerOptions?: CompilerOptions +} + +export type DocGenOptions = ParserOptions & { + /** Glob patterns to ignore */ + exclude?: string[] + /** Glob patterns to include. defaults to ts|tsx */ + include?: string[] +} + +export type Options = LoaderOptions & TypescriptOptions & DocGenOptions + +export function getGenerateOptions( + options: Options, +): Pick { + const { setDisplayName = true, typePropName = 'type' } = options + + return { + setDisplayName, + typePropName, + } +} diff --git a/packages/framework-react/src/plugins/react-docgen-typescript/utils/typescript.ts b/packages/framework-react/src/plugins/react-docgen-typescript/utils/typescript.ts new file mode 100644 index 00000000..b3d29e4f --- /dev/null +++ b/packages/framework-react/src/plugins/react-docgen-typescript/utils/typescript.ts @@ -0,0 +1,23 @@ +import { dirname } from 'node:path' +import ts from 'typescript' + +/** Get the contents of the tsconfig in the system */ + +export function getTSConfigFile( + tsconfigPath: string, +): Partial { + try { + const basePath = dirname(tsconfigPath) + const configFile = ts.readConfigFile(tsconfigPath, ts.sys.readFile) + + return ts.parseJsonConfigFileContent( + configFile.config, + ts.sys, + basePath, + {}, + tsconfigPath, + ) + } catch (error) { + return {} + } +} diff --git a/packages/framework-react/src/plugins/react-docgen.test.ts b/packages/framework-react/src/plugins/react-docgen.test.ts deleted file mode 100644 index 9e081ea9..00000000 --- a/packages/framework-react/src/plugins/react-docgen.test.ts +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Code taken from https://github.com/storybookjs/storybook/tree/next/code/frameworks/react-vite/src/plugins - */ - -import { describe, expect, it, vi } from 'vitest' -import { getReactDocgenImporter } from './react-docgen' - -const reactDocgenMock = vi.hoisted(() => { - return { - makeFsImporter: vi.fn().mockImplementation((fn) => fn), - } -}) - -const reactDocgenResolverMock = vi.hoisted(() => { - return { - defaultLookupModule: vi.fn(), - } -}) - -vi.mock('./docgen-resolver', async (importOriginal) => { - const actual = await importOriginal() - return { - ...actual, - defaultLookupModule: reactDocgenResolverMock.defaultLookupModule, - } -}) - -vi.mock('react-docgen', async (importOriginal) => { - const actual = await importOriginal() - return { - ...actual, - makeFsImporter: reactDocgenMock.makeFsImporter, - } -}) - -describe('getReactDocgenImporter function', () => { - it('should not map the request if a tsconfig path mapping is not available', () => { - const filename = './src/components/Button.tsx' - const basedir = '/src' - const imported = getReactDocgenImporter(undefined) - reactDocgenResolverMock.defaultLookupModule.mockImplementation( - (filen: string) => filen, - ) - const result = (imported as any)(filename, basedir) - expect(result).toBe(filename) - }) - - it('should map the request', () => { - const mappedFile = './mapped-file.tsx' - const matchPath = vi.fn().mockReturnValue(mappedFile) - const filename = './src/components/Button.tsx' - const basedir = '/src' - const imported = getReactDocgenImporter(matchPath) - reactDocgenResolverMock.defaultLookupModule.mockImplementation( - (filen: string) => filen, - ) - const result = (imported as any)(filename, basedir) - expect(result).toBe(mappedFile) - }) -}) diff --git a/packages/framework-react/src/plugins/react-docgen.ts b/packages/framework-react/src/plugins/react-docgen.ts deleted file mode 100644 index c5518916..00000000 --- a/packages/framework-react/src/plugins/react-docgen.ts +++ /dev/null @@ -1,139 +0,0 @@ -/** - * Code taken from https://github.com/storybookjs/storybook/tree/next/code/frameworks/react-vite/src/plugins - */ - -import path from 'node:path' -import { createFilter } from '@rollup/pluginutils' -import type { RsbuildPlugin } from '@rsbuild/core' -import findUp from 'find-up' -import MagicString from 'magic-string' -import type { Documentation } from 'react-docgen' -import { - // ERROR_CODES, - builtinHandlers as docgenHandlers, - builtinResolvers as docgenResolver, - makeFsImporter, - parse, -} from 'react-docgen' -import { logger } from 'storybook/internal/node-logger' -import * as TsconfigPaths from 'tsconfig-paths' -import actualNameHandler from './docgen-handlers/actualNameHandler' -import { - RESOLVE_EXTENSIONS, - ReactDocgenResolveError, - defaultLookupModule, -} from './docgen-resolver' - -type DocObj = Documentation & { actualName: string; definedInFile: string } - -// TODO: None of these are able to be overridden, so `default` is aspirational here. -const defaultHandlers = Object.values(docgenHandlers).map((handler) => handler) -const defaultResolver = new docgenResolver.FindExportedDefinitionsResolver() -const handlers = [...defaultHandlers, actualNameHandler] - -type Options = { - include?: string | RegExp | (string | RegExp)[] - exclude?: string | RegExp | (string | RegExp)[] -} - -export async function reactDocgen({ - include = /\.(mjs|tsx?|jsx?)$/, - exclude = [/node_modules\/.*/], -}: Options = {}): Promise { - const cwd = process.cwd() - const filter = createFilter(include, exclude) - - const tsconfigPath = await findUp('tsconfig.json', { cwd }) - const tsconfig = TsconfigPaths.loadConfig(tsconfigPath) - - let matchPath: TsconfigPaths.MatchPath | undefined - - if (tsconfig.resultType === 'success') { - logger.info('Using tsconfig paths for react-docgen') - matchPath = TsconfigPaths.createMatchPath( - tsconfig.absoluteBaseUrl, - tsconfig.paths, - ['browser', 'module', 'main'], - ) - } - - return { - name: 'storybook:react-docgen-plugin', - // enforce: 'pre', - setup(api) { - api.transform( - { - test: (id) => { - if (!filter(path.relative(cwd, id))) { - return false - } - - return true - }, - }, - async ({ code: src, resource: id }) => { - // return '' - // transform(src: string, id: string) { - // if (!filter(path.relative(cwd, id))) { - // return - // } - try { - const docgenResults = parse(src, { - resolver: defaultResolver, - handlers, - importer: getReactDocgenImporter(matchPath), - filename: id, - }) as DocObj[] - const s = new MagicString(src) - // biome-ignore lint/complexity/noForEach: - docgenResults.forEach((info) => { - const { actualName, definedInFile, ...docgenInfo } = info - // biome-ignore lint/suspicious/noDoubleEquals: - if (actualName && definedInFile == id) { - const docNode = JSON.stringify(docgenInfo) - s.append(`;${actualName}.__docgenInfo=${docNode}`) - } - }) - - return { - code: s.toString(), - map: s.generateMap({ hires: true, source: id }).toString(), - } - } catch (e: any) { - // Ignore the error when react-docgen cannot find a react component - // if (e.code === ERROR_CODES.MISSING_DEFINITION) { - - // Don't throw in any cases otherwise the watch will hang. - return src - // } - } - // } - }, - ) - }, - } -} - -export function getReactDocgenImporter( - matchPath: TsconfigPaths.MatchPath | undefined, -) { - return makeFsImporter((filename, basedir) => { - const mappedFilenameByPaths = (() => { - if (matchPath) { - const match = matchPath(filename) - return match || filename - // biome-ignore lint/style/noUselessElse: - } else { - return filename - } - })() - - const result = defaultLookupModule(mappedFilenameByPaths, basedir) - - if (RESOLVE_EXTENSIONS.find((ext) => result.endsWith(ext))) { - return result - } - - throw new ReactDocgenResolveError(filename) - }) -} diff --git a/packages/framework-react/src/react-docs.ts b/packages/framework-react/src/react-docs.ts index 74347b17..d4e41a6d 100644 --- a/packages/framework-react/src/react-docs.ts +++ b/packages/framework-react/src/react-docs.ts @@ -13,12 +13,13 @@ export const rsbuildFinalDocs: NonNullable< const typescriptOptions = await options.presets.apply('typescript', {} as any) const debug = options.loglevel === 'debug' - const { reactDocgen } = typescriptOptions || {} + const { reactDocgen, reactDocgenTypescriptOptions } = typescriptOptions || {} if (typeof reactDocgen !== 'string') { return config } + //#region react-docgen if (reactDocgen !== 'react-docgen-typescript') { return mergeRsbuildConfig(config, { tools: { @@ -43,27 +44,37 @@ export const rsbuildFinalDocs: NonNullable< }, }) } + //#endregion - const { reactDocgen: reactDocGenPlugin } = await import( - './plugins/react-docgen' - ) + //#region react-docgen-typescript + let typescriptPresent: boolean + try { + require.resolve('typescript') + typescriptPresent = true + } catch (e) { + typescriptPresent = false + } + + if (reactDocgen === 'react-docgen-typescript' && typescriptPresent) { + } + + const reactDocGenTsPlugin = await import('./plugins/react-docgen-typescript') // TODO: Rspack doesn't support the hooks `react-docgen-typescript`' required. // Currently, using `transform` hook to implement the same behavior. return mergeRsbuildConfig(config, { plugins: [ - await reactDocGenPlugin({ - include: - reactDocgen === 'react-docgen-typescript' - ? /\.(mjs|tsx?|jsx?)$/ - : /\.(mjs|jsx?)$/, + await reactDocGenTsPlugin.default({ + ...reactDocgenTypescriptOptions, + // We *need* this set so that RDT returns default values in the same format as react-docgen + savePropValueAsString: true, }), ], }) + //#endregion - // throw new Error( - // "Rspack didn't support the hooks `react-docgen-typescript`' required", - // ) + //#region webpack flavor react-docgen-typescript implementation, lacking support for hooks. + // it's now superseded by the `transform` hook implementation of Vite flavor. // const { ReactDocgenTypeScriptPlugin } = await import( // '@storybook/react-docgen-typescript-plugin' @@ -100,4 +111,5 @@ export const rsbuildFinalDocs: NonNullable< // }, // }, // }) + //#endregion } diff --git a/packages/framework-react/tsconfig.json b/packages/framework-react/tsconfig.json index 578565ee..a7df504e 100644 --- a/packages/framework-react/tsconfig.json +++ b/packages/framework-react/tsconfig.json @@ -5,5 +5,6 @@ "resolveJsonModule": true, "outDir": "dist" }, - "include": ["src/**/*"] + "include": ["src/**/*"], + "exclude": ["**/__tests__/**/*"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 34d253e7..bdb9bdd0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -223,6 +223,9 @@ importers: react-docgen: specifier: ^7.1.0 version: 7.1.0 + react-docgen-typescript: + specifier: ^2.2.2 + version: 2.2.2(typescript@5.7.3) resolve: specifier: ^1.22.10 version: 1.22.10 @@ -239,6 +242,9 @@ importers: '@storybook/types': specifier: 8.5.0-beta.8 version: 8.5.0-beta.8(storybook@8.5.0-beta.8(prettier@2.8.8)) + '@types/react': + specifier: ^18.3.18 + version: 18.3.18 '@types/resolve': specifier: ^1.20.6 version: 1.20.6 @@ -414,6 +420,9 @@ importers: sandboxes/react-18: dependencies: + antd: + specifier: ^5.23.2 + version: 5.23.2(luxon@3.5.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: specifier: 18.3.1 version: 18.3.1 @@ -852,6 +861,40 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} + '@ant-design/colors@7.2.0': + resolution: {integrity: sha512-bjTObSnZ9C/O8MB/B4OUtd/q9COomuJAR2SYfhxLyHvCKn4EKwCN3e+fWGMo7H5InAyV0wL17jdE9ALrdOW/6A==} + + '@ant-design/cssinjs-utils@1.1.3': + resolution: {integrity: sha512-nOoQMLW1l+xR1Co8NFVYiP8pZp3VjIIzqV6D6ShYF2ljtdwWJn5WSsH+7kvCktXL/yhEtWURKOfH5Xz/gzlwsg==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@ant-design/cssinjs@1.23.0': + resolution: {integrity: sha512-7GAg9bD/iC9ikWatU9ym+P9ugJhi/WbsTWzcKN6T4gU0aehsprtke1UAaaSxxkjjmkJb3llet/rbUSLPgwlY4w==} + peerDependencies: + react: '>=16.0.0' + react-dom: '>=16.0.0' + + '@ant-design/fast-color@2.0.6': + resolution: {integrity: sha512-y2217gk4NqL35giHl72o6Zzqji9O7vHh9YmhUVkPtAOpoTCH4uWxo/pr4VE8t0+ChEPs0qo4eJRC5Q1eXWo3vA==} + engines: {node: '>=8.x'} + + '@ant-design/icons-svg@4.4.2': + resolution: {integrity: sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==} + + '@ant-design/icons@5.6.0': + resolution: {integrity: sha512-Mb6QkQmPLZsmIHJ6oBsoyKrrT8/kAUdQ6+8q38e2bQSclROi69SiDlI4zZroaIPseae1w110RJH0zGrphAvlSQ==} + engines: {node: '>=8'} + peerDependencies: + react: '>=16.0.0' + react-dom: '>=16.0.0' + + '@ant-design/react-slick@1.1.2': + resolution: {integrity: sha512-EzlvzE6xQUBrZuuhSAFTdsr4P2bBBHGZwKFemEfq8gIGyIQCxalYfZW/T2ORbtQx5rU69o+WycP3exY/7T1hGA==} + peerDependencies: + react: '>=16.9.0' + '@babel/code-frame@7.26.2': resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} @@ -1536,8 +1579,8 @@ packages: '@babel/regjsgen@0.8.0': resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} - '@babel/runtime@7.24.5': - resolution: {integrity: sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==} + '@babel/runtime@7.26.0': + resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} engines: {node: '>=6.9.0'} '@babel/template@7.25.9': @@ -1692,6 +1735,12 @@ packages: '@emnapi/wasi-threads@1.0.1': resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==} + '@emotion/hash@0.8.0': + resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==} + + '@emotion/unitless@0.7.5': + resolution: {integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==} + '@esbuild/aix-ppc64@0.20.2': resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} engines: {node: '>=12'} @@ -2783,6 +2832,61 @@ packages: '@polka/url@1.0.0-next.28': resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} + '@rc-component/async-validator@5.0.4': + resolution: {integrity: sha512-qgGdcVIF604M9EqjNF0hbUTz42bz/RDtxWdWuU5EQe3hi7M8ob54B6B35rOsvX5eSvIHIzT9iH1R3n+hk3CGfg==} + engines: {node: '>=14.x'} + + '@rc-component/color-picker@2.0.1': + resolution: {integrity: sha512-WcZYwAThV/b2GISQ8F+7650r5ZZJ043E57aVBFkQ+kSY4C6wdofXgB0hBx+GPGpIU0Z81eETNoDUJMr7oy/P8Q==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/context@1.4.0': + resolution: {integrity: sha512-kFcNxg9oLRMoL3qki0OMxK+7g5mypjgaaJp/pkOis/6rVxma9nJBF/8kCIuTYHUQNr0ii7MxqE33wirPZLJQ2w==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/mini-decimal@1.1.0': + resolution: {integrity: sha512-jS4E7T9Li2GuYwI6PyiVXmxTiM6b07rlD9Ge8uGZSCz3WlzcG5ZK7g5bbuKNeZ9pgUuPK/5guV781ujdVpm4HQ==} + engines: {node: '>=8.x'} + + '@rc-component/mutate-observer@1.1.0': + resolution: {integrity: sha512-QjrOsDXQusNwGZPf4/qRQasg7UFEj06XiCJ8iuiq/Io7CrHrgVi6Uuetw60WAMG1799v+aM8kyc+1L/GBbHSlw==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/portal@1.1.2': + resolution: {integrity: sha512-6f813C0IsasTZms08kfA8kPAGxbbkYToa8ALaiDIGGECU4i9hj8Plgbx0sNJDrey3EtHO30hmdaxtT0138xZcg==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/qrcode@1.0.0': + resolution: {integrity: sha512-L+rZ4HXP2sJ1gHMGHjsg9jlYBX/SLN2D6OxP9Zn3qgtpMWtO2vUfxVFwiogHpAIqs54FnALxraUy/BCO1yRIgg==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/tour@1.15.1': + resolution: {integrity: sha512-Tr2t7J1DKZUpfJuDZWHxyxWpfmj8EZrqSgyMZ+BCdvKZ6r1UDsfU46M/iWAAFBy961Ssfom2kv5f3UcjIL2CmQ==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + '@rc-component/trigger@2.2.6': + resolution: {integrity: sha512-/9zuTnWwhQ3S3WT1T8BubuFTT46kvnXgaERR9f4BTKyn61/wpf/BvbImzYBubzJibU707FxwbKszLlHjcLiv1Q==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + '@remix-run/router@1.21.0': resolution: {integrity: sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==} engines: {node: '>=14.0.0'} @@ -4274,6 +4378,12 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} + antd@5.23.2: + resolution: {integrity: sha512-h39z/uSeNvF3FtSMytle58s68zQFXJ+XuLm31l6mPBBq99tUSxO9b1Wfnw7b8Q5Mfl4hsXjoz85+/jIRGfYJ5Q==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + any-promise@1.3.0: resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} @@ -4756,6 +4866,9 @@ packages: resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} engines: {node: '>=0.10.0'} + classnames@2.5.1: + resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + clean-css@5.3.3: resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} engines: {node: '>= 10.0'} @@ -4890,6 +5003,9 @@ packages: resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==} engines: {node: '>= 0.8.0'} + compute-scroll-into-view@3.1.1: + resolution: {integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -5133,6 +5249,9 @@ packages: dayjs@1.11.10: resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -6866,6 +6985,9 @@ packages: json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + json2mq@0.2.0: + resolution: {integrity: sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==} + json5@1.0.2: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} hasBin: true @@ -8366,6 +8488,234 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} + rc-cascader@3.33.0: + resolution: {integrity: sha512-JvZrMbKBXIbEDmpIORxqvedY/bck6hGbs3hxdWT8eS9wSQ1P7//lGxbyKjOSyQiVBbgzNWriSe6HoMcZO/+0rQ==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-checkbox@3.5.0: + resolution: {integrity: sha512-aOAQc3E98HteIIsSqm6Xk2FPKIER6+5vyEFMZfo73TqM+VVAIqOkHoPjgKLqSNtVLWScoaM7vY2ZrGEheI79yg==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-collapse@3.9.0: + resolution: {integrity: sha512-swDdz4QZ4dFTo4RAUMLL50qP0EY62N2kvmk2We5xYdRwcRn8WcYtuetCJpwpaCbUfUt5+huLpVxhvmnK+PHrkA==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-dialog@9.6.0: + resolution: {integrity: sha512-ApoVi9Z8PaCQg6FsUzS8yvBEQy0ZL2PkuvAgrmohPkN3okps5WZ5WQWPc1RNuiOKaAYv8B97ACdsFU5LizzCqg==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-drawer@7.2.0: + resolution: {integrity: sha512-9lOQ7kBekEJRdEpScHvtmEtXnAsy+NGDXiRWc2ZVC7QXAazNVbeT4EraQKYwCME8BJLa8Bxqxvs5swwyOepRwg==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-dropdown@4.2.1: + resolution: {integrity: sha512-YDAlXsPv3I1n42dv1JpdM7wJ+gSUBfeyPK59ZpBD9jQhK9jVuxpjj3NmWQHOBceA1zEPVX84T2wbdb2SD0UjmA==} + peerDependencies: + react: '>=16.11.0' + react-dom: '>=16.11.0' + + rc-field-form@2.7.0: + resolution: {integrity: sha512-hgKsCay2taxzVnBPZl+1n4ZondsV78G++XVsMIJCAoioMjlMQR9YwAp7JZDIECzIu2Z66R+f4SFIRrO2DjDNAA==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-image@7.11.0: + resolution: {integrity: sha512-aZkTEZXqeqfPZtnSdNUnKQA0N/3MbgR7nUnZ+/4MfSFWPFHZau4p5r5ShaI0KPEMnNjv4kijSCFq/9wtJpwykw==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-input-number@9.4.0: + resolution: {integrity: sha512-Tiy4DcXcFXAf9wDhN8aUAyMeCLHJUHA/VA/t7Hj8ZEx5ETvxG7MArDOSE6psbiSCo+vJPm4E3fGN710ITVn6GA==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-input@1.7.2: + resolution: {integrity: sha512-g3nYONnl4edWj2FfVoxsU3Ec4XTE+Hb39Kfh2MFxMZjp/0gGyPUgy/v7ZhS27ZxUFNkuIDYXm9PJsLyJbtg86A==} + peerDependencies: + react: '>=16.0.0' + react-dom: '>=16.0.0' + + rc-mentions@2.19.1: + resolution: {integrity: sha512-KK3bAc/bPFI993J3necmaMXD2reZTzytZdlTvkeBbp50IGH1BDPDvxLdHDUrpQx2b2TGaVJsn+86BvYa03kGqA==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-menu@9.16.0: + resolution: {integrity: sha512-vAL0yqPkmXWk3+YKRkmIR8TYj3RVdEt3ptG2jCJXWNAvQbT0VJJdRyHZ7kG/l1JsZlB+VJq/VcYOo69VR4oD+w==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-motion@2.9.5: + resolution: {integrity: sha512-w+XTUrfh7ArbYEd2582uDrEhmBHwK1ZENJiSJVb7uRxdE7qJSYjbO2eksRXmndqyKqKoYPc9ClpPh5242mV1vA==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-notification@5.6.2: + resolution: {integrity: sha512-Id4IYMoii3zzrG0lB0gD6dPgJx4Iu95Xu0BQrhHIbp7ZnAZbLqdqQ73aIWH0d0UFcElxwaKjnzNovTjo7kXz7g==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-overflow@1.4.1: + resolution: {integrity: sha512-3MoPQQPV1uKyOMVNd6SZfONi+f3st0r8PksexIdBTeIYbMX0Jr+k7pHEDvsXtR4BpCv90/Pv2MovVNhktKrwvw==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-pagination@5.0.0: + resolution: {integrity: sha512-QjrPvbAQwps93iluvFM62AEYglGYhWW2q/nliQqmvkTi4PXP4HHoh00iC1Sa5LLVmtWQHmG73fBi2x6H6vFHRg==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-picker@4.9.2: + resolution: {integrity: sha512-SLW4PRudODOomipKI0dvykxW4P8LOqtMr17MOaLU6NQJhkh9SZeh44a/8BMxwv5T6e3kiIeYc9k5jFg2Mv35Pg==} + engines: {node: '>=8.x'} + peerDependencies: + date-fns: '>= 2.x' + dayjs: '>= 1.x' + luxon: '>= 3.x' + moment: '>= 2.x' + react: '>=16.9.0' + react-dom: '>=16.9.0' + peerDependenciesMeta: + date-fns: + optional: true + dayjs: + optional: true + luxon: + optional: true + moment: + optional: true + + rc-progress@4.0.0: + resolution: {integrity: sha512-oofVMMafOCokIUIBnZLNcOZFsABaUw8PPrf1/y0ZBvKZNpOiu5h4AO9vv11Sw0p4Hb3D0yGWuEattcQGtNJ/aw==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-rate@2.13.0: + resolution: {integrity: sha512-oxvx1Q5k5wD30sjN5tqAyWTvJfLNNJn7Oq3IeS4HxWfAiC4BOXMITNAsw7u/fzdtO4MS8Ki8uRLOzcnEuoQiAw==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-resize-observer@1.4.3: + resolution: {integrity: sha512-YZLjUbyIWox8E9i9C3Tm7ia+W7euPItNWSPX5sCcQTYbnwDb5uNpnLHQCG1f22oZWUhLw4Mv2tFmeWe68CDQRQ==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-segmented@2.7.0: + resolution: {integrity: sha512-liijAjXz+KnTRVnxxXG2sYDGd6iLL7VpGGdR8gwoxAXy2KglviKCxLWZdjKYJzYzGSUwKDSTdYk8brj54Bn5BA==} + peerDependencies: + react: '>=16.0.0' + react-dom: '>=16.0.0' + + rc-select@14.16.6: + resolution: {integrity: sha512-YPMtRPqfZWOm2XGTbx5/YVr1HT0vn//8QS77At0Gjb3Lv+Lbut0IORJPKLWu1hQ3u4GsA0SrDzs7nI8JG7Zmyg==} + engines: {node: '>=8.x'} + peerDependencies: + react: '*' + react-dom: '*' + + rc-slider@11.1.8: + resolution: {integrity: sha512-2gg/72YFSpKP+Ja5AjC5DPL1YnV8DEITDQrcc1eASrUYjl0esptaBVJBh5nLTXCCp15eD8EuGjwezVGSHhs9tQ==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-steps@6.0.1: + resolution: {integrity: sha512-lKHL+Sny0SeHkQKKDJlAjV5oZ8DwCdS2hFhAkIjuQt1/pB81M0cA0ErVFdHq9+jmPmFw1vJB2F5NBzFXLJxV+g==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-switch@4.1.0: + resolution: {integrity: sha512-TI8ufP2Az9oEbvyCeVE4+90PDSljGyuwix3fV58p7HV2o4wBnVToEyomJRVyTaZeqNPAp+vqeo4Wnj5u0ZZQBg==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-table@7.50.2: + resolution: {integrity: sha512-+nJbzxzstBriLb5sr9U7Vjs7+4dO8cWlouQbMwBVYghk2vr508bBdkHJeP/z9HVjAIKmAgMQKxmtbgDd3gc5wA==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-tabs@15.5.0: + resolution: {integrity: sha512-NrDcTaUJLh9UuDdMBkjKTn97U9iXG44s9D03V5NHkhEDWO5/nC6PwC3RhkCWFMKB9hh+ryqgZ+TIr1b9Jd/hnQ==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-textarea@1.9.0: + resolution: {integrity: sha512-dQW/Bc/MriPBTugj2Kx9PMS5eXCCGn2cxoIaichjbNvOiARlaHdI99j4DTxLl/V8+PIfW06uFy7kjfUIDDKyxQ==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-tooltip@6.3.2: + resolution: {integrity: sha512-oA4HZIiZJbUQ5ojigM0y4XtWxaH/aQlJSzknjICRWNpqyemy1sL3X3iEQV2eSPBWEq+bqU3+aSs81z+28j9luA==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-tree-select@5.27.0: + resolution: {integrity: sha512-2qTBTzwIT7LRI1o7zLyrCzmo5tQanmyGbSaGTIf7sYimCklAToVVfpMC6OAldSKolcnjorBYPNSKQqJmN3TCww==} + peerDependencies: + react: '*' + react-dom: '*' + + rc-tree@5.13.0: + resolution: {integrity: sha512-2+lFvoVRnvHQ1trlpXMOWtF8BUgF+3TiipG72uOfhpL5CUdXCk931kvDdUkTL/IZVtNEDQKwEEmJbAYJSA5NnA==} + engines: {node: '>=10.x'} + peerDependencies: + react: '*' + react-dom: '*' + + rc-upload@4.8.1: + resolution: {integrity: sha512-toEAhwl4hjLAI1u8/CgKWt30BR06ulPa4iGQSMvSXoHzO88gPCslxqV/mnn4gJU7PDoltGIC9Eh+wkeudqgHyw==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-util@5.44.3: + resolution: {integrity: sha512-q6KCcOFk3rv/zD3MckhJteZxb0VjAIFuf622B7ElK4vfrZdAzs16XR5p3VTdy3+U5jfJU5ACz4QnhLSuAGe5dA==} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + + rc-virtual-list@3.18.1: + resolution: {integrity: sha512-ARSsD/dey/I4yNQHFYYUaKLUkD1wnD4lRZIvb3rCLMbTMmoFQJRVrWuSfbNt5P5MzMNooEBDvqrUPM4QN7BMNA==} + engines: {node: '>=8.x'} + peerDependencies: + react: '>=16.9.0' + react-dom: '>=16.9.0' + react-colorful@5.6.1: resolution: {integrity: sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==} peerDependencies: @@ -8592,6 +8942,9 @@ packages: requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + resize-observer-polyfill@1.5.1: + resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} + resolve-cwd@3.0.0: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} engines: {node: '>=8'} @@ -8911,6 +9264,9 @@ packages: resolution: {integrity: sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==} engines: {node: '>= 12.13.0'} + scroll-into-view-if-needed@3.1.0: + resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} + section-matter@1.0.0: resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} engines: {node: '>=4'} @@ -9227,6 +9583,9 @@ packages: resolution: {integrity: sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==} engines: {node: '>=8.0'} + string-convert@0.2.1: + resolution: {integrity: sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==} + string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} engines: {node: '>=10'} @@ -9312,6 +9671,9 @@ packages: peerDependencies: postcss: ^8.4.31 + stylis@4.3.5: + resolution: {integrity: sha512-K7npNOKGRYuhAFFzkzMGfxFDpN6gDwf8hcMiE+uveTVbBgm93HrNP3ZDUpKqzZ4pG7TP6fmb+EMAQPjq9FqqvA==} + stylus-loader@7.1.3: resolution: {integrity: sha512-TY0SKwiY7D2kMd3UxaWKSf3xHF0FFN/FAfsSqfrhxRT/koXTwffq2cgEWDkLQz7VojMu7qEEHt5TlMjkPx9UDw==} engines: {node: '>= 14.15.0'} @@ -9430,6 +9792,10 @@ packages: thread-stream@2.7.0: resolution: {integrity: sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==} + throttle-debounce@5.0.2: + resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==} + engines: {node: '>=12.22'} + through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} @@ -10257,6 +10623,55 @@ snapshots: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 + '@ant-design/colors@7.2.0': + dependencies: + '@ant-design/fast-color': 2.0.6 + + '@ant-design/cssinjs-utils@1.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@ant-design/cssinjs': 1.23.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@babel/runtime': 7.26.0 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@ant-design/cssinjs@1.23.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.0 + '@emotion/hash': 0.8.0 + '@emotion/unitless': 0.7.5 + classnames: 2.5.1 + csstype: 3.1.3 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + stylis: 4.3.5 + + '@ant-design/fast-color@2.0.6': + dependencies: + '@babel/runtime': 7.26.0 + + '@ant-design/icons-svg@4.4.2': {} + + '@ant-design/icons@5.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@ant-design/colors': 7.2.0 + '@ant-design/icons-svg': 4.4.2 + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@ant-design/react-slick@1.1.2(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + json2mq: 0.2.0 + react: 18.3.1 + resize-observer-polyfill: 1.5.1 + throttle-debounce: 5.0.2 + '@babel/code-frame@7.26.2': dependencies: '@babel/helper-validator-identifier': 7.25.9 @@ -11140,7 +11555,7 @@ snapshots: '@babel/regjsgen@0.8.0': {} - '@babel/runtime@7.24.5': + '@babel/runtime@7.26.0': dependencies: regenerator-runtime: 0.14.1 @@ -11416,6 +11831,10 @@ snapshots: dependencies: tslib: 2.8.1 + '@emotion/hash@0.8.0': {} + + '@emotion/unitless@0.7.5': {} + '@esbuild/aix-ppc64@0.20.2': optional: true @@ -11879,14 +12298,14 @@ snapshots: '@manypkg/find-root@1.1.0': dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.26.0 '@types/node': 12.20.55 find-up: 4.1.0 fs-extra: 8.1.0 '@manypkg/get-packages@1.1.3': dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.26.0 '@changesets/types': 4.1.0 '@manypkg/find-root': 1.1.0 fs-extra: 8.1.0 @@ -12315,22 +12734,6 @@ snapshots: - nx optional: true - '@nrwl/js@17.2.8(@babel/traverse@7.25.9)(@swc/core@1.7.26(@swc/helpers@0.5.15))(@types/node@18.19.33)(nx@17.2.8(@swc/core@1.7.26(@swc/helpers@0.5.15)))(typescript@5.2.2)(verdaccio@5.31.0(typanion@3.14.0))': - dependencies: - '@nx/js': 17.2.8(@babel/traverse@7.25.9)(@swc/core@1.7.26(@swc/helpers@0.5.15))(@types/node@18.19.33)(nx@17.2.8(@swc/core@1.7.26(@swc/helpers@0.5.15)))(typescript@5.2.2)(verdaccio@5.31.0(typanion@3.14.0)) - transitivePeerDependencies: - - '@babel/traverse' - - '@swc-node/register' - - '@swc/core' - - '@swc/wasm' - - '@types/node' - - debug - - nx - - supports-color - - typescript - - verdaccio - optional: true - '@nrwl/js@17.2.8(@babel/traverse@7.25.9)(@swc/core@1.7.26(@swc/helpers@0.5.15))(@types/node@18.19.33)(nx@17.2.8(@swc/core@1.7.26(@swc/helpers@0.5.15)))(typescript@5.7.3)(verdaccio@5.31.0(typanion@3.14.0))': dependencies: '@nx/js': 17.2.8(@babel/traverse@7.25.9)(@swc/core@1.7.26(@swc/helpers@0.5.15))(@types/node@18.19.33)(nx@17.2.8(@swc/core@1.7.26(@swc/helpers@0.5.15)))(typescript@5.7.3)(verdaccio@5.31.0(typanion@3.14.0)) @@ -12474,8 +12877,8 @@ snapshots: '@babel/plugin-transform-runtime': 7.25.9(@babel/core@7.24.5) '@babel/preset-env': 7.24.5(@babel/core@7.24.5) '@babel/preset-typescript': 7.24.1(@babel/core@7.24.5) - '@babel/runtime': 7.24.5 - '@nrwl/js': 17.2.8(@babel/traverse@7.25.9)(@swc/core@1.7.26(@swc/helpers@0.5.15))(@types/node@18.19.33)(nx@17.2.8(@swc/core@1.7.26(@swc/helpers@0.5.15)))(typescript@5.2.2)(verdaccio@5.31.0(typanion@3.14.0)) + '@babel/runtime': 7.26.0 + '@nrwl/js': 17.2.8(@babel/traverse@7.25.9)(@swc/core@1.7.26(@swc/helpers@0.5.15))(@types/node@18.19.33)(nx@17.2.8(@swc/core@1.7.26(@swc/helpers@0.5.15)))(typescript@5.7.3)(verdaccio@5.31.0(typanion@3.14.0)) '@nx/devkit': 17.2.8(nx@17.2.8(@swc/core@1.7.26(@swc/helpers@0.5.15))) '@nx/workspace': 17.2.8(@swc/core@1.7.26(@swc/helpers@0.5.15)) '@phenomnomnominal/tsquery': 5.0.1(typescript@5.2.2) @@ -12520,7 +12923,7 @@ snapshots: '@babel/plugin-transform-runtime': 7.25.9(@babel/core@7.24.5) '@babel/preset-env': 7.24.5(@babel/core@7.24.5) '@babel/preset-typescript': 7.24.1(@babel/core@7.24.5) - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.26.0 '@nrwl/js': 17.2.8(@babel/traverse@7.25.9)(@swc/core@1.7.26(@swc/helpers@0.5.15))(@types/node@18.19.33)(nx@17.2.8(@swc/core@1.7.26(@swc/helpers@0.5.15)))(typescript@5.7.3)(verdaccio@5.31.0(typanion@3.14.0)) '@nx/devkit': 17.2.8(nx@17.2.8(@swc/core@1.7.26(@swc/helpers@0.5.15))) '@nx/workspace': 17.2.8(@swc/core@1.7.26(@swc/helpers@0.5.15)) @@ -12846,6 +13249,75 @@ snapshots: '@polka/url@1.0.0-next.28': {} + '@rc-component/async-validator@5.0.4': + dependencies: + '@babel/runtime': 7.26.0 + + '@rc-component/color-picker@2.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@ant-design/fast-color': 2.0.6 + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@rc-component/context@1.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.0 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@rc-component/mini-decimal@1.1.0': + dependencies: + '@babel/runtime': 7.26.0 + + '@rc-component/mutate-observer@1.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@rc-component/portal@1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@rc-component/qrcode@1.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@rc-component/tour@1.15.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.0 + '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rc-component/trigger': 2.2.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@rc-component/trigger@2.2.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.26.0 + '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + '@remix-run/router@1.21.0': {} '@rollup/pluginutils@5.1.4(rollup@4.17.2)': @@ -13998,7 +14470,7 @@ snapshots: '@testing-library/dom@10.4.0': dependencies: '@babel/code-frame': 7.26.2 - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.26.0 '@types/aria-query': 5.0.4 aria-query: 5.3.0 chalk: 4.1.2 @@ -14028,7 +14500,7 @@ snapshots: '@testing-library/react@16.0.1(@testing-library/dom@10.4.0)(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.26.0 '@testing-library/dom': 10.4.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -14851,6 +15323,64 @@ snapshots: ansi-styles@6.2.1: {} + antd@5.23.2(luxon@3.5.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@ant-design/colors': 7.2.0 + '@ant-design/cssinjs': 1.23.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@ant-design/cssinjs-utils': 1.1.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@ant-design/fast-color': 2.0.6 + '@ant-design/icons': 5.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@ant-design/react-slick': 1.1.2(react@18.3.1) + '@babel/runtime': 7.26.0 + '@rc-component/color-picker': 2.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rc-component/mutate-observer': 1.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rc-component/qrcode': 1.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rc-component/tour': 1.15.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@rc-component/trigger': 2.2.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + copy-to-clipboard: 3.3.3 + dayjs: 1.11.13 + rc-cascader: 3.33.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-checkbox: 3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-collapse: 3.9.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-dialog: 9.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-drawer: 7.2.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-dropdown: 4.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-field-form: 2.7.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-image: 7.11.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-input: 1.7.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-input-number: 9.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-mentions: 2.19.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-menu: 9.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-notification: 5.6.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-pagination: 5.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-picker: 4.9.2(dayjs@1.11.13)(luxon@3.5.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-progress: 4.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-rate: 2.13.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-segmented: 2.7.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-select: 14.16.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-slider: 11.1.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-steps: 6.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-switch: 4.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-table: 7.50.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-tabs: 15.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-textarea: 1.9.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-tooltip: 6.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-tree: 5.13.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-tree-select: 5.27.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-upload: 4.8.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + scroll-into-view-if-needed: 3.1.0 + throttle-debounce: 5.0.2 + transitivePeerDependencies: + - date-fns + - luxon + - moment + any-promise@1.3.0: {} anymatch@3.1.3: @@ -15037,7 +15567,7 @@ snapshots: babel-plugin-macros@2.8.0: dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.26.0 cosmiconfig: 6.0.0 resolve: 1.22.10 optional: true @@ -15412,6 +15942,8 @@ snapshots: isobject: 3.0.1 static-extend: 0.1.2 + classnames@2.5.1: {} + clean-css@5.3.3: dependencies: source-map: 0.6.1 @@ -15535,6 +16067,8 @@ snapshots: - supports-color optional: true + compute-scroll-into-view@3.1.1: {} + concat-map@0.0.1: {} connect-history-api-fallback@2.0.0: @@ -15821,6 +16355,8 @@ snapshots: dayjs@1.11.10: optional: true + dayjs@1.11.13: {} + debug@2.6.9: dependencies: ms: 2.0.0 @@ -18079,6 +18615,10 @@ snapshots: json-stringify-safe@5.0.1: optional: true + json2mq@0.2.0: + dependencies: + string-convert: 0.2.1 + json5@1.0.2: dependencies: minimist: 1.2.8 @@ -19604,7 +20144,7 @@ snapshots: polished@4.3.1: dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.26.0 portfinder@1.0.32: dependencies: @@ -20050,6 +20590,325 @@ snapshots: unpipe: 1.0.0 optional: true + rc-cascader@3.33.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-select: 14.16.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-tree: 5.13.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-checkbox@3.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-collapse@3.9.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-dialog@9.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-drawer@7.2.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-dropdown@4.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + '@rc-component/trigger': 2.2.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-field-form@2.7.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + '@rc-component/async-validator': 5.0.4 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-image@7.11.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + '@rc-component/portal': 1.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-dialog: 9.6.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-input-number@9.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + '@rc-component/mini-decimal': 1.1.0 + classnames: 2.5.1 + rc-input: 1.7.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-input@1.7.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-mentions@2.19.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + '@rc-component/trigger': 2.2.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-input: 1.7.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-menu: 9.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-textarea: 1.9.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-menu@9.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + '@rc-component/trigger': 2.2.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-overflow: 1.4.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-motion@2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-notification@5.6.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-overflow@1.4.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-pagination@5.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-picker@4.9.2(dayjs@1.11.13)(luxon@3.5.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + '@rc-component/trigger': 2.2.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-overflow: 1.4.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + dayjs: 1.11.13 + luxon: 3.5.0 + + rc-progress@4.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-rate@2.13.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-resize-observer@1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + resize-observer-polyfill: 1.5.1 + + rc-segmented@2.7.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-select@14.16.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + '@rc-component/trigger': 2.2.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-overflow: 1.4.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-virtual-list: 3.18.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-slider@11.1.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-steps@6.0.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-switch@4.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-table@7.50.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + '@rc-component/context': 1.4.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-virtual-list: 3.18.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-tabs@15.5.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-dropdown: 4.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-menu: 9.16.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-textarea@1.9.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-input: 1.7.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-tooltip@6.3.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + '@rc-component/trigger': 2.2.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + classnames: 2.5.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-tree-select@5.27.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-select: 14.16.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-tree: 5.13.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-tree@5.13.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-motion: 2.9.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-virtual-list: 3.18.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-upload@4.8.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + rc-util@5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-is: 18.3.1 + + rc-virtual-list@3.18.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/runtime': 7.26.0 + classnames: 2.5.1 + rc-resize-observer: 1.4.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + rc-util: 5.44.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-colorful@5.6.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: react: 18.3.1 @@ -20118,7 +20977,7 @@ snapshots: react-helmet-async@1.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.26.0 invariant: 2.2.4 prop-types: 15.8.1 react: 18.3.1 @@ -20154,7 +21013,7 @@ snapshots: react-syntax-highlighter@15.6.1(react@18.3.1): dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.26.0 highlight.js: 10.7.3 highlightjs-vue: 1.0.0 lowlight: 1.20.0 @@ -20261,7 +21120,7 @@ snapshots: regenerator-transform@0.15.2: dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.26.0 regex-not@1.0.2: dependencies: @@ -20362,6 +21221,8 @@ snapshots: requires-port@1.0.0: {} + resize-observer-polyfill@1.5.1: {} + resolve-cwd@3.0.0: dependencies: resolve-from: 5.0.0 @@ -20664,6 +21525,10 @@ snapshots: ajv-keywords: 5.1.0(ajv@8.12.0) optional: true + scroll-into-view-if-needed@3.1.0: + dependencies: + compute-scroll-into-view: 3.1.1 + section-matter@1.0.0: dependencies: extend-shallow: 2.0.1 @@ -21048,6 +21913,7 @@ snapshots: magic-string: 0.30.17 react: 16.14.0 react-docgen: 7.1.0 + react-docgen-typescript: 2.2.2(typescript@5.7.3) react-dom: 16.14.0(react@16.14.0) resolve: 1.22.10 storybook: 8.5.0-beta.8(prettier@2.8.8) @@ -21082,6 +21948,8 @@ snapshots: transitivePeerDependencies: - supports-color + string-convert@0.2.1: {} + string-length@4.0.2: dependencies: char-regex: 1.0.2 @@ -21169,6 +22037,8 @@ snapshots: postcss-selector-parser: 6.1.2 optional: true + stylis@4.3.5: {} + stylus-loader@7.1.3(stylus@0.59.0)(webpack@5.96.1(@swc/core@1.7.26(@swc/helpers@0.5.15))): dependencies: fast-glob: 3.3.2 @@ -21321,6 +22191,8 @@ snapshots: real-require: 0.2.0 optional: true + throttle-debounce@5.0.2: {} + through@2.3.8: optional: true @@ -22383,7 +23255,7 @@ snapshots: yup@0.32.11: dependencies: - '@babel/runtime': 7.24.5 + '@babel/runtime': 7.26.0 '@types/lodash': 4.17.1 lodash: 4.17.21 lodash-es: 4.17.21 diff --git a/sandboxes/react-18/.storybook/main.ts b/sandboxes/react-18/.storybook/main.ts index 20a74466..313493ef 100644 --- a/sandboxes/react-18/.storybook/main.ts +++ b/sandboxes/react-18/.storybook/main.ts @@ -27,6 +27,11 @@ const config: StorybookConfig = { }, typescript: { reactDocgen: 'react-docgen-typescript', + reactDocgenTypescriptOptions: { + shouldExtractLiteralValuesFromEnum: true, + shouldRemoveUndefinedFromOptional: true, + propFilter: () => true, + }, check: true, }, } diff --git a/sandboxes/react-18/package.json b/sandboxes/react-18/package.json index c697ae92..b90f0351 100644 --- a/sandboxes/react-18/package.json +++ b/sandboxes/react-18/package.json @@ -13,6 +13,7 @@ "storybook": "storybook dev -p 6006" }, "dependencies": { + "antd": "^5.23.2", "react": "18.3.1", "react-dom": "18.3.1" }, diff --git a/sandboxes/react-18/src/stories/AntdButton.stories.ts b/sandboxes/react-18/src/stories/AntdButton.stories.ts new file mode 100644 index 00000000..6a973f4a --- /dev/null +++ b/sandboxes/react-18/src/stories/AntdButton.stories.ts @@ -0,0 +1,56 @@ +import type { Meta, StoryObj } from '@storybook/react' +import { fn } from '@storybook/test' +import { AntdButton } from './AntdButton' + +// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export +const meta = { + title: 'Example/AntdButton', + component: AntdButton, + parameters: { + // Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout + layout: 'centered', + }, + // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs + tags: ['autodocs'], + // More on argTypes: https://storybook.js.org/docs/api/argtypes + argTypes: { + backgroundColor: { control: 'color' }, + }, + // Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args + args: { onClick: fn() }, +} satisfies Meta + +export default meta +type Story = StoryObj + +// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args +export const Primary: Story = { + args: { + primary: true, + label: 'Button', + myButtonExtra: 'PrimaryExtra', + }, +} + +export const Secondary: Story = { + args: { + label: 'Button', + myButtonExtra: 'SecondaryExtra', + }, +} + +export const Large: Story = { + args: { + size: 'large', + label: 'Button', + myButtonExtra: 'LargeExtra', + }, +} + +export const Small: Story = { + args: { + size: 'small', + label: 'Button', + myButtonExtra: 'SmallExtra', + }, +} diff --git a/sandboxes/react-18/src/stories/AntdButton.tsx b/sandboxes/react-18/src/stories/AntdButton.tsx new file mode 100644 index 00000000..070343fc --- /dev/null +++ b/sandboxes/react-18/src/stories/AntdButton.tsx @@ -0,0 +1,22 @@ +import { Button, type ButtonProps } from 'antd' +import React from 'react' + +interface AntdButtonProps extends ButtonProps { + myButtonExtra: string +} + +/** + * An extended Ant Design button with an extra string. + */ +export const AntdButton: React.FC = ({ + children, + myButtonExtra, + ...props +}) => { + return ( + + ) +}