Skip to content

Commit

Permalink
Merge pull request #11016 from matheo/feat/compodoc-classes
Browse files Browse the repository at this point in the history
Addon-docs: Angular ArgTypes for pipes, injectables, classes
  • Loading branch information
shilman authored Jun 3, 2020
2 parents 0cd00c7 + 0233802 commit 6efa4cc
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 12 deletions.
38 changes: 30 additions & 8 deletions addons/docs/src/frameworks/angular/compodoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, PropDef[]>;

Expand Down Expand Up @@ -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'");
Expand All @@ -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) {
Expand Down Expand Up @@ -137,13 +151,21 @@ const extractDefaultValue = (property: Property) => {
}
};

export const extractArgTypesFromData = (componentData: Directive) => {
export const extractArgTypesFromData = (componentData: Class | Directive | Injectable | Pipe) => {
const sectionToItems: Record<string, ArgType[]> = {};
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);
Expand Down Expand Up @@ -205,5 +227,5 @@ export const extractComponentDescription = (component: Component | Directive) =>
if (!componentData) {
return null;
}
return componentData.rawdescription;
return componentData.rawdescription || componentData.description;
};
41 changes: 37 additions & 4 deletions addons/docs/src/frameworks/angular/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -39,4 +69,7 @@ export interface Decorator {
export interface CompodocJson {
directives: Directive[];
components: Component[];
pipes: Pipe[];
injectables: Injectable[];
classes: Class[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Storyshots DocInjectable Basic 1`] = `
<storybook-dynamic-app-root
cfr={[Function CodegenComponentFactoryResolver]}
data={[Function Object]}
target={[Function ViewContainerRef_]}
>
<ng-component>
<div>
<h1>
DocInjectable
</h1>
</div>
</ng-component>
</storybook-dynamic-app-root>
`;
Original file line number Diff line number Diff line change
@@ -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 [];
}
}
Original file line number Diff line number Diff line change
@@ -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: '<div><h1>DocInjectable</h1></div>',
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Storyshots DocPipe Basic 1`] = `
<storybook-dynamic-app-root
cfr={[Function CodegenComponentFactoryResolver]}
data={[Function Object]}
target={[Function ViewContainerRef_]}
>
<ng-component>
<div>
<h1>
DOCPIPE
</h1>
</div>
</ng-component>
</storybook-dynamic-app-root>
`;
18 changes: 18 additions & 0 deletions examples/angular-cli/src/stories/doc-pipe/doc-pipe.pipe.ts
Original file line number Diff line number Diff line change
@@ -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();
}
}
16 changes: 16 additions & 0 deletions examples/angular-cli/src/stories/doc-pipe/doc-pipe.stories.ts
Original file line number Diff line number Diff line change
@@ -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: `<div><h1>{{ 'DocPipe' | docPipe }}</h1></div>`,
});

0 comments on commit 6efa4cc

Please sign in to comment.