From b10834c83d83a6e0a3cc3f39046d73f8c312b2d7 Mon Sep 17 00:00:00 2001 From: Mateo Tibaquira Date: Tue, 2 Jun 2020 01:21:30 -0500 Subject: [PATCH 1/2] feat(docs): extract ArgTypes for Angular pipes, injectables and classes --- .../docs/src/frameworks/angular/compodoc.ts | 38 +++++++++++++---- addons/docs/src/frameworks/angular/types.ts | 41 +++++++++++++++++-- 2 files changed, 67 insertions(+), 12 deletions(-) diff --git a/addons/docs/src/frameworks/angular/compodoc.ts b/addons/docs/src/frameworks/angular/compodoc.ts index c1f9784d63c2..8810a8a799f2 100644 --- a/addons/docs/src/frameworks/angular/compodoc.ts +++ b/addons/docs/src/frameworks/angular/compodoc.ts @@ -4,8 +4,17 @@ import { PropDef } from '@storybook/components'; import { ArgType, ArgTypes } from '@storybook/api'; import { logger } from '@storybook/client-logger'; -import { string } from 'prop-types'; -import { Argument, CompodocJson, Component, Method, Property, Directive } from './types'; +import { + Argument, + Class, + CompodocJson, + Component, + Injectable, + Method, + Pipe, + Property, + Directive, +} from './types'; type Sections = Record; @@ -54,12 +63,14 @@ const mapPropertyToSection = (key: string, item: Property) => { const mapItemToSection = (key: string, item: Method | Property): string => { switch (key) { + case 'methods': case 'methodsClass': return 'methods'; case 'inputsClass': return 'inputs'; case 'outputsClass': return 'outputs'; + case 'properties': case 'propertiesClass': if (isMethod(item)) { throw new Error("Cannot be of type Method if key === 'propertiesClass'"); @@ -72,7 +83,10 @@ const mapItemToSection = (key: string, item: Method | Property): string => { export const findComponentByName = (name: string, compodocJson: CompodocJson) => compodocJson.components.find((c: Component) => c.name === name) || - compodocJson.directives.find((c: Directive) => c.name === name); + compodocJson.directives.find((c: Directive) => c.name === name) || + compodocJson.pipes.find((c: Pipe) => c.name === name) || + compodocJson.injectables.find((c: Injectable) => c.name === name) || + compodocJson.classes.find((c: Class) => c.name === name); const getComponentData = (component: Component | Directive) => { if (!component) { @@ -137,13 +151,21 @@ const extractDefaultValue = (property: Property) => { } }; -export const extractArgTypesFromData = (componentData: Directive) => { +export const extractArgTypesFromData = (componentData: Class | Directive | Injectable | Pipe) => { const sectionToItems: Record = {}; - const compodocClasses = ['propertiesClass', 'methodsClass', 'inputsClass', 'outputsClass']; - type COMPODOC_CLASS = 'propertiesClass' | 'methodsClass' | 'inputsClass' | 'outputsClass'; + const compodocClasses = ['component', 'directive'].includes(componentData.type) + ? ['propertiesClass', 'methodsClass', 'inputsClass', 'outputsClass'] + : ['properties', 'methods']; + type COMPODOC_CLASS = + | 'properties' + | 'methods' + | 'propertiesClass' + | 'methodsClass' + | 'inputsClass' + | 'outputsClass'; compodocClasses.forEach((key: COMPODOC_CLASS) => { - const data = componentData[key] || []; + const data = (componentData as any)[key] || []; data.forEach((item: Method | Property) => { const section = mapItemToSection(key, item); const defaultValue = isMethod(item) ? undefined : extractDefaultValue(item as Property); @@ -205,5 +227,5 @@ export const extractComponentDescription = (component: Component | Directive) => if (!componentData) { return null; } - return componentData.rawdescription; + return componentData.rawdescription || componentData.description; }; diff --git a/addons/docs/src/frameworks/angular/types.ts b/addons/docs/src/frameworks/angular/types.ts index 9bc7f760c852..9f7e64afbabf 100644 --- a/addons/docs/src/frameworks/angular/types.ts +++ b/addons/docs/src/frameworks/angular/types.ts @@ -2,26 +2,56 @@ export interface Method { name: string; args: Argument[]; returnType: string; - decorators: Decorator[]; - description: string; + decorators?: Decorator[]; + description?: string; } export interface Property { name: string; - decorators: Decorator[]; + decorators?: Decorator[]; type: string; optional: boolean; defaultValue?: string; description?: string; } +export interface Class { + name: string; + ngname: string; + type: 'pipe'; + properties: Property[]; + methods: Method[]; + description?: string; + rawdescription?: string; +} + +export interface Injectable { + name: string; + type: 'injectable'; + properties: Property[]; + methods: Method[]; + description?: string; + rawdescription?: string; +} + +export interface Pipe { + name: string; + type: 'class'; + properties: Property[]; + methods: Method[]; + description?: string; + rawdescription?: string; +} + export interface Directive { name: string; + type: 'directive' | 'component'; propertiesClass: Property[]; inputsClass: Property[]; outputsClass: Property[]; methodsClass: Method[]; - rawdescription: string; + description?: string; + rawdescription?: string; } export type Component = Directive; @@ -39,4 +69,7 @@ export interface Decorator { export interface CompodocJson { directives: Directive[]; components: Component[]; + pipes: Pipe[]; + injectables: Injectable[]; + classes: Class[]; } From 02338023b6b49f1f7ffb323f64c76b12b7d18521 Mon Sep 17 00:00:00 2001 From: Mateo Tibaquira Date: Wed, 3 Jun 2020 03:09:00 -0500 Subject: [PATCH 2/2] feat(examples): added dummy pipe and injectable to show their props --- .../doc-injectable.stories.storyshot | 17 ++++++++++++ .../doc-injectable/doc-injectable.service.ts | 27 +++++++++++++++++++ .../doc-injectable/doc-injectable.stories.ts | 16 +++++++++++ .../__snapshots__/doc-pipe.stories.storyshot | 17 ++++++++++++ .../src/stories/doc-pipe/doc-pipe.pipe.ts | 18 +++++++++++++ .../src/stories/doc-pipe/doc-pipe.stories.ts | 16 +++++++++++ 6 files changed, 111 insertions(+) create mode 100644 examples/angular-cli/src/stories/doc-injectable/__snapshots__/doc-injectable.stories.storyshot create mode 100644 examples/angular-cli/src/stories/doc-injectable/doc-injectable.service.ts create mode 100644 examples/angular-cli/src/stories/doc-injectable/doc-injectable.stories.ts create mode 100644 examples/angular-cli/src/stories/doc-pipe/__snapshots__/doc-pipe.stories.storyshot create mode 100644 examples/angular-cli/src/stories/doc-pipe/doc-pipe.pipe.ts create mode 100644 examples/angular-cli/src/stories/doc-pipe/doc-pipe.stories.ts diff --git a/examples/angular-cli/src/stories/doc-injectable/__snapshots__/doc-injectable.stories.storyshot b/examples/angular-cli/src/stories/doc-injectable/__snapshots__/doc-injectable.stories.storyshot new file mode 100644 index 000000000000..d3a6a62dc02a --- /dev/null +++ b/examples/angular-cli/src/stories/doc-injectable/__snapshots__/doc-injectable.stories.storyshot @@ -0,0 +1,17 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots DocInjectable Basic 1`] = ` + + +
+

+ DocInjectable +

+
+
+
+`; diff --git a/examples/angular-cli/src/stories/doc-injectable/doc-injectable.service.ts b/examples/angular-cli/src/stories/doc-injectable/doc-injectable.service.ts new file mode 100644 index 000000000000..b6ad136fec33 --- /dev/null +++ b/examples/angular-cli/src/stories/doc-injectable/doc-injectable.service.ts @@ -0,0 +1,27 @@ +import { Injectable } from '@angular/core'; +import { HttpHeaders } from '@angular/common/http'; + +/** + * This is an Angular Injectable + * example that has a Prop Table. + */ +@Injectable({ + providedIn: 'root', +}) +export class DocInjectableService { + /** + * Auth headers to use. + */ + auth: any; + + constructor() { + this.auth = new HttpHeaders({ 'Content-Type': 'application/json' }); + } + + /** + * Get posts from Backend. + */ + getPosts() { + return []; + } +} diff --git a/examples/angular-cli/src/stories/doc-injectable/doc-injectable.stories.ts b/examples/angular-cli/src/stories/doc-injectable/doc-injectable.stories.ts new file mode 100644 index 000000000000..bb576e74f509 --- /dev/null +++ b/examples/angular-cli/src/stories/doc-injectable/doc-injectable.stories.ts @@ -0,0 +1,16 @@ +import { DocInjectableService } from './doc-injectable.service'; + +export default { + title: 'DocInjectable', + component: DocInjectableService, + parameters: { docs: { iframeHeight: 120 } }, +}; + +const modules = { + provider: [DocInjectableService], +}; + +export const Basic = () => ({ + moduleMetadata: modules, + template: '

DocInjectable

', +}); diff --git a/examples/angular-cli/src/stories/doc-pipe/__snapshots__/doc-pipe.stories.storyshot b/examples/angular-cli/src/stories/doc-pipe/__snapshots__/doc-pipe.stories.storyshot new file mode 100644 index 000000000000..87c448fce67e --- /dev/null +++ b/examples/angular-cli/src/stories/doc-pipe/__snapshots__/doc-pipe.stories.storyshot @@ -0,0 +1,17 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Storyshots DocPipe Basic 1`] = ` + + +
+

+ DOCPIPE +

+
+
+
+`; diff --git a/examples/angular-cli/src/stories/doc-pipe/doc-pipe.pipe.ts b/examples/angular-cli/src/stories/doc-pipe/doc-pipe.pipe.ts new file mode 100644 index 000000000000..6b7aca418a37 --- /dev/null +++ b/examples/angular-cli/src/stories/doc-pipe/doc-pipe.pipe.ts @@ -0,0 +1,18 @@ +import { Pipe, PipeTransform } from '@angular/core'; + +/** + * This is an Angular Pipe + * example that has a Prop Table. + */ +@Pipe({ + name: 'docPipe', +}) +export class DocPipe implements PipeTransform { + /** + * Transforms a string into uppercase. + * @param value string + */ + transform(value: string): string { + return value?.toUpperCase(); + } +} diff --git a/examples/angular-cli/src/stories/doc-pipe/doc-pipe.stories.ts b/examples/angular-cli/src/stories/doc-pipe/doc-pipe.stories.ts new file mode 100644 index 000000000000..55065c1688c7 --- /dev/null +++ b/examples/angular-cli/src/stories/doc-pipe/doc-pipe.stories.ts @@ -0,0 +1,16 @@ +import { DocPipe } from './doc-pipe.pipe'; + +export default { + title: 'DocPipe', + component: DocPipe, + parameters: { docs: { iframeHeight: 120 } }, +}; + +const modules = { + declarations: [DocPipe], +}; + +export const Basic = () => ({ + moduleMetadata: modules, + template: `

{{ 'DocPipe' | docPipe }}

`, +});