Fandry UI
Layout

Tabs

A set of tabs that switch between panels — pair with fandry-tab and fandry-tab-panel.

fandry-tabs

Example

Link to section Example

Custom colors and parts

Link to section Custom colors and parts

The same component with a few --fd-* tokens set around it and its parts restyled. The code is under Parts below.

Props

Link to section Props
PropTypeDefaultDescription
valuestring''The value of the selected tab. Updates as the user picks a tab. Unset, or matching no tab, the first enabled tab is selected.
aria-labelstring—Names the tab list, e.g. "Settings".
change (event)CustomEvent<{ value }>—Fires when the user picks a different tab, by click or keyboard; event.detail.value is that tab's value. Not fired when value is set from code or the tab is already selected.

Parts

Link to section Parts

Style the elements inside the component from your own CSS with ::part(). Every fandry component renders in native shadow DOM, so parts work on LWR and Salesforce alike. For colors, spacing, radius and type across many components, set the --fd-* tokens instead. The code for the "Custom colors and parts" example above:

PartDescription
baseThe outermost element.
listThe element holding the items.
<!-- template -->
<div class="brand">
  <fandry-tabs value="account" aria-label="Settings">
    <fandry-tab slot="tab" value="account">Account</fandry-tab>
    <fandry-tab slot="tab" value="billing">Billing</fandry-tab>
    <fandry-tab slot="tab" value="team">Team</fandry-tab>
    <fandry-tab-panel value="account">
      <fandry-text>Update your name, email and password.</fandry-text>
    </fandry-tab-panel>
    <fandry-tab-panel value="billing">
      <fandry-text>Manage your plan and payment method.</fandry-text>
    </fandry-tab-panel>
    <fandry-tab-panel value="team">
      <fandry-text>Invite people to your workspace.</fandry-text>
    </fandry-tab-panel>
  </fandry-tabs>
</div>

/* css */
/* Scoped to this demo. Set the same --fd-* tokens on :root to theme
   every fandry-* component on the site. */
.brand {
  --fd-primary: 160 84% 26%;
}

fandry-tabs::part(list) {
  gap: 0.5rem;
  box-shadow: none;
}

fandry-tab::part(base) {
  border-radius: 999px;
  border-bottom-color: transparent;
}

fandry-tab::part(base selected) {
  background: hsl(160 84% 26%);
  color: white;
}
​

Code

Link to section Code
<fandry-tabs value="account" aria-label="Settings" onchange={handleChange}>
  <fandry-tab slot="tab" value="account">Account</fandry-tab>
  <fandry-tab slot="tab" value="billing">Billing</fandry-tab>
  <fandry-tab-panel value="account">Account settings</fandry-tab-panel>
  <fandry-tab-panel value="billing">Billing settings</fandry-tab-panel>
</fandry-tabs>

handleChange(event) {
  this.selectedTab = event.detail.value;
}
​

Tabs and panels are siblings

Put each fandry-tab in the tab slot and each fandry-tab-panel in the default slot, as direct children (a wrapper element in between hides them from fandry-tabs), matched by value, which every tab and panel needs. They stay separate children so a panel can hold anything, and a tab can be restyled or replaced without touching the panels.

A focused tab is selected: the arrow keys, Home and End move between enabled tabs. Every panel stays in the page, hidden until its tab is selected. A tab and its panel are in different shadow roots, so they cannot point at each other with ids; set aria-label on a panel to name it. A panel is a Tab stop only when it has nothing focusable inside, so keyboard users can reach its content: a native control, or a component with its own focus(), in the page's own markup counts.