Demo pane
A demo pane shows a demo and its source side by side. The demo is in front; readers drag the handle between the panes to reveal the code behind it. Use it when the demo should come first, and the code is there for readers who want it.
See it
import { ChangeDetectionStrategy , Component , inject , input } from '@angular/core';
import { NgDocButtonComponent , NgDocColor } from '@ng-doc/ui-kit';
import { NgDocNotifyService } from '@ng-doc/ui-kit/services/notify';
@Component ({
selector: 'ng-doc-button-demo',
imports: [NgDocButtonComponent ],
templateUrl: './button-demo.component.html',
styleUrls: ['./button-demo.component.scss'],
changeDetection: ChangeDetectionStrategy .OnPush,
})
export class ButtonDemoComponent {
private readonly notifyService = inject (NgDocNotifyService );
readonly color = input <NgDocColor >('primary');
clickEvent(): void {
this.notifyService.notify('Button was clicked!');
}
}Drag the handle, or click it, to reveal the code. The handle also works with the keyboard: the arrow keys move it, and Enter or Space opens or closes the code pane. With several source files, the code pane shows them as tabs.
The demo sits on the same dotted canvas as a demo (
Use it
Add the component to the demos of the page, as for a demo (demoPane action:
{{ NgDocActions.demoPane("ButtonDemoComponent") }} Options
Pass options as the second argument of demoPane. They follow :
| Option | Type | Default | Description |
|---|---|---|---|
expanded | boolean | false | Opens the code pane from the start. |
defaultTab | string | – | The source tab to open first, such as HTML. |
tabs | string | string[] | All | The source tabs to show, by name. |
inputs | Record<string, unknown> | – | Values for the inputs of the demo component. |
fullscreenRoute | string | – | Shows a link that opens the demo on its own page in a new tab, instead of the demo. |
class | string | string[] | – | CSS classes for the demo pane element. |
This demo pane opens with its code, and shows only the template:
{{ NgDocActions.demoPane("ButtonDemoComponent", { expanded: true, tabs: ["HTML"] }) }}<button [color]="color()" (click)="clickEvent()" ng-doc-button-flat>Just a button</button>Inputs
Give the demo component inputs, and set them where you render the demo with the inputs option. One component can then show several variants.
import { ChangeDetectionStrategy , Component , input } from '@angular/core';
import { NgDocButtonComponent , NgDocColor } from '@ng-doc/ui-kit';
@Component ({
selector: 'ng-doc-button-inline-demo',
imports: [NgDocButtonComponent ],
template: `<button ng-doc-button [color]="color()">Button</button>`,
changeDetection: ChangeDetectionStrategy .OnPush,
})
export class ButtonInlineDemoComponent {
readonly color = input <NgDocColor >('primary');
}{{ NgDocActions.demoPane("ButtonInlineDemoComponent", { inputs: { color: "info" } }) }}import { ChangeDetectionStrategy , Component , input } from '@angular/core';
import { NgDocButtonComponent , NgDocColor } from '@ng-doc/ui-kit';
@Component ({
selector: 'ng-doc-button-inline-demo',
imports: [NgDocButtonComponent ],
template: `<button ng-doc-button [color]="color()">Button</button>`,
changeDetection: ChangeDetectionStrategy .OnPush,
})
export class ButtonInlineDemoComponent {
readonly color = input <NgDocColor >('primary');
}Open in a new tab
To let readers open a demo on its own page, add a child route for it to the route of the page in ng-doc.page.ts:
import { NgDocPage } from '@ng-doc/core';
import { ButtonDemoComponent } from './button-demo.component';
const MyAwesomePage: NgDocPage = {
title: 'MyAwesomePage',
mdFile: './index.md',
demos: { ButtonDemoComponent },
route: {
children: [
{
path: 'button',
component: ButtonDemoComponent,
},
],
},
};
export default MyAwesomePage;Then pass the path of the route as the fullscreenRoute option. A link that opens the route in a new tab replaces the demo. The route is a standalone page: the demo alone on the dotted canvas, with a small link back to the page in the corner, and without the navbar, the sidebar, the table of contents or the page content. Your app.html needs no changes for it, and the server renders and prerenders the route the same way.
{{ NgDocActions.demoPane("ButtonDemoComponent", { fullscreenRoute: "button" }) }}import { ChangeDetectionStrategy , Component , inject , input } from '@angular/core';
import { NgDocButtonComponent , NgDocColor } from '@ng-doc/ui-kit';
import { NgDocNotifyService } from '@ng-doc/ui-kit/services/notify';
@Component ({
selector: 'ng-doc-button-demo',
imports: [NgDocButtonComponent ],
templateUrl: './button-demo.component.html',
styleUrls: ['./button-demo.component.scss'],
changeDetection: ChangeDetectionStrategy .OnPush,
})
export class ButtonDemoComponent {
private readonly notifyService = inject (NgDocNotifyService );
readonly color = input <NgDocColor >('primary');
clickEvent(): void {
this.notifyService.notify('Button was clicked!');
}
}Disable fullscreen routes
To render the child routes of a page yourself, instead of as standalone pages, set disableFullscreenRoutes in ng-doc.page.ts. You will then need a <router-outlet /> in your page (for example in the demo).
By default disableFullscreenRoutes is false.
import { NgDocPage } from '@ng-doc/core';
import { MasterDetailComponent } from './master-detail.component';
import { MasterComponent } from './master.component';
import { DetailComponent } from './detail.component';
const MyAwesomePage: NgDocPage = {
title: 'MyAwesomePage',
mdFile: './index.md',
demos: { MasterDetailComponent },
disableFullscreenRoutes: true,
route: {
children: [
{
path: '',
component: MasterComponent,
},
{
path: ':id',
component: DetailComponent,
},
],
},
};
export default MyAwesomePage;Customization
Style every demo pane with CSS variables in your global styles:
:root {
--ng-doc-demo-pane-height: 320px;
--ng-doc-pane-front-background: var(--ng-doc-background);
}| Variable | Default | Description |
|---|---|---|
--ng-doc-demo-pane-height | The height of the content | A fixed height for demo panes. |
--ng-doc-demo-pane-margin | --ng-doc-page-block-margin | The space above and below a demo pane. Set it on body. |
--ng-doc-pane-border | 1px solid var(--ng-doc-border-color) | The border of the demo pane and of both panes. |
--ng-doc-pane-background | --ng-doc-base-1 | The background of both panes. |
--ng-doc-pane-front-background | --ng-doc-pane-background | The background of the demo pane. |
--ng-doc-pane-back-background | --ng-doc-pane-background | The background of the code pane. |
--ng-doc-pane-front-border | --ng-doc-pane-border | The border of the demo pane. |
--ng-doc-pane-back-border | --ng-doc-pane-border | The border of the code pane. |
--ng-doc-pane-content-min-width | 200px | The narrowest a pane can get. |
To style one demo pane, give it a class with the class option and set the variables on that class:
{{ NgDocActions.demoPane("ButtonDemoComponent", { class: "tall-pane" }) }}.tall-pane {
--ng-doc-demo-pane-height: 480px;
} Gotchas
NoteA demo pane opens on
defaultTabor on the first tab. Unlike a demo, it ignores theopenedparameter of snippets (Snippets [Opened by default] ).
Next: