Code tabs on previews

A preview's Code panel normally shows the Razor that rendered it. Put <CodeTab> children inside the preview and the panel shows those instead, one tab each. Use it when the reader's code isn't the code that drew the example : the same result in two syntaxes, or one live example documented for several platforms.

Rendered with Blazor
ShellDocs.Components
Layouts, chrome and the content primitives.
ShellDocs.Markdown
The Markdig pipeline and component slots.
ShellDocs.Core
Navigation graph and search index.
ShellDocs.Tokens
Design tokens as CSS variables.
<CardGrid Columns="2">
<Card Title="ShellDocs.Components" Description="Layouts, chrome and the content primitives." />
<Card Title="ShellDocs.Markdown" Description="The Markdig pipeline and component slots." />
<Card Title="ShellDocs.Core" Description="Navigation graph and search index." />
<Card Title="ShellDocs.Tokens" Description="Design tokens as CSS variables." />
</CardGrid>

Written as:

markdown
<DemoPreview Component="PackageFamilyDemo" Layout="stretch" SyncKey="syntax" Caption="Rendered with Blazor">
<CodeTab Label="Markdown">

```markdown
<CardGrid Columns="2">
<Card Title="ShellDocs.Components" Description="Layouts, chrome and the content primitives." />
</CardGrid>
```

</CodeTab>
<CodeTab Label="Razor">

```razor
<CardGrid Columns="2">
    @foreach (var package in Packages)
    {
        <Card Title="@package.Name" Description="@package.Summary" />
    }
</CardGrid>
```

</CodeTab>
</DemoPreview>

The rules

  • Each tab's code is the first fence inside it. The fence's language drives highlighting.
  • Without a fence, the tag's text is the code and Language="…" sets the language.
  • The Copy button copies the tab that is showing.
  • Without <CodeTab> children the Code panel shows the Razor source, as before.

Where they work

Prop Type Default Description
DemoPreview yes — The tabs replace the demo's .razor file in the Code panel.
ComponentPreview yes — The tabs are taken out of the body before it is passed to the component as child content.
IframePreview yes — Without tabs an iframe preview has no Code panel at all.
razor:preview fence no — The fence body is Razor, so a code fence can't sit inside it. Use DemoPreview instead.

Switching together

SyncKey works as it does on CodeGroup and Tabs. Every block with the same key switches together, on this page and on later ones, and the choice is saved in localStorage.

A missing tab

When a block has no tab for the current choice it says so and keeps its height, instead of jumping to another tab. Choose Razor in the first example, then look at this one:

ShellDocs.Components
Layouts, chrome and the content primitives.
ShellDocs.Markdown
The Markdig pipeline and component slots.
ShellDocs.Core
Navigation graph and search index.
ShellDocs.Tokens
Design tokens as CSS variables.
<CardGrid Columns="2">
<Card Title="ShellDocs.Components" Description="Layouts, chrome and the content primitives." />
</CardGrid>

Page switch

A page switch is a row of tabs on the page itself that drives a SyncKey. The Markdown | Razor row at the top of this page is one. Declare it once and it appears on every page whose blocks use that key:

csharp
builder.Services.AddShellDocs(o =>
{
    o.AddSyncSwitch("platform", "MAUI", "Avalonia");
});

It sits under the page header when RenderPageTitle is on, otherwise right above the first block that uses the key. Pages that don't use the key don't get one. The first option is the default until a reader picks another, so every block starts on the same tab.

To choose the spot yourself, write the tag. The automatic one is then left out on that page:

markdown
<SyncSwitch SyncKey="platform" />

For a key with no AddSyncSwitch, list the options on the tag. This page does that:

markdown
<SyncSwitch SyncKey="syntax" Options="Markdown, Razor" />
Prop Type Default Description
SyncKeyRequired string — The key the switch drives.
Options string? from AddSyncSwitch Comma-separated option labels. They must match the tab labels.

Caption

Caption adds a short muted note to the preview's toolbar, such as which platform rendered the example. The first preview on this page has one.

markdown
<DemoPreview Component="PackageFamilyDemo" Caption="Rendered with Blazor" />

ShellDocsOptions.PreviewCaption sets a caption for every preview on the site. A preview's own Caption replaces it.

csharp
o.PreviewCaption = "Rendered with Blazor";

From a Razor file

Outside markdown, pass the tabs as a parameter:

razor
<DemoPreview Component="PackageFamilyDemo"
             SyncKey="syntax"
             CodeTabs="@(new PreviewCodeTab[] { new("Markdown", markdownSource, "markdown") })" />

A PreviewCodeTab is a label, the code, and a language that defaults to text.

XAML

xaml and axaml fences are highlighted as XML. Sites created before 0.1.13-alpha need 'xml' in the langs list of the Shiki loader in App.razor.

Props

These are the same on DemoPreview, ComponentPreview and IframePreview.

Prop Type Default Description
SyncKey string? — Blocks with the same key switch together and remember the choice.
Caption string? PreviewCaption Muted note in the toolbar.
CodeTabs IReadOnlyList<PreviewCodeTab>? — The tabs, when the preview is written in a .razor file.

CodeTab inside a preview:

Prop Type Default Description
LabelRequired string — Tab label, and the value a SyncKey matches on.
Language string? text Highlighting language when the body has no fence.

See also