• Stars
    star
    820
  • Rank 55,603 (Top 2 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 6 years ago
  • Updated 11 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Beautiful toolbox for jsdoc generated documentation - with 'typescript', `category` and `component` plugins

Documentation toolbox for your javascript / typescript projects based on JSDoc3 with @category, @component and @optional plugins.

This is how it looks:

Example

Example documentation can be found here: https://softwarebrothers.github.io/example-design-system/index.html

OpenSource SoftwareBrothers community

Installation

npm install --save-dev better-docs

Theme Usage

With command line

Assuming that you have jsdoc installed globally:

jsdoc your-documented-file.js -t ./node_modules/better-docs

With npm and configuration file

In your projects package.json file - add a new script:

"script": {
  "docs": "jsdoc -c jsdoc.json"
}

in your jsdoc.json file, set the template:

"opts": {
  "template": "node_modules/better-docs"
}

TypeScript support

better-docs has a plugin which allows you to generate documentation from your TypeScript codebase.

Usage

To use it update your jsdoc.json file

...
"tags": {
    "allowUnknownTags": ["optional"] //or true
},
"plugins": [
    "node_modules/better-docs/typescript"
],
"source": {
    "includePattern": "\\.(jsx|js|ts|tsx)$",
},
...

And now you can run your jsdoc command and parse TypeScript files.

How it works?

It performs 4 operations:

  • First of all it transpiles all .ts and .tsx files to .js, so that all comments used by you are treated as a regular JSDoc comments.

Furthermore it:

  • Converts all your commented type aliases to @typedef
  • Converts all your commented interface definitions to @interface,
  • Converts descriptions for your public, protected, static class members

so they can be printed by JSDoc automatically.

Examples

/**
 * ActionRequest
 * @memberof Action
 * @alias ActionRequest
 */
export type ActionRequest = {
  /**
   * parameters passed in an URL
   */
  params: {
    /**
     * Id of current resource
     */
    resourceId: string;
    /**
     * Id of current record
     */
    recordId?: string;
    /**
     * Name of an action
     */
    action: string;

    [key: string]: any;
  };
}

is converted to:

/**
 * ActionRequest'
 * @memberof Action'
 * @alias ActionRequest'
 * @typedef {object} ActionRequest'
 * @property {object} params   parameters passed in an URL'
 * @property {string} params.resourceId   Id of current resource'
 * @property {string} [params.recordId]   Id of current record'
 * @property {string} params.action   Name of an action'
 * @property {any} params.{...}'
 */

Also you can comment the interface in a similar fashion:

/**
 * JSON representation of an {@link Action}
 * @see Action
 */
export default interface ActionJSON {
  /**
   * Unique action name
   */
  name: string;
  /**
   * Type of an action
   */
  actionType: 'record' | 'resource' | Array<'record' | 'resource'>;
  /**
   * Action icon
   */
  icon?: string;
  /**
   * Action label - visible on the frontend
   */
  label: string;
  /**
   * Guarding message
   */
  guard?: string;
  /**
   * If action should have a filter (for resource actions)
   */
  showFilter: boolean;
  /**
   * Action component. When set to false action will be invoked immediately after clicking it,
   * to put in another words: there wont be an action view
   */
  component?: string | false | null;
}

or describe your class properties like that:

/**
 * Class name
 */
class ClassName {
  /**
   * Some private member which WONT be in jsdoc (because it is private)
   */
  private name: string

  /**
   * Some protected member which will go to the docs
   */
  protected somethingIsA: number

  /**
   * And static member which will goes to the docs.
   */
  static someStaticMember: number

  public notCommentedWontBeInJSDoc: string

  constructor(color: string) {}
}

@category plugin

better-docs also allows you to nest your documentation into categories and subcategories in the sidebar menu.

Usage

To add a plugin - update plugins section in your jsdoc.json file:

...
"tags": {
    "allowUnknownTags": ["category"] //or true
},
"plugins": [
    "node_modules/better-docs/category"
],
...

and then you can use @category and/or @subcategory tag in your code:

/**
 * Class description
 * @category Category
 * @subcategory All
 */
class YourClass {
  ....
}

@component plugin [BETA]

Better-docs also allows you to document your React and Vue components automatically. The only thing you have to do is to add a @component tag. It will take all props from your components and along with an @example tag - will generate a live preview.

Installation instructions

Similar as before to add a plugin - you have to update the plugins section in your jsdoc.json file:

...
"tags": {
    "allowUnknownTags": ["component"] //or true
},
"plugins": [
    "node_modules/better-docs/component"
],
...

Since component plugin uses parcel as a bundler you have to install it globally. To do this run:

# if you use npm
npm install -g parcel-bundler

# or yarn
yarn global add parcel-bundler

Usage

To document components simply add @component in your JSDoc documentation:

/**
 * Some documented component
 *
 * @component
 */
const Documented = (props) => {
  const { text } = props
  return (
    <div>{text}</div>
  )
}

Documented.propTypes = {
  /**
   * Text is a text
   */
  text: PropTypes.string.isRequired,
}

export default Documented

The plugin will take the information from your PropTypes and put them into an array.

For Vue it looks similar:

<script>
/**
 * @component
 */
export default {
  name: 'ExampleComponent',
  props: {
    spent: {
      type: Number,
      default: 30,
    },
    remaining: {
      type: Number,
      default: 40,
    }
  },
}
</script>

In this case, props will be taken from props property.

Preview

@component plugin also modifies the behaviour of @example tag in a way that it can generate an actual component preview. What you have to do is to add an @example tag and return component from it:

React example:

/**
 * Some documented component
 *
 * @component
 * @example
 * const text = 'some example text'
 * return (
 *   <Documented text={text} />
 * )
 */
const Documented = (props) => {
  ///...
}

Vue example 1:

<script>
/**
 * @component
 * @example
 * <ExampleComponent :spent="100" :remaining="50"></ExampleComponent>
 */
export default {
  name: 'ExampleComponent',
  //...
}
</script>

Vue example 2:

<script>
/**
 * @component
 * @example
 * {
 *   template: `<Box>
 *     <ProgressBar :spent="spent" :remaining="50"></ProgressBar>
 *     <ProgressBar :spent="50" :remaining="50" style="margin-top: 20px"></ProgressBar>
 *   </Box>`,
 *   data: function() {
 *     return {spent: 223};
 *   }
 * }
 */
export default {
  name: 'ExampleComponent',
  //...
}
</script>

You can put as many @example tags as you like in one component and "caption" each of them like this:

/**
 * @component
 * @example <caption>Example usage of method1.</caption>
 * // your example here
 */

Mixing components in preview

Also you can use multiple components which are documented with @component tag together. So lets say you have 2 components and in the second component you want to use the first one as a wrapper like this:

// component-1.js
/**
 * Component 1
 * @component
 *
 */
const Component1 = (props) => {...}

// component-2.js
/**
 * Component 2
 * @component
 * @example
 * return (
 *   <Component1>
 *     <Component2 prop1={'some value'}/>
 *     <Component2 prop1={'some other value'}/>
 *   </Component1>
 * )
 */
const Component2 = (props) => {...}

Wrapper component [only React]

Most probably your components will have to be run within a particular context, like within redux store provider or with custom CSS libraries. You can simulate this by passing a component.wrapper in your jsdoc.json: (To read more about passing options - scroll down to Customization section)

// jsdoc.json
{
    "opts": {...},
    "templates": {
        "better-docs": {
            "name": "Sample Documentation",
            "component": {
              "wrapper": "./path/to/your/wrapper-component.js",
            },
            "...": "...",
        }
    }
}

Wrapper component can look like this:

// wrapper-component.js
import React from 'react'
import { BrowserRouter } from 'react-router-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'

const store = createStore(() => ({}), {})

const Component = (props) => {
  return (
    <React.Fragment>
      <head>
        <link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.css" />
      </head>
      <Provider store={store}>
        <BrowserRouter>
          {props.children}
        </BrowserRouter>
      </Provider>
    </React.Fragment>
  )
}

export default Component

Styling React examples

Better-docs inserts all examples within an iframe. This results in the following styling options:

  1. If you pass styles inline - they will work right away.

  2. For css modules to work with parcel bundler - you have to install postcss-modules package:

yarn add postcss-modules

and create a .postcssrc file:

// .postcssrc
{
	"modules": true
}
  1. For styled-components you have to use wrapper component which looks like this:
import React from 'react'
import { StyleSheetManager } from 'styled-components'

const Component = (props) => {
  const { frameContext } = props
  return (
    <StyleSheetManager target={frameContext.document.head}>
      {props.children}
    </StyleSheetManager>
  )
}

export default Component

Adding commands to bundle entry file

@component plugin creates an entry file: .entry.js in your docs output folder. Sometimes you might want to add something to it. You can do this by passing: component.entry option, which is an array of strings.

So let's say you want to add babel-polyfill and 'bulma.css' framework to your bundle. You can do it like this:

// jsdoc.json
{
    "opts": {...},
    "templates": {
        "better-docs": {
            "name": "Sample Documentation",
            "component": {
                "entry": [
                    "import 'babel-polyfill';",
                    "import 'bulma/css/bulma.css';"
                ]
            },
            "...": "...",
        }
    }
}

Customization

First of all, let me state that better-docs extends the default template. That is why default template parameters are also handled.

[BETA]: You must explicitly set the search option of the default template to true to enable search

To customize the better-docs pass options to templates['better-docs']. section in your jsdoc configuration file.

Example configuration file with settings for both default and better-docs templates:

{
    "tags": {
        "allowUnknownTags": ["category"]
    },
    "source": {
        "include": ["./src"],
        "includePattern": ".js$",
        "excludePattern": "(node_modules/|docs)"
    },
    "plugins": [
        "plugins/markdown",
        "jsdoc-mermaid",
        "node_modules/better-docs/category"
    ],
    "opts": {
        "encoding": "utf8",
        "destination": "docs/",
        "readme": "readme.md",
        "recurse": true,
        "verbose": true,
        "tutorials": "./docs-src/tutorials",
        "template": "better-docs"
    },
    "templates": {
        "cleverLinks": false,
        "monospaceLinks": false,
        "search": true,
        "default": {
            "staticFiles": {
              "include": [
                  "./docs-src/statics"
              ]
            }
        },
        "better-docs": {
            "name": "Sample Documentation",
            "logo": "images/logo.png",
            "title": "", // HTML title
            "css": "style.css",
            "trackingCode": "tracking-code-which-will-go-to-the-HEAD",
	    "hideGenerator": false,
            "navLinks": [
                {
                    "label": "Github",
                    "href": "https://github.com/SoftwareBrothers/admin-bro"
                },
                {
                    "label": "Example Application",
                    "href": "https://admin-bro-example-app-staging.herokuapp.com/admin"
                }
            ]
        }
    }
}

Extras

typedef(import(...))

better-docs also has one extra plugin for handling typescript'like types imports like (it has to be one-liner):

/** @typedef {import('./some-other-file').ExportedType} ExportedType */

It simply removes that from the code so JSDoc wont throw an error. In order to use it add this plugin to your plugins section:

  "plugins": [
        "node_modules/better-docs/typedef-import"
    ],

Setting up for the development

If you want to change the theme locally follow the steps:

  1. Clone the repo to the folder where you have the project:
cd your-project
git clone [email protected]:SoftwareBrothers/better-docs.git

or add it as a git submodule:

git submodule add [email protected]:SoftwareBrothers/better-docs.git
  1. Install the packages
cd better-docs

npm install

# or

yarn
  1. Within the better-docs folder run the gulp script. It will regenerate documentation every time you change something.

It supports following EVN variables:

  • DOCS_COMMAND - a command in your root repo which you use to generate documentation: i.e. DOCS_COMMAND='jsdoc -c jsdoc.json' or npm run docs if you have docs command defined in package.json file
  • DOCS_OUTPUT - where your documentation is generated. It should point to the same folder your jsdoc --destination conf. But make sure that it is relative to the path where you cloned better-docs.
  • DOCS - list of folders from your original repo what you want to watch for changes. Separated by comma.
cd better-docs
DOCS_COMMAND='npm run docs' DOCS=../src/**/*,../config/**/* DOCS_OUTPUT=../docs cd better-docs && gulp

The script should launch the browser and refresh it whenever you change something in the template or in DOCS.

Setting up the jsdoc in your project

If you want to see how to setup jsdoc in your project - take a look at these brief tutorials:

License

better-docs is Copyright ยฉ 2019 SoftwareBrothers.co. It is free software and may be redistributed under the terms specified in the LICENSE file - MIT.

About SoftwareBrothers.co

We're an open, friendly team that helps clients from all over the world to transform their businesses and create astonishing products.

  • We are available for hire.
  • If you want to work for us - check out the career page.

More Repositories

1

adminjs

AdminJS is an admin panel for apps written in node.js
TypeScript
8,143
star
2

active_skin

Flat skin for active admin.
Sass
425
star
3

adminjs-nestjs

NestJS module to import admin the Nest way
TypeScript
141
star
4

fabricjs-viewport

allows zooming and viewport manipulation in fabricjs
CoffeeScript
128
star
5

adminjs-example-app

Example application for AdminJS
TypeScript
97
star
6

adminjs-dev

Development environment for AdminJS
HTML
46
star
7

adminjs-prisma

TypeScript
44
star
8

adminjs-expressjs

This is an official AdminJS plugin which integrates it to expressjs framework.
TypeScript
43
star
9

adminjs-sequelizejs

Sequelizejs adapter for AdminBro
TypeScript
27
star
10

adminjs-design-system

DesignSystem on which AdminJS is based on
TypeScript
26
star
11

boxmodel-rails

Provides a pack of css utility classes to set paddings, margins and borders without writting css code
Ruby
23
star
12

adminjs-hapijs

Hapijs integration for AdminJS
TypeScript
20
star
13

adminjs-upload

AdminJS Feature - Upload Files
TypeScript
17
star
14

android-base

android base project with registration
Java
16
star
15

hapijs-mongoose-app-bootstrap

Base application using hapijs and mongoose with JWT auth
JavaScript
16
star
16

rails_admin_softwarebrothers_theme

rails_admin theme used in SoftwareBrothers
Ruby
15
star
17

adminjs-mongoose

Mongoose adapter for AdminJS
TypeScript
15
star
18

example-design-system

This is an example JSDoc generated documentation for Vue app:
Vue
15
star
19

forfeater

Ordering food inside your company
JavaScript
12
star
20

i18n-structure

It adds support of nice and nifty structure of locale files to your Rails app (along with helper methods)
Ruby
12
star
21

mailinger

TypeScript
12
star
22

forfeater-vue

Ordering food inside your company - frontend
Vue
9
star
23

admin-bro-theme-dark

Dark theme for AdminBro
JavaScript
9
star
24

xcode-project-template

The official project template of the SoftwareBrothers iOS team. This template should be the common base for all new projects and ensures common project structure and foundation classes.
Swift
9
star
25

react-native-hapijs-client

Client application for hapijs backend written in React Native
JavaScript
9
star
26

ios-utils

Set of helpful protocols, classes, extensions etc. used in iOS projects at SoftwareBrothers
Swift
8
star
27

business-intelligence

HTML
8
star
28

adminjs-koa

Koa plugin for AdminBro
TypeScript
7
star
29

aws-lambda-static-page

AWS Lambda - single, static page generator using PUG and SCSS
JavaScript
7
star
30

nest-mongo-boilerplate

TypeScript
7
star
31

adminjs-fastify

TypeScript
6
star
32

adminjs-sql

TypeScript
6
star
33

nest-typeorm-boilerplate

TypeScript
5
star
34

sb-starter-react-native

Software Brothers React Native Starter Kit
JavaScript
4
star
35

worklog-monitor-api

TypeScript
3
star
36

adminjs-themes

Themes set for AdminJS
TypeScript
3
star
37

adminjs-docs

3
star
38

forfeater-v2

Forfeater in Nestjs
TypeScript
3
star
39

admin-bro-hasura

TypeScript
2
star
40

adminjs-frontend

Frontend for AdminJS Core
2
star
41

worklog-monitor-ui

TypeScript
2
star
42

admin-bro-extension-template

Extension template for AdminBro
JavaScript
2
star
43

app-bootstrap

2
star
44

leaderator-extension

Chrome extension for leaderator
2
star
45

admin-bro-e2e

Cypress e2e tests for Admin-Bro
JavaScript
2
star
46

adminjs-firebase-functions

Plugin which renders admin panel on firebase cloud functions.
TypeScript
2
star
47

adminjs-import-export

TypeScript
2
star
48

proxi-cypress-e2e

JavaScript
1
star
49

adminjs-changelog

Official AdminJS changelogs
1
star
50

adminjs-feature-template

TypeScript
1
star
51

worklog-monitor-infra

Makefile
1
star
52

adminjs-relations

Handle resource relations
TypeScript
1
star
53

codewars-api

Codewars League - api
TypeScript
1
star
54

adminjs-passwords

AdminJS feature for hashing passwords
TypeScript
1
star
55

adminjs-bundler

A bundling script for CI/CD to use with AdminJS
TypeScript
1
star
56

codewars-frontend

TypeScript
1
star
57

seleniumGHActionsCheck

Project was created to check github actions possibilities for selenium
JavaScript
1
star
58

nest-firebase-functions

Basic setup for Nest to work with Firebase Functions
TypeScript
1
star
59

adminjs-logger

Logger resource for AdminBro actions
TypeScript
1
star
60

adminjs-custom-components

TypeScript
1
star
61

adminjs-objection

TypeScript
1
star
62

adminjs-e2e-tests

AdminJS e2e test with cypress
JavaScript
1
star
63

hapi-app-bootstrap

SoftwareBrothers app bootstrap: hapi
JavaScript
1
star
64

adminjs-leaflet

TypeScript
1
star
65

Travis_BS_CI_CD

JavaScript
1
star
66

adminjs-common

Common utilities and tools used across AdminJS frontend and core libraries (v7+)
1
star