Documenting

To make your package easy to understand for other developers, you should provide some documentation. WebWriter can help by generating a manifest and readme file out of the structure and comments of your code.

Guidelines for documentation

  • Documentation is for developers! You can assume WebDev knowledge and should not include information about using the widgets’ UI, etc.
  • Documentation should be in English as a primary language.
  • Avoid duplication: Link to external resources where neccessary instead of reproducing them.
  • Use idiomatic solutions for JS/TS wherever possible (Type annotations, fitting and consistent method and field names, good JSDoc comments).

Generating documentation with @webwriter/build

The recommended approach for documenting packages is to include all documentation in the source code (JSDoc) and metadata (package.json). While this has limitations, it avoids duplication of documentation, which can easily become outdated when the package changes. With a tooling step, you can then generate API documentation for your package automatically. WebWriter’s build tool @webwriter/build enables this workflow.

Using the command npx @webwriter/build document in your package repository will generate two files:

  1. custom-elements.json is a machine-readable description of the custom elements in the package (the widgets). This can be used by external tooling, including the WebWriter website’s package playground.
  2. README.md is a human-readable description of the package. It is generated out of the package.json and the custom-elements.json from the previous step. The build tool will fall back to the name API.md if there is an existing README.md not generated by the build tool.

Source-level documentation

Including machine-readable metadata configured in your package.json (license, author, keywords, etc.) is highly recommended as a start since this not only can be used for a human-readable README file, but also helps tools such as package managers and WebWriter itself.

Additionally, all members of the package can be documented with structuring and comments in the source code.

Documenting snippets and themes

Snippets and themes are automatically listed in the README file using the exports and editingConfig from package.json.

{
    "exports": {
        "./snippets/webwriter-slides.html": "./src/snippets/webwriter-slides.html"
    }
}

Documenting widgets

The configured source files in exports (package.json) are considered the entry points for documenting each widget.

{
    "exports": {
        "./widgets/webwriter-slides.*": {
            "source": "./src/widgets/webwriter-slides.ts",
            "default": "./dist/widgets/webwriter-slides.*"
        },
        "./widgets/webwriter-slide.*": {
            "source": "./src/widgets/webwriter-slide.ts",
            "default": "./dist/widgets/webwriter-slide.*"
        },
    }
}

Using JSDoc comments, you can add descriptions to widgets.

Widget class with JSDoc comment.

/** Single slide for the `webwriter-slides` widget. */
@customElement("webwriter-slide")
export class WebwriterSlide extends LitElementWw {...}

Documenting widget fields and methods

You can document public widget fields (properties, including getters, and attributes) with a JSDoc description, the default value, type annotation (TypeScript only), and the property decorator (Lit only).

If you want certain fields to be ignored, you can set them as protected or private, or use the JSDoc annotation /** @internal */.

Widget field active with description, default value, and decorator providing infos for documentation.

/** Single slide for the `webwriter-slides` widget. */
@customElement("webwriter-slide")
export class WebwriterSlide extends LitElementWw {
  
  /** Whether the slide is selected/shown. */
  @property({type: Boolean, attribute: true, reflect: true})
  accessor active = false

  protected somePrivateStuff = true // This is ignored
}

Similarly, methods can have a JSDoc description, and default values as well as type annotations (TypeScript only) are also processed. Methods that are protected, private, or /** @internal */ are ignored.

Widget method nextSlide with description and annotated parameters.

/** Slideshow container for sequential display of content. */
@customElement("webwriter-slides")
export class WebwriterSlides extends LitElementWw {
  // ...
  /** Activate the next slide element. */
  nextSlide(backwards:boolean=false, step:number=1) {
    const i = this.activeSlideIndex
    const n = this.slides?.length - 1
    this.activeSlideIndex = backwards
      ? Math.max(0, i - step)
      : Math.min(n, i + step)
  }
  // ...
}

Documenting widget CSS variables, parts, and slots

The more advanced features of widgets such as CSS variables, parts, and slots should be annotated using JSDoc. You can refer to the analyzer tool’s reference for details.

You can also use JSDoc’s tags as an alternative to annotate the widget’s tag, description (summary), and properties/attributes.

JSDoc tags for CSS variables, parts, and slots.

/**
 * @summary This is MyWidget...
 *
 * @tag my-widget
 * @tagname my-widget
 * 
 * @attr {boolean} disabled - disables the widget
 * @attribute {string} foo - description for foo
 * 
 * @prop {boolean} prop1 - some description
 * @property {number} prop2 - some description
 * 
 * 
 * @csspart bar - Styles the color of bar
 *
 * @slot - This is a default/unnamed slot
 * @slot container - You can put some widgets here
 *
 * @cssprop --text-color - Controls the color of foo
 * @cssproperty [--background-color=red] - Controls the color of bar
 *
 * @fires custom-event - some description for custom-event
 * @fires {Event} typed-event - some description for typed-event
 * @event {CustomEvent} typed-custom-event - some description for typed-custom-event
 */
class MyWidget extends LitElementWw {...}