├── .github └── workflows │ ├── main.yml │ ├── nodejs.yml │ └── stale.yml ├── .gitignore ├── .lintstagedrc ├── .npmignore ├── .prettierrc ├── LICENSE.md ├── README.md ├── examples ├── react-styleguidist-example │ ├── .lintstagedrc │ ├── README.md │ ├── components │ │ ├── Column.md │ │ ├── Column.tsx │ │ ├── ConstExport.tsx │ │ ├── Grid.tsx │ │ ├── HocComponent.tsx │ │ ├── PureRow.tsx │ │ └── Row.tsx │ ├── index.ts │ ├── package-lock.json │ ├── package.json │ ├── styleguide.config.js │ ├── tsconfig.json │ ├── tslint.json │ └── webpack.config.js └── react-styleguidist-sections-example │ ├── .lintstagedrc │ ├── README.md │ ├── components │ ├── Column.md │ ├── Column.tsx │ ├── ConstExport.tsx │ ├── Grid.tsx │ ├── HocComponent.tsx │ ├── PureRow.tsx │ └── Row.tsx │ ├── index.ts │ ├── package-lock.json │ ├── package.json │ ├── styleguide.config.js │ ├── tsconfig.json │ ├── tslint.json │ └── webpack.config.js ├── lint.json ├── package-lock.json ├── package.json ├── src ├── __tests__ │ ├── __sourceMapInit.ts │ ├── buildFilter.ts │ ├── data │ │ ├── AppMenu.tsx │ │ ├── ButtonWithOnClickComponent.tsx │ │ ├── Column.tsx │ │ ├── ColumnHigherOrderComponent.tsx │ │ ├── ColumnHigherOrderComponentHoc.tsx │ │ ├── ColumnWithAnnotatedChildren.tsx │ │ ├── ColumnWithDefaultAnonymousExportOnly.tsx │ │ ├── ColumnWithDefaultExport.tsx │ │ ├── ColumnWithDefaultExportOnly.tsx │ │ ├── ColumnWithHtmlAttributes.tsx │ │ ├── ColumnWithLog.tsx │ │ ├── ColumnWithMethods.tsx │ │ ├── ColumnWithPick.tsx │ │ ├── ColumnWithPropsWithExternalType.MyExternalType.tsx │ │ ├── ColumnWithPropsWithExternalType.tsx │ │ ├── ColumnWithStaticComponents.tsx │ │ ├── ColumnWithStaticMethods.tsx │ │ ├── ColumnWithUndocumentedProps.tsx │ │ ├── ColumnWithoutExportedProps.tsx │ │ ├── ComplexGenericUnionIntersection.tsx │ │ ├── ComplexGenericUnionIntersectionWithOmit.tsx │ │ ├── ComponentWithDefaultProps.tsx │ │ ├── ComponentWithImportedDefaultProps.tsx │ │ ├── ComponentWithReferencedDefaultProps.tsx │ │ ├── ComponentWithTypeJsDocTag.tsx │ │ ├── ConstExport.tsx │ │ ├── ExportObject.tsx │ │ ├── ExportsDefaultInterface.tsx │ │ ├── ExportsPropTypeImport.tsx │ │ ├── ExportsPropTypeShape.tsx │ │ ├── ExtendsExternalPropsComponent.tsx │ │ ├── ExtendsExternalPropsComponentParentProps.tsx │ │ ├── ExternalPropsComponent.tsx │ │ ├── ExternalPropsComponentProps.ts │ │ ├── ExtractLiteralValuesFromEnum.tsx │ │ ├── ExtractLiteralValuesFromUnion.tsx │ │ ├── ExtractPropTags.tsx │ │ ├── FilePathCheck.tsx │ │ ├── FlippableImage.tsx │ │ ├── ForwardRefDefaultExport.tsx │ │ ├── ForwardRefDefaultExportAtExport.tsx │ │ ├── ForwardRefDefaultValues.tsx │ │ ├── FunctionDeclaration.tsx │ │ ├── FunctionDeclarationAsConstAsDefaultExportWithMemo.tsx │ │ ├── FunctionDeclarationAsDefaultExport.tsx │ │ ├── FunctionDeclarationAsDefaultExportWithMemo.tsx │ │ ├── FunctionDeclarationDefaultProps.tsx │ │ ├── FunctionDeclarationVisibleName.tsx │ │ ├── FunctionalComponentAsConst.tsx │ │ ├── FunctionalComponentAsConstAsDefaultExport.tsx │ │ ├── FunctionalComponentAsConstAsNamedExport.tsx │ │ ├── FunctionalComponentWithDefaultImportReact.tsx │ │ ├── FunctionalComponentWithDesctructuredProps.constants.ts │ │ ├── FunctionalComponentWithDesctructuredProps.tsx │ │ ├── FunctionalComponentWithDesctructuredPropsAndImportedConstants.tsx │ │ ├── GenericWithExtends.tsx │ │ ├── HOCIntersectionProps.tsx │ │ ├── InlineConst.tsx │ │ ├── Issue188.tsx │ │ ├── Issue320.tsx │ │ ├── JSDocWithParam.tsx │ │ ├── MultipleAllWithDisplayName.tsx │ │ ├── MultipleSomeWithDisplayName.tsx │ │ ├── MultipleWithNoExplicitDisplayName.tsx │ │ ├── OnlyDefaultExportUnion.tsx │ │ ├── OnlyDefaultExportUnionAsExport.tsx │ │ ├── PureRow.tsx │ │ ├── ReactSFCAsConst.tsx │ │ ├── ReactSFCAsConstAsDefaultExport.tsx │ │ ├── ReactSFCAsConstAsNamedExport.tsx │ │ ├── Regression_v0_0_12.tsx │ │ ├── RemoveOptionalValuesFromEnum.tsx │ │ ├── RemoveOptionalValuesFromUnion.tsx │ │ ├── Row.tsx │ │ ├── SeparateDefaultProps.tsx │ │ ├── SeparateDefaultPropsIndividual.tsx │ │ ├── SimpleDiscriminatedUnionIntersection.tsx │ │ ├── SimpleGenericUnionIntersection.tsx │ │ ├── SimpleUnionIntersection.tsx │ │ ├── SimpleUnions.tsx │ │ ├── StatefulDisplayName.tsx │ │ ├── StatefulDisplayNameDefaultExport.tsx │ │ ├── StatefulDisplayNameFolder │ │ │ └── index.tsx │ │ ├── StatefulDisplayNameHOC.tsx │ │ ├── StatefulIntersectionExternalProps.tsx │ │ ├── StatefulIntersectionProps.tsx │ │ ├── Stateless.tsx │ │ ├── StatelessDisplayName.tsx │ │ ├── StatelessDisplayNameDefaultExport.tsx │ │ ├── StatelessDisplayNameDefaultExportDifferentFilename.tsx │ │ ├── StatelessDisplayNameFolder │ │ │ ├── Stateless.d.ts │ │ │ └── index.tsx │ │ ├── StatelessDisplayNameHOC.tsx │ │ ├── StatelessDisplayNameStyledComponent.tsx │ │ ├── StatelessIntersectionExternalProps.tsx │ │ ├── StatelessIntersectionGenericProps.tsx │ │ ├── StatelessIntersectionProps.tsx │ │ ├── StatelessShorthandDefaultProps.tsx │ │ ├── StatelessStaticComponents.tsx │ │ ├── StatelessStaticComponentsExportVariation1.tsx │ │ ├── StatelessStaticComponentsExportVariation2.tsx │ │ ├── StatelessStaticComponentsNamedObjectExport.tsx │ │ ├── StatelessStaticComponentsNamedObjectExportAsKeys.tsx │ │ ├── StatelessWithDefaultOnlyJsDoc.tsx │ │ ├── StatelessWithDefaultProps.tsx │ │ ├── StatelessWithDefaultPropsAsString.tsx │ │ ├── StatelessWithDefaultPropsTypescript3.tsx │ │ ├── StatelessWithDestructuredProps.tsx │ │ ├── StatelessWithDestructuredPropsArrow.tsx │ │ ├── SubComponent.tsx │ │ ├── UnassignedLet.tsx │ │ ├── const.ts │ │ ├── shapes.ts │ │ ├── tsconfig.json │ │ └── withHOC.tsx │ ├── parser.ts │ ├── testUtils.ts │ └── trimFileName.ts ├── buildFilter.ts ├── index.ts ├── parser.ts ├── propTypesParser.ts └── trimFileName.ts ├── stylesheet-example-column.png ├── stylesheet-example-grid.png └── tsconfig.json /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Node.js Package 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v1 12 | - uses: actions/setup-node@v1 13 | with: 14 | node-version: 12 15 | - run: npm test 16 | 17 | publish-npm: 18 | needs: build 19 | runs-on: ubuntu-latest 20 | steps: 21 | - uses: actions/checkout@v1 22 | - uses: actions/setup-node@v1 23 | with: 24 | node-version: 12 25 | registry-url: https://registry.npmjs.org/ 26 | - run: npm publish 27 | env: 28 | NODE_AUTH_TOKEN: ${{secrets.npm_token}} 29 | 30 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: Node CI 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: [master] 8 | workflow_dispatch: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | 14 | strategy: 15 | matrix: 16 | node-version: [14.x] 17 | 18 | steps: 19 | - uses: actions/checkout@v1 20 | - name: Use Node.js ${{ matrix.node-version }} 21 | uses: actions/setup-node@v1 22 | with: 23 | node-version: ${{ matrix.node-version }} 24 | - name: install dependencies 25 | run: npm install 26 | env: 27 | CI: true 28 | - name: test 29 | run: npm test 30 | env: 31 | CI: true 32 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | # This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time. 2 | # 3 | # You can adjust the behavior by modifying this file. 4 | # For more information, see: 5 | # https://github.com/actions/stale 6 | name: Mark stale issues and pull requests 7 | 8 | on: 9 | schedule: 10 | - cron: '40 10 * * *' 11 | 12 | jobs: 13 | stale: 14 | 15 | runs-on: ubuntu-latest 16 | permissions: 17 | issues: write 18 | pull-requests: write 19 | 20 | steps: 21 | - uses: actions/stale@v3 22 | with: 23 | repo-token: ${{ secrets.GITHUB_TOKEN }} 24 | days-before-stale: 365 25 | stale-issue-message: 'There was no activity for a long time. The issue will be closed soon.' 26 | stale-pr-message: 'There was no activity for a long time. The PR will be closed soon.' 27 | close-issue-message: Closing this issue as obsolete. 28 | close-pr-message: Closing this PR as obsolete. 29 | stale-issue-label: 'stale' 30 | stale-pr-label: 'stale' 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/node,visualstudiocode 2 | 3 | ### Node ### 4 | # Logs 5 | logs 6 | *.log 7 | npm-debug.log* 8 | 9 | # Runtime data 10 | pids 11 | *.pid 12 | *.seed 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # node-waf configuration 27 | .lock-wscript 28 | 29 | # Compiled binary addons (http://nodejs.org/api/addons.html) 30 | build/Release 31 | 32 | # Dependency directories 33 | node_modules 34 | jspm_packages 35 | 36 | # Optional npm cache directory 37 | .npm 38 | 39 | # Optional REPL history 40 | .node_repl_history 41 | 42 | 43 | ### VisualStudioCode ### 44 | .vscode 45 | 46 | ### Webstorm ### 47 | .idea 48 | 49 | # App 50 | lib 51 | temp -------------------------------------------------------------------------------- /.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "src/**/*.{ts,tsx}": [ 3 | "npm run prettier:base -- --write" 4 | ] 5 | } -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | __tests__/ -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "none", 3 | "singleQuote": true 4 | } 5 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2016 Pavel Vasek 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-docgen-typescript 2 | 3 | [![Build Status](https://github.com/styleguidist/react-docgen-typescript/actions/workflows/nodejs.yml/badge.svg)](https://github.com/styleguidist/react-docgen-typescript/actions/workflows/nodejs.yml) 4 | 5 | ![](https://nodei.co/npm/react-docgen-typescript.png?downloadRank=true&downloads=true) 6 | 7 | A simple parser for React properties defined in TypeScript instead of propTypes. 8 | 9 | It can be used with [React Styleguidist](https://github.com/styleguidist/react-styleguidist). 10 | 11 | ## Installation 12 | 13 | ```bash 14 | npm install --save-dev react-docgen-typescript 15 | ``` 16 | 17 | ## Usage 18 | 19 | To parse a file for docgen information use the `parse` function. 20 | 21 | ```ts 22 | const docgen = require("react-docgen-typescript"); 23 | 24 | const options = { 25 | savePropValueAsString: true, 26 | }; 27 | 28 | // Parse a file for docgen info 29 | docgen.parse("./path/to/component", options); 30 | ``` 31 | 32 | If you want to customize the typescript configuration or docgen options, this package exports a variety of ways to create custom parsers. 33 | 34 | ```ts 35 | const docgen = require("react-docgen-typescript"); 36 | 37 | // Create a parser with the default typescript config and custom docgen options 38 | const customParser = docgen.withDefaultConfig(options); 39 | 40 | const docs = customParser.parse("./path/to/component"); 41 | 42 | // Create a parser with the custom typescript and custom docgen options 43 | const customCompilerOptionsParser = docgen.withCompilerOptions( 44 | { esModuleInterop: true }, 45 | options 46 | ); 47 | 48 | // Create a parser with using your typescript config 49 | const tsConfigParser = docgen.withCustomConfig("./tsconfig.json", { 50 | savePropValueAsString: true, 51 | }); 52 | ``` 53 | 54 | ### React Styleguidist integration 55 | 56 | Include following line in your `styleguide.config.js`: 57 | 58 | ```javascript 59 | module.exports = { 60 | propsParser: require("react-docgen-typescript").withDefaultConfig([ 61 | parserOptions, 62 | ]).parse, 63 | }; 64 | ``` 65 | 66 | or if you want to use custom tsconfig file 67 | 68 | ```javascript 69 | module.exports = { 70 | propsParser: require("react-docgen-typescript").withCustomConfig( 71 | "./tsconfig.json", 72 | [parserOptions] 73 | ).parse, 74 | }; 75 | ``` 76 | 77 | ## Options 78 | 79 | ### `propFilter` 80 | 81 | The `propFilter` option allows you to omit certain props from documentation generation. 82 | 83 | You can either provide and object with some of our pre-configured filters: 84 | 85 | ```typescript 86 | interface FilterOptions { 87 | skipPropsWithName?: string[] | string; 88 | skipPropsWithoutDoc?: boolean; 89 | } 90 | 91 | const options = { 92 | propFilter: { 93 | skipPropsWithName: ['as', 'id']; 94 | skipPropsWithoutDoc: true; 95 | } 96 | } 97 | ``` 98 | 99 | If you do not want to print out all the HTML attributes of a component typed like the following: 100 | 101 | ```typescript 102 | const MyComponent: React.FC> = ()... 103 | ``` 104 | 105 | you can provide a `propFilter` function and do the filtering logic yourself. 106 | 107 | ```typescript 108 | type PropFilter = (prop: PropItem, component: Component) => boolean; 109 | 110 | const options = { 111 | propFilter: (prop: PropItem, component: Component) => { 112 | if (prop.declarations !== undefined && prop.declarations.length > 0) { 113 | const hasPropAdditionalDescription = prop.declarations.find((declaration) => { 114 | return !declaration.fileName.includes("node_modules"); 115 | }); 116 | 117 | return Boolean(hasPropAdditionalDescription); 118 | } 119 | 120 | return true; 121 | }, 122 | }; 123 | ``` 124 | 125 | Note: `children` without a doc comment will not be documented. 126 | 127 | ### `componentNameResolver` 128 | 129 | ```typescript 130 | (exp: ts.Symbol, source: ts.SourceFile) => string | undefined | null | false; 131 | ``` 132 | 133 | If a string is returned, then the component will use that name. Else it will fallback to the default logic of parser. 134 | 135 | ### `shouldExtractLiteralValuesFromEnum`: boolean 136 | 137 | If set to true, string enums and unions will be converted to docgen enum format. Useful if you use Storybook and want to generate knobs automatically using [addon-smart-knobs](https://github.com/storybookjs/addon-smart-knobs). 138 | 139 | ### `shouldExtractValuesFromUnion`: boolean 140 | 141 | If set to true, every unions will be converted to docgen enum format. 142 | 143 | ### `shouldSortUnions`: boolean 144 | 145 | When used in combination with `shouldExtractValuesFromUnion` or `shouldExtractLiteralValuesFromEnum`, sorts union members in string-sort order when set to true. This is useful for ensuring the same order of members every time. 146 | 147 | ### `skipChildrenPropWithoutDoc`: boolean (default: `true`) 148 | 149 | If set to false the docs for the `children` prop will be generated even without an explicit description. 150 | 151 | ### `shouldRemoveUndefinedFromOptional`: boolean 152 | 153 | If set to true, types that are optional will not display " | undefined" in the type. 154 | 155 | ### `savePropValueAsString`: boolean 156 | 157 | If set to true, defaultValue to props will be string. 158 | Example: 159 | 160 | ```javascript 161 | Component.defaultProps = { 162 | counter: 123, 163 | disabled: false, 164 | }; 165 | ``` 166 | 167 | Will return: 168 | 169 | ```javascript 170 | counter: { 171 | defaultValue: '123', 172 | required: true, 173 | type: 'number' 174 | }, 175 | disabled: { 176 | defaultValue: 'false', 177 | required: true, 178 | type: 'boolean' 179 | } 180 | ``` 181 | 182 | **Styled components example:** 183 | 184 | ```typescript 185 | componentNameResolver: (exp, source) => 186 | exp.getName() === "StyledComponentClass" && getDefaultExportForFile(source); 187 | ``` 188 | 189 | > The parser exports `getDefaultExportForFile` helper through its public API. 190 | 191 | ## Example 192 | 193 | In the example folder you can see React Styleguidist integration. 194 | 195 | **Warning:** only named exports are supported. If your project uses default exports, you still need to include named exports for `react-docgen-typescript`. 196 | 197 | The component [`Column.tsx`](./examples/react-styleguidist-example/components/Column.tsx) 198 | 199 | ```javascript 200 | import * as React from "react"; 201 | import { Component } from "react"; 202 | 203 | /** 204 | * Column properties. 205 | */ 206 | export interface IColumnProps { 207 | /** prop1 description */ 208 | prop1?: string; 209 | /** prop2 description */ 210 | prop2: number; 211 | /** 212 | * prop3 description 213 | */ 214 | prop3: () => void; 215 | /** prop4 description */ 216 | prop4: "option1" | "option2" | "option3"; 217 | } 218 | 219 | /** 220 | * Form column. 221 | */ 222 | export class Column extends Component { 223 | render() { 224 | return
Test
; 225 | } 226 | } 227 | ``` 228 | 229 | Will generate the following stylesheet: 230 | 231 | ![Stylesheet example](https://github.com/styleguidist/react-docgen-typescript/raw/master/stylesheet-example-column.png "Stylesheet example") 232 | 233 | The functional component [`Grid.tsx`](./examples/react-styleguidist-example/components/Grid.tsx) 234 | 235 | ```javascript 236 | import * as React from "react"; 237 | 238 | /** 239 | * Grid properties. 240 | */ 241 | export interface IGridProps { 242 | /** prop1 description */ 243 | prop1?: string; 244 | /** prop2 description */ 245 | prop2: number; 246 | /** 247 | * prop3 description 248 | */ 249 | prop3: () => void; 250 | /** Working grid description */ 251 | prop4: "option1" | "option2" | "option3"; 252 | } 253 | 254 | /** 255 | * Form Grid. 256 | */ 257 | export const Grid = (props: IGridProps) => { 258 | const smaller = () => { 259 | return; 260 | }; 261 | return
Grid
; 262 | }; 263 | ``` 264 | 265 | Will generate the following stylesheet: 266 | 267 | ![Stylesheet example](https://github.com/styleguidist/react-docgen-typescript/raw/master/stylesheet-example-grid.png "Stylesheet example") 268 | 269 | ## Contributions 270 | 271 | The typescript is pretty complex and there are many different ways how 272 | to define components and their props so it's realy hard to support all 273 | these use cases. That means only one thing, contributions are highly 274 | welcome. Just keep in mind that each PR should also include tests for 275 | the part it's fixing. 276 | 277 | Thanks to all contributors without their help there wouldn't be a single 278 | bug fixed or feature implemented. Check the [**contributors**](https://github.com/styleguidist/react-docgen-typescript/graphs/contributors) tab to find out 279 | more. All those people supported this project. **THANK YOU!** 280 | 281 | ## Thanks to others 282 | 283 | The integration with React Styleguidist wouldn't be possible without [Vyacheslav Slinko](https://github.com/vslinko) pull request [#118](https://github.com/styleguidist/react-styleguidist/pull/118) at React Styleguidist. 284 | -------------------------------------------------------------------------------- /examples/react-styleguidist-example/.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "components/**/*.{ts,tsx}": [ 3 | "npm run prettier:base -- --write", 4 | "git add" 5 | ] 6 | } -------------------------------------------------------------------------------- /examples/react-styleguidist-example/README.md: -------------------------------------------------------------------------------- 1 | # Example project 2 | 3 | First you need to install depedencies either by running `npm install`. 4 | 5 | Then you can start it with `npm start` and navigate to http://localhost:6060/. 6 | 7 | The project was tested against the _node version v10.0.1_. -------------------------------------------------------------------------------- /examples/react-styleguidist-example/components/Column.md: -------------------------------------------------------------------------------- 1 | This is our column custom document with example: 2 | 3 | -------------------------------------------------------------------------------- /examples/react-styleguidist-example/components/Column.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Component } from 'react'; 3 | 4 | /** 5 | * Column properties. 6 | */ 7 | export interface IColumnProps extends React.HTMLAttributes { 8 | /** prop1 description */ 9 | prop1?: string; 10 | /** prop2 description */ 11 | prop2: number; 12 | /** 13 | * prop3 description 14 | */ 15 | prop3: () => void; 16 | /** prop4 description */ 17 | prop4: 'option1' | 'option2' | 'option3'; 18 | } 19 | 20 | /** 21 | * Form column. 22 | */ 23 | export class Column extends Component { 24 | render() { 25 | return
Column
; 26 | } 27 | } 28 | 29 | export default Column; 30 | -------------------------------------------------------------------------------- /examples/react-styleguidist-example/components/ConstExport.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | /** 4 | * Row properties. 5 | */ 6 | export interface IRowProps { 7 | /** prop1 description */ 8 | prop1?: string; 9 | /** prop2 description */ 10 | prop2: number; 11 | /** 12 | * prop3 description 13 | */ 14 | prop3: () => void; 15 | /** prop4 description */ 16 | prop4: 'option1' | 'option2' | 'option3'; 17 | } 18 | 19 | /** 20 | * test 21 | * 22 | */ 23 | export const test = (one: number) => { 24 | return one; 25 | }; 26 | 27 | export const myObj = { 28 | foo: 'bar' 29 | }; 30 | 31 | /** 32 | * Form row. 33 | */ 34 | export const ConstExportRow = (props: IRowProps) => { 35 | const innerFunc = (props: IRowProps) => { 36 | return Inner Func; 37 | }; 38 | const innerNonExportedFunc = (props: IRowProps) => { 39 | return Inner Func; 40 | }; 41 | return
Test
; 42 | }; 43 | 44 | const nonExportedFunc = (props: IRowProps) => { 45 | return
No Export
; 46 | }; 47 | 48 | export default ConstExportRow; 49 | -------------------------------------------------------------------------------- /examples/react-styleguidist-example/components/Grid.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | /** 4 | * Grid properties. 5 | */ 6 | export interface IGridProps { 7 | /** prop1 description */ 8 | prop1?: string; 9 | /** prop2 description */ 10 | prop2: number; 11 | /** 12 | * prop3 description 13 | */ 14 | prop3: () => void; 15 | /** Working grid description */ 16 | prop4: 'option1' | 'option2' | 'option3'; 17 | } 18 | 19 | /** 20 | * Form Grid. 21 | */ 22 | export const Grid = (props: IGridProps) => { 23 | const smaller = () => { 24 | return; 25 | }; 26 | return
Grid
; 27 | }; 28 | 29 | const notExported = (props: IGridProps) => { 30 | return
not exported grid
; 31 | }; 32 | 33 | export default Grid; 34 | -------------------------------------------------------------------------------- /examples/react-styleguidist-example/components/HocComponent.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | /** 4 | * Row properties. 5 | */ 6 | export interface IRowProps { 7 | /** prop1 description */ 8 | prop1?: string; 9 | /** prop2 description */ 10 | prop2: number; 11 | /** 12 | * prop3 description 13 | */ 14 | prop3: () => void; 15 | /** prop4 description */ 16 | prop4: 'option1' | 'option2' | 'option3'; 17 | } 18 | 19 | /** 20 | * Form row. 21 | */ 22 | class Component extends React.Component { 23 | render() { 24 | return
Test
; 25 | } 26 | } 27 | 28 | export function hoc(Component: T): T { 29 | // do whatever you need but return the same type T 30 | return Component as T; 31 | } 32 | 33 | /** This example shows HocComponent */ 34 | export const HocComponent = hoc(Component); 35 | -------------------------------------------------------------------------------- /examples/react-styleguidist-example/components/PureRow.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | /** 4 | * Row properties. 5 | */ 6 | export interface IRowProps { 7 | /** prop1 description */ 8 | prop1?: string; 9 | /** prop2 description */ 10 | prop2: number; 11 | /** 12 | * prop3 description 13 | */ 14 | prop3: () => void; 15 | /** prop4 description */ 16 | prop4: 'option1' | 'option2' | 'option3'; 17 | } 18 | 19 | /** 20 | * Form row. 21 | */ 22 | export class PureRow extends React.PureComponent { 23 | render() { 24 | return
Test
; 25 | } 26 | } 27 | 28 | export default PureRow; 29 | -------------------------------------------------------------------------------- /examples/react-styleguidist-example/components/Row.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Component } from 'react'; 3 | 4 | /** 5 | * Row properties. 6 | */ 7 | export interface IRowProps { 8 | /** prop1 description */ 9 | prop1?: string; 10 | /** prop2 description */ 11 | prop2: number; 12 | /** 13 | * prop3 description 14 | */ 15 | prop3: () => void; 16 | /** prop4 description */ 17 | prop4: 'option1' | 'option2' | 'option3'; 18 | } 19 | 20 | /** 21 | * Form Row. 22 | */ 23 | export class Row extends Component { 24 | render() { 25 | return
Row
; 26 | } 27 | } 28 | 29 | export default Row; 30 | -------------------------------------------------------------------------------- /examples/react-styleguidist-example/index.ts: -------------------------------------------------------------------------------- 1 | // this is fake app index file 2 | // just to make sure the webpack itself is setup correctly 3 | 4 | import { Column } from "./components/Column"; 5 | import { ConstExportRow } from "./components/ConstExport"; 6 | import { Grid } from "./components/Grid"; 7 | import { HocComponent } from "./components/HocComponent"; 8 | import { PureRow } from "./components/PureRow"; 9 | import { Row } from "./components/Row"; 10 | 11 | export { 12 | Column, 13 | ConstExportRow, 14 | Grid, 15 | HocComponent, 16 | PureRow, 17 | Row, 18 | } -------------------------------------------------------------------------------- /examples/react-styleguidist-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-docgen-typescript-example", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "tsc": "tsc", 8 | "styleguidist": "styleguidist", 9 | "start": "tsc && styleguidist server --config styleguide.config.js", 10 | "webpack": "webpack", 11 | "lint": "tslint -c tslint.json 'src/**/*.{ts,tsx}'", 12 | "lint:fix": "npm run lint -- --fix", 13 | "prettier:base": "prettier --parser typescript --single-quote --trailing-comma none", 14 | "prettier:check": "npm run prettier:base -- -l \"components/**/*.{ts,tsx}\"", 15 | "prettier:write": "npm run prettier:base -- --write \"components/**/*.{ts,tsx}\"" 16 | }, 17 | "license": "MIT", 18 | "dependencies": { 19 | "@types/react": "^16.4.14", 20 | "@types/react-dom": "^16.0.7", 21 | "react": "^16.5.0", 22 | "react-dom": "^16.5.0" 23 | }, 24 | "devDependencies": { 25 | "husky": "^0.14.3", 26 | "lint-staged": "^7.2.2", 27 | "prettier": "^1.14.2", 28 | "react-docgen-typescript": "^1.9.0", 29 | "react-styleguidist": "^7.3.7", 30 | "ts-loader": "^5.1.0", 31 | "tslint": "^5.11.0", 32 | "typescript": "^3.0.3", 33 | "webpack": "^4.18.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /examples/react-styleguidist-example/styleguide.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const glob = require('glob'); 3 | 4 | module.exports = { 5 | title: 'React Style Guide Example', 6 | components: function () { 7 | return glob.sync(path.resolve(__dirname, 'components/**/*.tsx')) 8 | .filter(function (module) { 9 | return /\/[A-Z]\w*\.tsx$/.test(module); 10 | }); 11 | }, 12 | resolver: require('react-docgen').resolver.findAllComponentDefinitions, 13 | propsParser: require('react-docgen-typescript').withDefaultConfig({ propFilter: { skipPropsWithoutDoc: true } }).parse 14 | }; -------------------------------------------------------------------------------- /examples/react-styleguidist-example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "lib": ["es5", "es6", "dom"], 6 | "noImplicitAny": false, 7 | "sourceMap": true, 8 | "outDir": "lib", 9 | "jsx": "react" 10 | } 11 | } -------------------------------------------------------------------------------- /examples/react-styleguidist-example/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:recommended" 5 | ], 6 | "jsRules": {}, 7 | "rules": { 8 | "member-access": false, 9 | "trailing-comma": [true, {"multiline": "never", "singleline": "never"}], 10 | "interface-name": false, 11 | "quotemark": [true, "single"], 12 | "arrow-parens": false 13 | }, 14 | "rulesDirectory": [] 15 | } -------------------------------------------------------------------------------- /examples/react-styleguidist-example/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | module.exports = { 4 | entry: { 5 | bundle: ['./index.ts'], 6 | }, 7 | context: path.resolve(__dirname), 8 | output: { 9 | filename: 'bundle.js', 10 | path: path.join(__dirname, 'temp') 11 | }, 12 | module: { 13 | rules: [ 14 | { 15 | test: /\.tsx?$/, 16 | loader: 'ts-loader', 17 | exclude: /node_modules/, 18 | } 19 | ] 20 | }, 21 | resolve: { 22 | extensions: [".tsx", ".ts", ".js"] 23 | } 24 | }; -------------------------------------------------------------------------------- /examples/react-styleguidist-sections-example/.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "components/**/*.{ts,tsx}": [ 3 | "npm run prettier:base -- --write", 4 | "git add" 5 | ] 6 | } -------------------------------------------------------------------------------- /examples/react-styleguidist-sections-example/README.md: -------------------------------------------------------------------------------- 1 | # Example project 2 | 3 | First you need to install depedencies either by running `npm install`. 4 | 5 | Then you can start it with `npm start` and navigate to http://localhost:6060/. 6 | 7 | The project was tested against the _node version v10.0.1_. -------------------------------------------------------------------------------- /examples/react-styleguidist-sections-example/components/Column.md: -------------------------------------------------------------------------------- 1 | This is our column custom document with example: 2 | 3 | -------------------------------------------------------------------------------- /examples/react-styleguidist-sections-example/components/Column.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Component } from 'react'; 3 | 4 | /** 5 | * Column properties. 6 | */ 7 | export interface IColumnProps extends React.HTMLAttributes { 8 | /** prop1 description */ 9 | prop1?: string; 10 | /** prop2 description */ 11 | prop2: number; 12 | /** 13 | * prop3 description 14 | */ 15 | prop3: () => void; 16 | /** prop4 description */ 17 | prop4: 'option1' | 'option2' | 'option3'; 18 | } 19 | 20 | /** 21 | * Form column. 22 | */ 23 | export class Column extends Component { 24 | render() { 25 | return
Column
; 26 | } 27 | } 28 | 29 | export default Column; 30 | -------------------------------------------------------------------------------- /examples/react-styleguidist-sections-example/components/ConstExport.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | /** 4 | * Row properties. 5 | */ 6 | export interface IRowProps { 7 | /** prop1 description */ 8 | prop1?: string; 9 | /** prop2 description */ 10 | prop2: number; 11 | /** 12 | * prop3 description 13 | */ 14 | prop3: () => void; 15 | /** prop4 description */ 16 | prop4: 'option1' | 'option2' | 'option3'; 17 | } 18 | 19 | /** 20 | * test 21 | * 22 | */ 23 | export const test = (one: number) => { 24 | return one; 25 | }; 26 | 27 | export const myObj = { 28 | foo: 'bar' 29 | }; 30 | 31 | /** 32 | * Form row. 33 | */ 34 | export const ConstExportRow = (props: IRowProps) => { 35 | const innerFunc = (props: IRowProps) => { 36 | return Inner Func; 37 | }; 38 | const innerNonExportedFunc = (props: IRowProps) => { 39 | return Inner Func; 40 | }; 41 | return
Test
; 42 | }; 43 | 44 | const nonExportedFunc = (props: IRowProps) => { 45 | return
No Export
; 46 | }; 47 | 48 | export default ConstExportRow; 49 | -------------------------------------------------------------------------------- /examples/react-styleguidist-sections-example/components/Grid.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | /** 4 | * Grid properties. 5 | */ 6 | export interface IGridProps { 7 | /** prop1 description */ 8 | prop1?: string; 9 | /** prop2 description */ 10 | prop2: number; 11 | /** 12 | * prop3 description 13 | */ 14 | prop3: () => void; 15 | /** Working grid description */ 16 | prop4: 'option1' | 'option2' | 'option3'; 17 | } 18 | 19 | /** 20 | * Form Grid. 21 | */ 22 | export const Grid = (props: IGridProps) => { 23 | const smaller = () => { 24 | return; 25 | }; 26 | return
Grid
; 27 | }; 28 | 29 | const notExported = (props: IGridProps) => { 30 | return
not exported grid
; 31 | }; 32 | 33 | export default Grid; 34 | -------------------------------------------------------------------------------- /examples/react-styleguidist-sections-example/components/HocComponent.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | /** 4 | * Row properties. 5 | */ 6 | export interface IRowProps { 7 | /** prop1 description */ 8 | prop1?: string; 9 | /** prop2 description */ 10 | prop2: number; 11 | /** 12 | * prop3 description 13 | */ 14 | prop3: () => void; 15 | /** prop4 description */ 16 | prop4: 'option1' | 'option2' | 'option3'; 17 | } 18 | 19 | /** 20 | * Form row. 21 | */ 22 | class Component extends React.Component { 23 | render() { 24 | return
Test
; 25 | } 26 | } 27 | 28 | export function hoc(Component: T): T { 29 | // do whatever you need but return the same type T 30 | return Component as T; 31 | } 32 | 33 | /** This example shows HocComponent */ 34 | export const HocComponent = hoc(Component); 35 | -------------------------------------------------------------------------------- /examples/react-styleguidist-sections-example/components/PureRow.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | /** 4 | * Row properties. 5 | */ 6 | export interface IRowProps { 7 | /** prop1 description */ 8 | prop1?: string; 9 | /** prop2 description */ 10 | prop2: number; 11 | /** 12 | * prop3 description 13 | */ 14 | prop3: () => void; 15 | /** prop4 description */ 16 | prop4: 'option1' | 'option2' | 'option3'; 17 | } 18 | 19 | /** 20 | * Form row. 21 | */ 22 | export class PureRow extends React.PureComponent { 23 | render() { 24 | return
Test
; 25 | } 26 | } 27 | 28 | export default PureRow; 29 | -------------------------------------------------------------------------------- /examples/react-styleguidist-sections-example/components/Row.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Component } from 'react'; 3 | 4 | /** 5 | * Row properties. 6 | */ 7 | export interface IRowProps { 8 | /** prop1 description */ 9 | prop1?: string; 10 | /** prop2 description */ 11 | prop2: number; 12 | /** 13 | * prop3 description 14 | */ 15 | prop3: () => void; 16 | /** prop4 description */ 17 | prop4: 'option1' | 'option2' | 'option3'; 18 | } 19 | 20 | /** 21 | * Form Row. 22 | */ 23 | export class Row extends Component { 24 | render() { 25 | return
Row
; 26 | } 27 | } 28 | 29 | export default Row; 30 | -------------------------------------------------------------------------------- /examples/react-styleguidist-sections-example/index.ts: -------------------------------------------------------------------------------- 1 | // this is fake app index file 2 | // just to make sure the webpack itself is setup correctly 3 | 4 | import { Column } from "./components/Column"; 5 | import { ConstExportRow } from "./components/ConstExport"; 6 | import { Grid } from "./components/Grid"; 7 | import { HocComponent } from "./components/HocComponent"; 8 | import { PureRow } from "./components/PureRow"; 9 | import { Row } from "./components/Row"; 10 | 11 | export { 12 | Column, 13 | ConstExportRow, 14 | Grid, 15 | HocComponent, 16 | PureRow, 17 | Row, 18 | } -------------------------------------------------------------------------------- /examples/react-styleguidist-sections-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-docgen-typescript-example", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "tsc": "tsc", 8 | "styleguidist": "styleguidist", 9 | "start": "tsc && styleguidist server --config styleguide.config.js", 10 | "webpack": "webpack", 11 | "lint": "tslint -c tslint.json 'src/**/*.{ts,tsx}'", 12 | "lint:fix": "npm run lint -- --fix", 13 | "prettier:base": "prettier --parser typescript --single-quote --trailing-comma none", 14 | "prettier:check": "npm run prettier:base -- -l \"components/**/*.{ts,tsx}\"", 15 | "prettier:write": "npm run prettier:base -- --write \"components/**/*.{ts,tsx}\"" 16 | }, 17 | "license": "MIT", 18 | "dependencies": { 19 | "@types/react": "^16.4.14", 20 | "@types/react-dom": "^16.0.7", 21 | "react": "^16.5.0", 22 | "react-codemirror2": "^5.1.0", 23 | "react-dom": "^16.5.0" 24 | }, 25 | "devDependencies": { 26 | "husky": "^0.14.3", 27 | "lint-staged": "^7.2.2", 28 | "prettier": "^1.14.2", 29 | "react-docgen-typescript": "^1.9.0", 30 | "react-styleguidist": "^7.3.7", 31 | "ts-loader": "^5.1.0", 32 | "tslint": "^5.11.0", 33 | "typescript": "^3.0.3", 34 | "webpack": "^4.18.0" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /examples/react-styleguidist-sections-example/styleguide.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const glob = require('glob'); 3 | 4 | module.exports = { 5 | title: 'React Style Guide Example', 6 | pagePerSection: true, 7 | sections: [ { 8 | name: 'Test section 1', 9 | description: 'Test secion 1 description', 10 | components: function () { 11 | return glob.sync(path.resolve(__dirname, 'components/**/*.tsx')) 12 | .filter(function (module) { 13 | return /\/[A-Z]\w*\.tsx$/.test(module); 14 | }); 15 | }, 16 | }, { 17 | name: 'Test secion 2', 18 | description: 'Test section 2 description' 19 | }], 20 | resolver: require('react-docgen').resolver.findAllComponentDefinitions, 21 | propsParser: require('react-docgen-typescript').withDefaultConfig({ propFilter: { skipPropsWithoutDoc: true } }).parse 22 | }; -------------------------------------------------------------------------------- /examples/react-styleguidist-sections-example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "lib": ["es5", "es6", "dom"], 6 | "noImplicitAny": false, 7 | "sourceMap": true, 8 | "outDir": "lib", 9 | "jsx": "react" 10 | } 11 | } -------------------------------------------------------------------------------- /examples/react-styleguidist-sections-example/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:recommended" 5 | ], 6 | "jsRules": {}, 7 | "rules": { 8 | "member-access": false, 9 | "trailing-comma": [true, {"multiline": "never", "singleline": "never"}], 10 | "interface-name": false, 11 | "quotemark": [true, "single"], 12 | "arrow-parens": false 13 | }, 14 | "rulesDirectory": [] 15 | } -------------------------------------------------------------------------------- /examples/react-styleguidist-sections-example/webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | module.exports = { 4 | entry: { 5 | bundle: ['./index.ts'], 6 | }, 7 | context: path.resolve(__dirname), 8 | output: { 9 | filename: 'bundle.js', 10 | path: path.join(__dirname, 'temp') 11 | }, 12 | module: { 13 | rules: [ 14 | { 15 | test: /\.tsx?$/, 16 | loader: 'ts-loader', 17 | exclude: /node_modules/, 18 | } 19 | ] 20 | }, 21 | resolve: { 22 | extensions: [".tsx", ".ts", ".js"] 23 | } 24 | }; -------------------------------------------------------------------------------- /lint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:recommended" 5 | ], 6 | "jsRules": {}, 7 | "rules": { 8 | "member-access": false, 9 | "trailing-comma": [true, {"multiline": "never", "singleline": "never"}], 10 | "interface-name": false, 11 | "quotemark": [true, "single"], 12 | "arrow-parens": false 13 | }, 14 | "rulesDirectory": [] 15 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-docgen-typescript", 3 | "version": "2.3.0", 4 | "description": "", 5 | "homepage": "https://github.com/styleguidist/react-docgen-typescript/", 6 | "bugs": "https://github.com/styleguidist/react-docgen-typescript/issues", 7 | "main": "lib/index.js", 8 | "types": "lib/index.d.ts", 9 | "scripts": { 10 | "precommit": "lint-staged", 11 | "tsc": "tsc", 12 | "tsc:watch": "tsc -w", 13 | "prepublishOnly": "tsc -d", 14 | "test": "tsc && mocha --timeout 10000 ./lib/**/__tests__/**.js", 15 | "test:debug": "tsc && mocha --inspect ./lib/**/__tests__/**.js", 16 | "print": "npm run tsc && node ./lib/print.js", 17 | "print:sample1": "npm run tsc && node ./lib/print.js ./src/__tests__/data/ColumnHigherOrderComponent.tsx simple", 18 | "lint": "eslint -c lint.json 'src/**/*.{ts,tsx}'", 19 | "lint:fix": "npm run lint -- --fix", 20 | "prettier:base": "prettier --parser typescript --single-quote --trailing-comma none", 21 | "prettier:check": "npm run prettier:base -- -l \"src/**/*.{ts,tsx}\"", 22 | "prettier:write": "npm run prettier:base -- --write \"src/**/*.{ts,tsx}\"" 23 | }, 24 | "license": "MIT", 25 | "peerDependencies": { 26 | "typescript": ">= 4.3.x" 27 | }, 28 | "devDependencies": { 29 | "@types/chai": "^4.1.0", 30 | "@types/lodash": "^4.14.137", 31 | "@types/mocha": "^5.2.5", 32 | "@types/node": "^15.6.1", 33 | "@types/prop-types": "^15.5.4", 34 | "@types/react": "^16.9.34", 35 | "@types/source-map-support": "^0.4.1", 36 | "chai": "^4.1.2", 37 | "eslint": "^7.32.0", 38 | "husky": "^0.14.3", 39 | "install": "^0.13.0", 40 | "lint-staged": "^16.1.0", 41 | "lodash": "^4.17.15", 42 | "mocha": "^11.5.0", 43 | "prettier": "^1.19.1", 44 | "prop-types": "^15.6.2", 45 | "react": "^16.4.2", 46 | "source-map-support": "^0.5.6", 47 | "typescript": "^4.3.2" 48 | }, 49 | "files": [ 50 | "lib", 51 | "README.md" 52 | ], 53 | "repository": { 54 | "type": "git", 55 | "url": "https://github.com/styleguidist/react-docgen-typescript.git" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/__tests__/__sourceMapInit.ts: -------------------------------------------------------------------------------- 1 | import * as sourceMapSupport from 'source-map-support'; 2 | sourceMapSupport.install(); 3 | -------------------------------------------------------------------------------- /src/__tests__/buildFilter.ts: -------------------------------------------------------------------------------- 1 | import { assert, expect } from 'chai'; 2 | import { buildFilter } from '../buildFilter'; 3 | import { ParentType, ParserOptions, PropItem } from '../parser'; 4 | 5 | function createProp( 6 | name: string, 7 | required: boolean = false, 8 | defaultValue?: any, 9 | description: string = '', 10 | type = { name: 'string' }, 11 | parent?: ParentType 12 | ): PropItem { 13 | return { 14 | defaultValue, 15 | description, 16 | name, 17 | parent, 18 | required, 19 | type 20 | }; 21 | } 22 | 23 | describe('buildFilter', () => { 24 | describe('default behaviour', () => { 25 | it('should skip "children" property if no description is set', () => { 26 | const prop1 = createProp('prop1', false, undefined, 'prop1 description'); 27 | const prop2 = createProp('prop2', false, undefined, 'prop2 description'); 28 | const children = createProp('children', false, undefined, ''); 29 | const opts: ParserOptions = {}; 30 | const filterFn = buildFilter(opts); 31 | expect( 32 | [prop1, prop2, children].filter(prop => 33 | filterFn(prop, { name: prop.name }) 34 | ) 35 | ).to.eql([prop1, prop2]); 36 | }); 37 | it('should not skip "children" property if description is set', () => { 38 | const prop1 = createProp('prop1', false, undefined, 'prop1 description'); 39 | const prop2 = createProp('prop2', false, undefined, 'prop2 description'); 40 | const children = createProp( 41 | 'children', 42 | false, 43 | undefined, 44 | 'children description' 45 | ); 46 | const opts: ParserOptions = {}; 47 | const filterFn = buildFilter(opts); 48 | expect( 49 | [prop1, prop2, children].filter(prop => 50 | filterFn(prop, { name: prop.name }) 51 | ) 52 | ).to.eql([prop1, prop2, children]); 53 | }); 54 | }); 55 | 56 | describe('static prop filter', () => { 57 | describe('skipPropsWithName', () => { 58 | it('should skip single prop by name', () => { 59 | const prop1 = createProp( 60 | 'prop1', 61 | false, 62 | undefined, 63 | 'prop1 description' 64 | ); 65 | const prop2 = createProp( 66 | 'prop2', 67 | false, 68 | undefined, 69 | 'prop2 description' 70 | ); 71 | const opts: ParserOptions = { 72 | propFilter: { skipPropsWithName: 'prop1' } 73 | }; 74 | const filterFn = buildFilter(opts); 75 | expect( 76 | [prop1, prop2].filter(prop => filterFn(prop, { name: prop.name })) 77 | ).to.eql([prop2]); 78 | }); 79 | it('should skip multiple props by name', () => { 80 | const prop1 = createProp( 81 | 'prop1', 82 | false, 83 | undefined, 84 | 'prop1 description' 85 | ); 86 | const prop2 = createProp( 87 | 'prop2', 88 | false, 89 | undefined, 90 | 'prop2 description' 91 | ); 92 | const prop3 = createProp( 93 | 'prop3', 94 | false, 95 | undefined, 96 | 'prop3 description' 97 | ); 98 | const opts: ParserOptions = { 99 | propFilter: { skipPropsWithName: ['prop1', 'prop3'] } 100 | }; 101 | const filterFn = buildFilter(opts); 102 | expect( 103 | [prop1, prop2, prop3].filter(prop => 104 | filterFn(prop, { name: prop.name }) 105 | ) 106 | ).to.eql([prop2]); 107 | }); 108 | }); 109 | 110 | describe('skipPropsWithoutDoc', () => { 111 | it('should skip children props with no documentation', () => { 112 | const prop1 = createProp( 113 | 'prop1', 114 | false, 115 | undefined, 116 | 'prop1 description' 117 | ); 118 | const prop2 = createProp('prop2', false, undefined, ''); 119 | const opts: ParserOptions = { 120 | propFilter: { skipPropsWithoutDoc: true } 121 | }; 122 | const filterFn = buildFilter(opts); 123 | expect( 124 | [prop1, prop2].filter(prop => filterFn(prop, { name: prop.name })) 125 | ).to.eql([prop1]); 126 | }); 127 | }); 128 | }); 129 | 130 | describe('dynamic prop filter', () => { 131 | it('should skip props based on dynamic filter rule', () => { 132 | const prop1 = createProp('foo', false, undefined, 'foo description'); 133 | const prop2 = createProp('bar', false, undefined, 'bar description'); 134 | const prop3 = createProp( 135 | 'foobar', 136 | false, 137 | undefined, 138 | 'foobar description' 139 | ); 140 | const opts: ParserOptions = { 141 | propFilter: (prop, component) => prop.name.indexOf('foo') === -1 142 | }; 143 | const filterFn = buildFilter(opts); 144 | expect( 145 | [prop1, prop2, prop3].filter(prop => 146 | filterFn(prop, { name: prop.name }) 147 | ) 148 | ).to.eql([prop2]); 149 | }); 150 | 151 | it('should get be possible to filter by component name', () => { 152 | const prop1 = createProp('foo', false, undefined, 'foo description'); 153 | const prop2 = createProp('bar', false, undefined, 'bar description'); 154 | const prop3 = createProp( 155 | 'foobar', 156 | false, 157 | undefined, 158 | 'foobar description' 159 | ); 160 | const opts: ParserOptions = { 161 | propFilter: (prop, component) => component.name.indexOf('BAR') === -1 162 | }; 163 | const filterFn = buildFilter(opts); 164 | expect( 165 | [prop1, prop2, prop3].filter(prop => 166 | filterFn(prop, { name: prop.name.toUpperCase() }) 167 | ) 168 | ).to.eql([prop1]); 169 | }); 170 | 171 | it('should be possible to filter by interface in which prop was declared.', () => { 172 | const stringType = { name: 'string' }; 173 | const htmlAttributesInterface = { 174 | fileName: 'node_modules/@types/react/index.d.ts', 175 | name: 'HTMLAttributes' 176 | }; 177 | const excludedType = { name: 'ExcludedType', fileName: 'src/types.ts' }; 178 | const prop1 = createProp( 179 | 'foo', 180 | false, 181 | undefined, 182 | 'foo description', 183 | stringType 184 | ); 185 | const prop2 = createProp( 186 | 'bar', 187 | false, 188 | undefined, 189 | 'bar description', 190 | stringType, 191 | excludedType 192 | ); 193 | const prop3 = createProp( 194 | 'onFocus', 195 | false, 196 | undefined, 197 | 'onFocus description', 198 | stringType, 199 | htmlAttributesInterface 200 | ); 201 | const opts: ParserOptions = { 202 | propFilter: (prop, component) => { 203 | if (prop.parent == null) { 204 | return true; 205 | } 206 | 207 | if (prop.parent.fileName.indexOf('@types/react/index.d.ts') > -1) { 208 | return false; 209 | } 210 | 211 | return prop.parent.name !== 'ExcludedType'; 212 | } 213 | }; 214 | const filterFn = buildFilter(opts); 215 | expect( 216 | [prop1, prop2, prop3].filter(prop => 217 | filterFn(prop, { name: 'SomeComponent' }) 218 | ) 219 | ).to.eql([prop1]); 220 | }); 221 | }); 222 | }); 223 | -------------------------------------------------------------------------------- /src/__tests__/data/AppMenu.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | /** IAppMenuProps props */ 4 | export interface IAppMenuProps { 5 | /** menu description */ 6 | menu: any; 7 | } 8 | 9 | export interface IAppMenuState { 10 | menu: any; 11 | } 12 | 13 | /** AppMenu description */ 14 | export class AppMenu extends React.Component { 15 | constructor(props, context) { 16 | super(props, context); 17 | this.state = { 18 | menu: this.props.menu 19 | }; 20 | 21 | this.handleClick = this.handleClick.bind(this); 22 | } 23 | 24 | componentWillReceiveProps(newProps: IAppMenuProps) { 25 | /* empty on purpose */ 26 | } 27 | 28 | handleClick(info) { 29 | /* empty on purpose */ 30 | } 31 | 32 | render() { 33 | return
test
; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/__tests__/data/ButtonWithOnClickComponent.tsx: -------------------------------------------------------------------------------- 1 | import { FC, PropsWithRef } from 'react'; 2 | 3 | type HTMLButtonProps = JSX.IntrinsicElements['button']; 4 | 5 | type Props = HTMLButtonProps & { 6 | /** onClick event handler */ 7 | onClick?: HTMLButtonProps['onClick']; 8 | }; 9 | 10 | const ButtonWithOnClickComponent: FC = props => { 11 | return