Ga naar hoofdinhoud

CnTab

One panel inside a CnTabs strip. Its title is rendered by the parent's nav; its body is rendered in the parent's panel area.

Usage

<CnTabs aria-label="Case details">
<CnTab title="Documents">
<DocumentList />
</CnTab>

<!-- controlled selection -->
<CnTab title="Tasks" :active="tab === 'tasks'" @click="tab = 'tasks'">
<TaskList />
</CnTab>

<!-- rich title -->
<CnTab>
<template #title>
{{ label }} <NcButton variant="tertiary" @click.stop="close()">×</NcButton>
</template>
<DraftForm />
</CnTab>

<CnTab title="Archive" disabled />
</CnTabs>

Props

PropTypeDefaultDescription
titleString''Plain-text tab title. Ignored when a #title slot is supplied.
activeBooleanfalseSelect this tab. Honoured on mount and on every later change, so it can drive a controlled strip.
disabledBooleanfalseRender the nav button disabled, skip the tab in keyboard navigation, and never give it the initial selection.
lazyBooleanfalseHold the panel body back until this tab is first activated, then keep it mounted. For strips whose panels are expensive to mount.

Slots

SlotDescription
defaultThe panel body.
titleRich tab title, rendered inside the parent's nav button. Overrides title. Use @click.stop on anything interactive here so it does not also switch tabs.

Events

EventPayloadDescription
clickThe user activated this tab. Fires on click and on keyboard activation.

Notes

  • The panel is not destroyed when inactive. It is hidden with hidden + display: none, matching bootstrap-vue's <BTab>. A panel that fetches on mounted() would refire that request on every tab switch under a v-if implementation. Put a v-if inside the panel if you want teardown.
  • lazy changes only the first paint. The body waits until the tab is first activated, and from then on the panel behaves exactly as above: it stays mounted, so switching back never refetches. Reach for it when the panels are expensive. Six panels that each fetch on mounted() fire six requests on page load, and five of them answer questions nobody has asked yet.
  • A title that is a computed value stays reactive. The parent invokes the child's title renderer inside its own render effect, so the nav strip re-renders when the title changes.
  • Rendered outside a CnTabs parent, the panel shows its content rather than vanishing. The realistic cause of a missed inject() is the package being loaded twice (ADR-019 / openregister#1958), and rendering blank with no error is the worse failure. The injection key is a Symbol.for, so duplicate module instances converge on the same key.

Reference

Props

NameTypeRequiredDefaultDescription
titlestring''Plain-text tab title. Ignored when a #title slot is supplied.
activebooleanfalseSelect this tab. Honoured on mount and on every later change.
disabledbooleanfalseRender the nav button disabled and skip this tab in keyboard navigation.
lazybooleanfalseHold the panel body back until this tab is first activated, then keep it mounted for the rest of the strip's life. Off by default, because the eager panel is what makes a tab switch instant and it is the behaviour every existing consumer already has. Turn it on when the panels are expensive: six panels that each fetch on mounted() fire six requests on page load, and five of those answer questions nobody has asked yet. This is NOT v-if-per-switch. Once a panel has been shown it stays in the DOM, so switching back to it never refetches. That is the whole reason an inactive panel is hidden rather than destroyed.

Events

NamePayloadDescription
clickThe user activated this tab.

Slots

NameBindingsDescription
defaultThe panel body.

See also

  • CnTabs — the strip, including the bootstrap-vue migration table