Components Components
Tabs
Components tabs
Tabbed panels — switch content without navigating.
Markup
Drops in as data-pb-block="tabs".
html
<div data-pb-block="tabs" class="pb-tabs" x-data="{ tab: 'one' }" style="max-width:36rem;">
<div class="pb-tabs__list" role="tablist" style="display:flex;gap:0.25rem;border-bottom:1px solid #e2e8f0;">
<button type="button" class="pb-tabs__tab" role="tab" @click="tab = 'one'" :aria-selected="tab === 'one'" :style="tab === 'one' ? 'color:#4f46e5;border-bottom-color:#4f46e5' : 'color:#64748b;border-bottom-color:transparent'" style="padding:0.7rem 1rem;border:0;border-bottom:2px solid transparent;background:transparent;font-weight:600;cursor:pointer;">Tab one</button>
<button type="button" class="pb-tabs__tab" role="tab" @click="tab = 'two'" :aria-selected="tab === 'two'" :style="tab === 'two' ? 'color:#4f46e5;border-bottom-color:#4f46e5' : 'color:#64748b;border-bottom-color:transparent'" style="padding:0.7rem 1rem;border:0;border-bottom:2px solid transparent;background:transparent;font-weight:600;cursor:pointer;">Tab two</button>
<button type="button" class="pb-tabs__tab" role="tab" @click="tab = 'three'" :aria-selected="tab === 'three'" :style="tab === 'three' ? 'color:#4f46e5;border-bottom-color:#4f46e5' : 'color:#64748b;border-bottom-color:transparent'" style="padding:0.7rem 1rem;border:0;border-bottom:2px solid transparent;background:transparent;font-weight:600;cursor:pointer;">Tab three</button>
</div>
<div class="pb-tabs__panels" style="padding:1.25rem 0;color:#475569;line-height:1.6;">
<div class="pb-tabs__panel" role="tabpanel" x-show="tab === 'one'"><p style="margin:0;">Content for the first tab.</p></div>
<div class="pb-tabs__panel" role="tabpanel" x-show="tab === 'two'" x-cloak><p style="margin:0;">Content for the second tab.</p></div>
<div class="pb-tabs__panel" role="tabpanel" x-show="tab === 'three'" x-cloak><p style="margin:0;">Content for the third tab.</p></div>
</div>
</div>Settings
Interactive behaviour is built in; on top of that every block supports:
- Bind to State
- Drive content reactively from a State with declarative Alpine —
x-text,x-showorx-modelover$store.app.<stateKey>. - On event → run a Flow
- Wire an interaction to a Flow: set
data-pb-flow="<slug>"anddata-pb-flow-event="click|submit|hover|change|…". The flow's returned actions update the page. - Link to a page
- Navigate to another published page on click with
data-pb-page="<slug>". - Styles & classes
- Edit spacing, colour and layout visually in the GrapesJS editor. The wrapper carries
data-pb-block="tabs"so it imports as a labelled, editable component. - Interactive out of the box
- Ships with Alpine state baked in (
x-data,@click,x-show,x-transition) — open/close, tabs and toggles work with no wiring. These owner-authored blocks are trusted and keep their executable directives.