Skip to content

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 (Demos). The button in its corner shows the demo fullscreen, centred at the size of the screen; press Esc or the button again to leave. Browsers that don't support fullscreen don't show the button.

 Use it

Add the component to the demos of the page, as for a demo (Demos [Use it]), then render it with the demoPane action:

index.mdTwig
{{ NgDocActions.demoPane("ButtonDemoComponent") }}

 Options

Pass options as the second argument of demoPane. They follow NgDocDemoPaneActionOptions:

OptionTypeDefaultDescription
expandedbooleanfalseOpens the code pane from the start.
defaultTabstring–The source tab to open first, such as HTML.
tabsstring | string[]AllThe source tabs to show, by name.
inputsRecord<string, unknown>–Values for the inputs of the demo component.
fullscreenRoutestring–Shows a link that opens the demo on its own page in a new tab, instead of the demo.
classstring | string[]–CSS classes for the demo pane element.

This demo pane opens with its code, and shows only the template:

index.mdTwig
{{ 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.

button-inline-demo.component.tsTypeScript
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');
}
index.mdTwig
{{ 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:

ng-doc.page.tsTypeScriptLines 8–13
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.

index.mdTwig
{{ 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.

ng-doc.page.tsTypeScriptLine 10
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:

styles.cssCSS
:root {
  --ng-doc-demo-pane-height: 320px;
  --ng-doc-pane-front-background: var(--ng-doc-background);
}
VariableDefaultDescription
--ng-doc-demo-pane-heightThe height of the contentA fixed height for demo panes.
--ng-doc-demo-pane-margin--ng-doc-page-block-marginThe space above and below a demo pane. Set it on body.
--ng-doc-pane-border1px solid var(--ng-doc-border-color)The border of the demo pane and of both panes.
--ng-doc-pane-background--ng-doc-base-1The background of both panes.
--ng-doc-pane-front-background--ng-doc-pane-backgroundThe background of the demo pane.
--ng-doc-pane-back-background--ng-doc-pane-backgroundThe background of the code pane.
--ng-doc-pane-front-border--ng-doc-pane-borderThe border of the demo pane.
--ng-doc-pane-back-border--ng-doc-pane-borderThe border of the code pane.
--ng-doc-pane-content-min-width200pxThe 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:

index.mdTwig
{{ NgDocActions.demoPane("ButtonDemoComponent", { class: "tall-pane" }) }}
styles.cssCSS
.tall-pane {
  --ng-doc-demo-pane-height: 480px;
}

 Gotchas

Note

A demo pane opens on defaultTab or on the first tab. Unlike a demo, it ignores the opened parameter of snippets (Snippets [Opened by default]).

Next: Snippets

Edit this page