Skip to content

Commit

Permalink
feat(core): support render all examples for overview (#389)
Browse files Browse the repository at this point in the history
* feat(core): support render all examples for overview

* refactor: rename test title
  • Loading branch information
why520crazy committed Aug 17, 2022
1 parent 33f46bc commit d61f728
Show file tree
Hide file tree
Showing 12 changed files with 127 additions and 13 deletions.
3 changes: 3 additions & 0 deletions packages/a-lib/button/doc/zh-cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,6 @@ import { AlibButtonModule } from "a-lib/button";
```html
<alib-button alibType="primary">按钮</alib-button>
```


<examples />
19 changes: 19 additions & 0 deletions packages/core/src/builders/doc-file.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,25 @@ describe('DocSourceFile', () => {
});
});

it('should rewrite file content', async () => {
await docgeniHost.writeFile(
'docs/getting-started.md',
`---${EOL}title: Title FrontMatter${EOL}order: 10${EOL}path: /custom/path${EOL}---${EOL}getting-started content`
);
const docSourceFile = new DocSourceFile(
{
cwd: root,
path: 'docs/getting-started.md',
base: root,
locale: 'zh-cn'
},
docgeniHost
);
await docSourceFile.build();
await docSourceFile.rewrite(docSourceFile.content + 'append-content');
expect(docSourceFile.output).toContain(`append-content`);
});

it('should emit file success', async () => {
const fileAbsPath = `${root}docs/getting-started.md`;
await docgeniHost.writeFile(fileAbsPath, `content`);
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/builders/doc-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ export class DocSourceFile<TMeta extends DocMeta = DocMeta> {
this.headings = result.headings;
}

public async rewrite(content: string) {
this.output = content;
}

public async emit(destRootPath: string) {
if (this.emitted) {
return {};
Expand Down
32 changes: 32 additions & 0 deletions packages/core/src/builders/library-component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,38 @@ describe('#library-component', () => {
);
});

it('should build overview success', async () => {
const component = new LibraryComponentImpl(context, library, 'button', `${DEFAULT_TEST_ROOT_PATH}/alib/button`);
expect(component.getOverviewContent('zh-cn')).toBeFalsy();
expect(component.getOverviewContent('en-us')).toBeFalsy();
await component.build();
expect(component.getOverviewContent('zh-cn')).toContain('这是一个按钮');
expect(component.getOverviewContent('en-us')).toContain('This is button');
});

it('should build overview with examples', async () => {
const component = new LibraryComponentImpl(context, library, 'button', `${DEFAULT_TEST_ROOT_PATH}/alib/button`);
await writeFilesToHost(context.host, {
[`${buttonDirPath}/doc/zh-cn.md`]: `${fixture.src['doc/zh-cn.md']}\n<examples />`,
[`${buttonDirPath}/doc/en-us.md`]: `${fixture.src['doc/en-us.md']}\n<examples />`
});
expect(component.getOverviewContent('zh-cn')).toBeFalsy();
expect(component.getOverviewContent('en-us')).toBeFalsy();
await component.build();
expect(component.getOverviewContent('en-us')).toContain(
'<example title="New Basic" name="alib-button-basic-example"></example>'
);
expect(component.getOverviewContent('en-us')).toContain(
'<example title="Advance" name="alib-button-advance-example"></example> '
);
expect(component.getOverviewContent('zh-cn')).toContain(
'<example title="New Basic" name="alib-button-basic-example"></example>'
);
expect(component.getOverviewContent('zh-cn')).toContain(
'<example title="Advance" name="alib-button-advance-example"></example> '
);
});

it('should emit lib component success', async () => {
const component = new LibraryComponentImpl(context, library, 'button', `${DEFAULT_TEST_ROOT_PATH}/alib/button`);
expect(component.getDocItem('zh-cn')).toBeFalsy();
Expand Down
33 changes: 30 additions & 3 deletions packages/core/src/builders/library-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { FileEmitter } from './emitter';
import { generateComponentExamplesModule } from './examples-module';

const NAMESPACE = 'library-builder';
const EXAMPLES_REGEX = /<examples\W*\/>/g;

export class LibraryComponentImpl extends FileEmitter implements LibraryComponent {
public name: string;
Expand Down Expand Up @@ -67,8 +68,8 @@ export class LibraryComponentImpl extends FileEmitter implements LibraryComponen
public async build(): Promise<void> {
this.resetEmitted();
await this.buildOverviews();
await this.buildApiDocs();
await this.buildExamples();
await this.buildApiDocs();
await this.buildDocItems();
}

Expand All @@ -86,6 +87,10 @@ export class LibraryComponentImpl extends FileEmitter implements LibraryComponen
return this.localeDocItemsMap[locale];
}

public getOverviewContent(locale: string): string {
return this.localeOverviewsMap[locale]?.output;
}

/**
* Get module key, `{libName}/{name}`
* example alib/button
Expand Down Expand Up @@ -124,9 +129,16 @@ export class LibraryComponentImpl extends FileEmitter implements LibraryComponen
}

private async buildOverview(docSourceFile: DocSourceFile) {
// this.hooks.buildDoc.call(docSourceFile);
await docSourceFile.build();
// this.hooks.buildDocSucceed.call(docSourceFile);
// await docSourceFile.build(content => {
// const examples = this.examples
// .map(example => {
// return `<example title="${example.title}" name="${example.key}"></example> \n`;
// })
// .join('\n');
// const newContent = content.replace(/<examples\W*\/>/g, `<dg-examples>\n${examples}\n</dg-examples>`);
// return newContent;
// });
}

private async tryGetApiDocsByManual(): Promise<Record<string, ApiDeclaration[]>> {
Expand Down Expand Up @@ -235,6 +247,21 @@ export class LibraryComponentImpl extends FileEmitter implements LibraryComponen
examples: this.examples,
examplesModule: examplesModuleName
});

for (const key in this.localeOverviewsMap) {
if (Object.prototype.hasOwnProperty.call(this.localeOverviewsMap, key)) {
const overviewSourceFile = this.localeOverviewsMap[key];
if (overviewSourceFile.output.match(EXAMPLES_REGEX)) {
const examples = this.examples
.map(example => {
return `<example title="${example.title}" name="${example.key}"></example> \n`;
})
.join('\n');
const newContent = overviewSourceFile.output.replace(EXAMPLES_REGEX, `<dg-examples>\n${examples}\n</dg-examples>`);
overviewSourceFile.rewrite(newContent);
}
}
}
}

private async buildExample(exampleName: string, moduleName: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export class ComponentViewerComponent implements OnInit {
@HostBinding(`class.dg-component-viewer`) isDocViewer = true;

@Input() docItem: ComponentDocItem;

constructor() {}

ngOnInit(): void {}
Expand Down
10 changes: 7 additions & 3 deletions packages/template/src/services/dom-portal-outlet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export class DomPortalOutlet implements PortalOutlet {
protected projectableNodes: any[][]
) {}

attach<T>(portal: ComponentPortal<T>) {
attach<T>(portal: ComponentPortal<T>, replace: boolean = false): ComponentRef<T> {
const resolver = portal.componentFactoryResolver || this.componentFactoryResolver;
const componentFactory = resolver.resolveComponentFactory(portal.component);
let componentRef: ComponentRef<T>;
Expand Down Expand Up @@ -132,8 +132,12 @@ export class DomPortalOutlet implements PortalOutlet {
}
// At this point the component has been instantiated, so we move it to the location in the DOM
// where we want it to be rendered.
this.outletElement.replaceWith(this.getComponentRootNode(componentRef));
// this.outletElement.appendChild(this._getComponentRootNode(componentRef));
if (replace) {
this.outletElement.replaceWith(this.getComponentRootNode(componentRef));
} else {
this.outletElement.appendChild(this.getComponentRootNode(componentRef));
}
//
this.attachedPortal = portal;

return componentRef;
Expand Down
18 changes: 17 additions & 1 deletion packages/template/src/services/toc.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,25 @@ export class TocService {
}

generateToc(docViewerContent: HTMLElement, scrollContainer = '.dg-scroll-container') {
const headers = Array.from<HTMLHeadingElement>(docViewerContent.querySelectorAll('h1, h2, h3, h4'));
const headers = Array.from<HTMLHeadingElement>(docViewerContent.querySelectorAll('h1, h2, h3, h4, dg-examples'));
const links: TocLink[] = [];
headers.forEach(header => {
if (header.tagName === 'DG-EXAMPLES') {
const allExamples = header.querySelectorAll('example');
const headerLevel = 2;
allExamples.forEach(example => {
links.push({
name: example.getAttribute('title'),
type: 'h2',
top: example.getBoundingClientRect().top,
id: example.getAttribute('name'),
active: false,
level: headerLevel,
element: example as HTMLHeadingElement
});
});
return;
}
// remove the 'TocLink' icon name from the inner text
const name = header.innerText.trim().replace(/^TocLink/, '');
const { top } = header.getBoundingClientRect();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export class ContentViewerComponent extends ContentRenderer implements OnInit, O
this.elementRef.nativeElement.innerHTML = content;
this.loadComponents('example', ExampleViewerComponent);
getBuiltInComponents().forEach(item => {
this.loadComponents(item.selector, item.component);
this.loadComponents(item.selector, item.component, true);
});

this.cdr.markForCheck();
Expand All @@ -78,14 +78,14 @@ export class ContentViewerComponent extends ContentRenderer implements OnInit, O
}
}

private loadComponents(selector: string, componentClass: Type<unknown>) {
private loadComponents(selector: string, componentClass: Type<unknown>, replace: boolean = false) {
const exampleElements = this.elementRef.nativeElement.querySelectorAll(selector);
Array.prototype.slice.call(exampleElements).forEach((element: Element) => {
const portalHost = new DomPortalOutlet(element, this.componentFactoryResolver, this.appRef, this.injector, [
element.childNodes as any
]);
const examplePortal = new ComponentPortal(componentClass, this.viewContainerRef);
const exampleViewerRef = portalHost.attach(examplePortal);
const exampleViewerRef = portalHost.attach(examplePortal, replace);
// 循环设置属性
for (const attributeKey in element.attributes) {
if (Object.prototype.hasOwnProperty.call(element.attributes, attributeKey)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
display: block;
padding: 20px 0px;

&:target {
.dg-example-viewer-wrapper {
border-color: $dg-primary;
}
}
&.dg-example-viewer-inline {
padding: 10px 0px;
.dg-example-viewer-wrapper {
Expand All @@ -37,7 +42,7 @@

.dg-example-viewer-wrapper {
border: 1px solid $dg-border-color;
// box-shadow: 0 0 10px -4px rgba(0, 0, 0, 0.1);
border-radius: 2px;
}

.dg-example-viewer-header {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ const nameOrdersMap = {

@Component({
selector: 'dg-example-viewer',
templateUrl: './example-viewer.component.html'
templateUrl: './example-viewer.component.html',
host: {
'[attr.id]': 'example?.key'
}
})
export class ExampleViewerComponent implements OnInit {
private _inline = false;
Expand Down
2 changes: 1 addition & 1 deletion packages/template/src/styles/variables.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
$dg-primary: #348fe4 !default;
$dg-primary: #6698ff !default;
$dg-primary-light: #246eff;
$dg-success: #66c060 !default; // 2dbcff
$dg-info: #2dbcff !default;
Expand Down

0 comments on commit d61f728

Please sign in to comment.