runem / web-component-analyzer

CLI that analyzes web components and emits documentation
https://runem.github.io/web-component-analyzer
MIT License
504 stars 64 forks source link

Add default value to json formatter #117

Closed steel closed 4 years ago

runem commented 4 years ago

Thank you very much for your contribution! :tada: I have three considerations before merging this PR.

  1. I'm in doubt if the **required** value for the default field is the best way to go. In that case I would rather a separate field called required, and I think that should be done for another PR.
  2. In case of no default value, I think the value of default should be undefined and not the empty string literal.
  3. I also think "attributes" should have a default field.
steel commented 4 years ago

Yep agree with those. I wasn't thinking and just copied over some stuff from the markdown formatter.

I've updated the PR and addressed all 3 concerns.

steel commented 4 years ago

I'm using your example in your readme:

/**
 * Here is a description of my web component.
 * 
 * @element my-element
 * 
 * @fires change - This jsdoc tag makes it possible to document events.
 * @fires submit
 * 
 * @attr {Boolean} disabled - This jsdoc tag documents an attribute.
 * @attr {on|off} switch - Here is an attribute with either the "on" or "off" value.
 * @attr my-attr
 * 
 * @prop value
 * 
 * @slot - This is an unnamed slot (the default slot)
 * @slot start - This is a slot named "start".
 * @slot end
 * 
 * @cssprop --main-bg-color - This jsdoc tag can be used to document css custom properties.
 * @cssprop --main-color
 */
class MyElement extends HTMLElement {

 /**
  * This is a description of a property with an attribute with exactly the same name: "color".
  * @type {"red"|"green"|"blue"}
  * @attr
  */
  color = "red";
}

JSON output:

  "version": 2,
  "tags": [
    {
      "name": "my-element",
      "description": "Here is a description of my web component.",
      "jsDoc": "/**\n * Here is a description of my web component.\n * \n * @element my-element\n * \n * @fires change - This jsdoc tag makes it possible to document events.\n * @fires submit\n * \n * @attr {Boolean} disabled - This jsdoc tag documents an attribute.\n * @attr {on|off} switch - Here is an attribute with either the \"on\" or \"off\" value.\n * @attr my-attr\n * \n * @prop value\n * \n * @slot - This is an unnamed slot (the default slot)\n * @slot start - This is a slot named \"start\".\n * @slot end\n * \n * @cssprop --main-bg-color - This jsdoc tag can be used to document css custom properties.\n * @cssprop --main-color\n */",
      "attributes": [
        {
          "name": "disabled",
          "description": "This jsdoc tag documents an attribute.",
          "type": "boolean"
        },
        {
          "name": "switch",
          "description": "Here is an attribute with either the \"on\" or \"off\" value.",
          "type": "\"on\" | \"off\""
        },
        {
          "name": "my-attr",
          "type": "any"
        },
        {
          "name": "color",
          "description": "This is a description of a property with an attribute with exactly the same name: \"color\".",
          "jsDoc": "/**\n  * This is a description of a property with an attribute with exactly the same name: \"color\".\n  * @type {\"red\"|\"green\"|\"blue\"}\n  * @attr\n  */",
          "type": "\"red\" | \"green\" | \"blue\"",
          "default": "\"red\"",
          "required": false
        }
      ],
      "properties": [
        {
          "name": "value",
          "type": "any"
        },
        {
          "name": "color",
          "description": "This is a description of a property with an attribute with exactly the same name: \"color\".",
          "jsDoc": "/**\n  * This is a description of a property with an attribute with exactly the same name: \"color\".\n  * @type {\"red\"|\"green\"|\"blue\"}\n  * @attr\n  */",
          "type": "\"red\" | \"green\" | \"blue\"",
          "default": "\"red\"",
          "required": false
        },
        {
          "name": "options",
          "type": "{}",
          "default": "{}",
          "required": false
        },
        {
          "name": "Object",
          "description": "This is a description of a property with an attribute called \"my-prop\".",
          "jsDoc": "/**\n   * This is a description of a property with an attribute called \"my-prop\".\n   * @type {number}\n   * @deprecated\n   */",
          "type": "number",
          "required": false
        }
      ],
      "events": [
        {
          "name": "submit"
        },
        {
          "name": "change",
          "description": "This jsdoc tag makes it possible to document events."
        }
      ],
      "slots": [
        {
          "name": "end"
        },
        {
          "name": "start",
          "description": "This is a slot named \"start\"."
        },
        {
          "name": "",
          "description": "This is an unnamed slot (the default slot)"
        }
      ],
      "cssProperties": [
        {
          "name": "--main-color"
        },
        {
          "name": "--main-bg-color",
          "description": "This jsdoc tag can be used to document css custom properties."
        }
      ]
    }
  ]
}
runem commented 4 years ago

Thanks! A final request before merging: would it be possible to have the value of required be "undefined" when required is false? (eg. required: member.required || undefined). I think required should not be present in the JSON output if it's false.

steel commented 4 years ago

Done.

I also fixed another issue where attributes defined in observedAttributes are not being merged and don't report the description and types correctly.

kylewelsby commented 4 years ago

it would be great to add CSSProp default while were at this.

steel commented 4 years ago

I decided to go another route and write my own analyzer using JSDoc directly. https://github.com/steel/custom-element-analyzer

runem commented 4 years ago

@kylewelsby I like your suggestion very much. I added support for it in the PR https://github.com/runem/web-component-analyzer/pull/127 :-) That PR includes a much better jsdoc parser that among other things supports default jsdoc notation like this:

/**
 * @cssprop [--bg-color=red] - The background color
 */
class MyElement extends HTMLElement {
   ...
}

You can test that version using the 1.0.0-next.4 beta npm publish:

npx web-component-analyzer@1.0.0-next.4 analyze my-element.js --format json

@steel I'm sorry I haven't had time responding to this PR. It started out as adding default value to JSON formatter, but it expanded with more functionality such as adding required and observedAttributes merge fix. Another time it would be easier for me to expedite if it were 3 different PR's :-) Also, the tests are failing, and I haven't had time looking into if the snapshot diff is what we want. The merging of attributes related to observedAttributes actually digs much deeper than just the jsdoc and default fields. In order to fix it 100% we e.g. have take into account the order of merging. To address the before mentioned (including the jsdoc parsing), I had to refactor the architecture of the analyzer. I've spend the past 3 weeks doing it, I'm almost done, and it looks great! You can read more about my thoughts and actions here https://github.com/runem/web-component-analyzer/issues/125

runem commented 4 years ago

I'll close this PR now as these all these features/fixes are now on master :+1: