charcell 0.1.0
mode

Tabs

panels behind tabs, one showing at a time. boxed, they are folder tabs.

usage

example

code

import { Tabs } from 'charcell/react';

export function TabsExample() {
  return (
    <Tabs
      items={[
        { value: 'kickstand', label: 'kickstand' },
        { value: 'melonweed', label: 'melonweed' },
        { value: 'corville', label: 'corville', disabled: true },
      ]}
      label="highway 9"
      panel={({ value }) => (
        <>
          {value === 'kickstand' && (
            <>
              <p>a biker bar out on the highway. quohog pours.</p>
            </>
          )}
          {value === 'melonweed' && (
            <>
              <p>what is left of the town sinks a foot a year.</p>
            </>
          )}
          {value === 'corville' && (
            <>
              <p>home of corley motors and its shareholders.</p>
            </>
          )}
        </>
      )}
    />
  );
}

as text

at rest
┌───────────┬───────────┬──────────┐
│ kickstand │ melonweed │ corville │
│           └───────────┴──────────┴───┐
│ a biker bar out on the highway.      │
│ quohog pours.                        │
└──────────────────────────────────────┘
hover
┌───────────┬───────────┬──────────┐
│ kickstand │ melonweed │ corville │
│           └───────────┴──────────┴───┐
│ a biker bar out on the highway.      │
│ quohog pours.                        │
└──────────────────────────────────────┘
tab focus
┌───────────┬───────────┬──────────┐
│❯kickstand │ melonweed │ corville │
│           └───────────┴──────────┴───┐
│ a biker bar out on the highway.      │
│ quohog pours.                        │
└──────────────────────────────────────┘
tab panel focus
┌───────────┬───────────┬──────────┐
│ kickstand │ melonweed │ corville │
│           └───────────┴──────────┴───┐
│❯a biker bar out on the highway.      │
│ quohog pours.                        │
└──────────────────────────────────────┘

props

Tabs

direction'ltr' | 'rtl'
The reading direction its keys and placement follow ('rtl' mirrors the arrow keys); the page's, once mounted, when unset.
itemsTabItem[]
The tabs, in order: { value, label, disabled }.
valuestring
Controlled selected tab; pair it with onValueChange.
binds with v-model:value in vue, bind:value in svelte
defaultValuestring
Uncontrolled initial tab; the first one when unset.
onValueChange(value: string) => void
Called with the newly selected tab's value.
labelstring
The tab list's accessible name.
variant'boxed' | 'dense'= 'boxed'
boxed (the default) is the folder; dense is the bare tab row, its tabs 16px tall, which misses WCAG 2.5.8's 24px target; boxed meets it.
border'none' | 'single' | 'rounded' | 'heavy' | 'double'
The style of the boxed panel's end and bottom sides: single, rounded, heavy, double or none. Its top is the tabs, and its start meets theirs.
borderEnd'none' | 'single' | 'rounded' | 'heavy' | 'double'
The style of the boxed panel's end side, over border.
borderBottom'none' | 'single' | 'rounded' | 'heavy' | 'double'
The style of the boxed panel's bottom side, over border.
fillboolean
Takes the container's box: grows in a flex or grid layout, and takes the full height of a block that has one; the selected panel takes the height the tab row leaves.

TabList

variant'boxed' | 'dense'= 'boxed'
boxed draws folder tabs over the panel; dense is the tabs over a faint rule.
border'none' | 'single' | 'rounded' | 'heavy' | 'double'
The panel's border, which its right side follows: a double side's outer line sits a stroke gap further out, and the base runs on to meet it (╖).
borderEnd'none' | 'single' | 'rounded' | 'heavy' | 'double'
The panel's right side, over border.

it also takes any other attribute of its <div>.

TabPanel

variant'boxed' | 'dense'= 'boxed'
boxed is the folder's body, a ring open at the top; dense is bare.
border'none' | 'single' | 'rounded' | 'heavy' | 'double'
The style of the boxed panel's end and bottom sides: single, rounded, heavy, double or none.
borderEnd'none' | 'single' | 'rounded' | 'heavy' | 'double'
The style of the boxed panel's end side, over border.
borderBottom'none' | 'single' | 'rounded' | 'heavy' | 'double'
The style of the boxed panel's bottom side, over border.
fillboolean
Takes the container's box: grows in a flex or grid layout, and takes the full height of a block that has one.

it also takes any other attribute of its <div>.

slots

in react, the default slot is children and each named slot a prop of its name, a function where the slot hands values; in vue, a slot; in svelte, a snippet.

Tabs

panel{ value: string }
A tab's content, given the tab's value.

TabList

default

TabPanel

default
The tab's content.