Tree
nested rows joined by drawn lines. groups fold, and a row can be a link.
usage
example
highway 9
the gorge
code
import { Tree, TreeGroup, TreeItem } from 'charcell/react';
export function TreeExample() {
return (
<Tree>
<TreeGroup label="highway 9" root>
<TreeItem label="kickstand" current />
<TreeItem label="melonweed" />
<TreeItem label="mink ranch" />
<TreeGroup label="the gorge" defaultOpen={false}>
<TreeItem label="tourist stop" />
<TreeItem label="ricky's ramp" />
<TreeItem label="ex-bridge" />
</TreeGroup>
<TreeItem label="smash-a-torium" />
<TreeItem label="corley motors" />
</TreeGroup>
</Tree>
);
}▴
▾
<script setup lang="ts">
import { Tree, TreeGroup, TreeItem } from 'charcell/vue';
</script>
<template>
<Tree>
<TreeGroup label="highway 9" root>
<TreeItem label="kickstand" current />
<TreeItem label="melonweed" />
<TreeItem label="mink ranch" />
<TreeGroup label="the gorge" :defaultOpen="false">
<TreeItem label="tourist stop" />
<TreeItem label="ricky's ramp" />
<TreeItem label="ex-bridge" />
</TreeGroup>
<TreeItem label="smash-a-torium" />
<TreeItem label="corley motors" />
</TreeGroup>
</Tree>
</template>▴
▾
<script lang="ts">
import { Tree, TreeGroup, TreeItem } from 'charcell/svelte';
</script>
<Tree>
<TreeGroup label="highway 9" root>
<TreeItem label="kickstand" current /><TreeItem
label="melonweed"
/><TreeItem label="mink ranch" /><TreeGroup
label="the gorge"
defaultOpen={false}
>
<TreeItem label="tourist stop" /><TreeItem
label="ricky's ramp"
/><TreeItem label="ex-bridge" />
</TreeGroup><TreeItem label="smash-a-torium" /><TreeItem
label="corley motors"
/>
</TreeGroup>
</Tree>▴
▾
<!-- component: TreeDriver (behavior not included) -->
<div class="CharcellTree">
<div class="CharcellTreeGroup CharcellTreeGroup--root">
<div
class="CharcellTreeGroup__summary"
role="button"
tabindex="0"
aria-expanded="true"
>
<span class="CharcellTreeGroup__summary-label">highway 9</span>
</div>
<div class="CharcellTreeGroup__children">
<button
class="CharcellTreeItem CharcellTreeItem--current"
type="button"
aria-current="true"
>
<span class="CharcellTreeItem__content">kickstand</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">melonweed</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">mink ranch</span>
</button>
<div class="CharcellTreeGroup">
<div
class="CharcellTreeGroup__summary"
role="button"
tabindex="0"
aria-expanded="false"
>
<span class="CharcellTreeGroup__summary-label">the gorge</span>
</div>
<div class="CharcellTreeGroup__children">
<button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">tourist stop</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">ricky's ramp</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">ex-bridge</span>
</button>
</div>
</div>
<button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">smash-a-torium</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">corley motors</span>
</button>
</div>
</div>
</div>
<!-- /component -->▴
▾
import { Tree, TreeGroup, TreeItem } from 'charcell/react';
export function TreeExample() {
return (
<Tree spacious>
<TreeGroup label="highway 9" root>
<TreeItem label="kickstand" current />
<TreeItem label="melonweed" />
<TreeItem label="mink ranch" />
<TreeGroup label="the gorge" defaultOpen={false}>
<TreeItem label="tourist stop" />
<TreeItem label="ricky's ramp" />
<TreeItem label="ex-bridge" />
</TreeGroup>
<TreeItem label="smash-a-torium" />
<TreeItem label="corley motors" />
</TreeGroup>
</Tree>
);
}▴
▾
<script setup lang="ts">
import { Tree, TreeGroup, TreeItem } from 'charcell/vue';
</script>
<template>
<Tree spacious>
<TreeGroup label="highway 9" root>
<TreeItem label="kickstand" current />
<TreeItem label="melonweed" />
<TreeItem label="mink ranch" />
<TreeGroup label="the gorge" :defaultOpen="false">
<TreeItem label="tourist stop" />
<TreeItem label="ricky's ramp" />
<TreeItem label="ex-bridge" />
</TreeGroup>
<TreeItem label="smash-a-torium" />
<TreeItem label="corley motors" />
</TreeGroup>
</Tree>
</template>▴
▾
<script lang="ts">
import { Tree, TreeGroup, TreeItem } from 'charcell/svelte';
</script>
<Tree spacious>
<TreeGroup label="highway 9" root>
<TreeItem label="kickstand" current /><TreeItem
label="melonweed"
/><TreeItem label="mink ranch" /><TreeGroup
label="the gorge"
defaultOpen={false}
>
<TreeItem label="tourist stop" /><TreeItem
label="ricky's ramp"
/><TreeItem label="ex-bridge" />
</TreeGroup><TreeItem label="smash-a-torium" /><TreeItem
label="corley motors"
/>
</TreeGroup>
</Tree>▴
▾
<!-- component: TreeDriver (behavior not included) -->
<div class="CharcellTree CharcellTree--spacious">
<div class="CharcellTreeGroup CharcellTreeGroup--root">
<div
class="CharcellTreeGroup__summary"
role="button"
tabindex="0"
aria-expanded="true"
>
<span class="CharcellTreeGroup__summary-label">highway 9</span>
</div>
<div class="CharcellTreeGroup__children">
<button
class="CharcellTreeItem CharcellTreeItem--current"
type="button"
aria-current="true"
>
<span class="CharcellTreeItem__content">kickstand</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">melonweed</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">mink ranch</span>
</button>
<div class="CharcellTreeGroup">
<div
class="CharcellTreeGroup__summary"
role="button"
tabindex="0"
aria-expanded="false"
>
<span class="CharcellTreeGroup__summary-label">the gorge</span>
</div>
<div class="CharcellTreeGroup__children">
<button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">tourist stop</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">ricky's ramp</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">ex-bridge</span>
</button>
</div>
</div>
<button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">smash-a-torium</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">corley motors</span>
</button>
</div>
</div>
</div>
<!-- /component -->▴
▾
import { Tree, TreeGroup, TreeItem } from 'charcell/react';
export function TreeExample() {
return (
<Tree disclosure="triangle">
<TreeGroup label="highway 9" root>
<TreeItem label="kickstand" current />
<TreeItem label="melonweed" />
<TreeItem label="mink ranch" />
<TreeGroup label="the gorge" defaultOpen={false}>
<TreeItem label="tourist stop" />
<TreeItem label="ricky's ramp" />
<TreeItem label="ex-bridge" />
</TreeGroup>
<TreeItem label="smash-a-torium" />
<TreeItem label="corley motors" />
</TreeGroup>
</Tree>
);
}▴
▾
<script setup lang="ts">
import { Tree, TreeGroup, TreeItem } from 'charcell/vue';
</script>
<template>
<Tree disclosure="triangle">
<TreeGroup label="highway 9" root>
<TreeItem label="kickstand" current />
<TreeItem label="melonweed" />
<TreeItem label="mink ranch" />
<TreeGroup label="the gorge" :defaultOpen="false">
<TreeItem label="tourist stop" />
<TreeItem label="ricky's ramp" />
<TreeItem label="ex-bridge" />
</TreeGroup>
<TreeItem label="smash-a-torium" />
<TreeItem label="corley motors" />
</TreeGroup>
</Tree>
</template>▴
▾
<script lang="ts">
import { Tree, TreeGroup, TreeItem } from 'charcell/svelte';
</script>
<Tree disclosure="triangle">
<TreeGroup label="highway 9" root>
<TreeItem label="kickstand" current /><TreeItem
label="melonweed"
/><TreeItem label="mink ranch" /><TreeGroup
label="the gorge"
defaultOpen={false}
>
<TreeItem label="tourist stop" /><TreeItem
label="ricky's ramp"
/><TreeItem label="ex-bridge" />
</TreeGroup><TreeItem label="smash-a-torium" /><TreeItem
label="corley motors"
/>
</TreeGroup>
</Tree>▴
▾
<!-- component: TreeDriver (behavior not included) -->
<div class="CharcellTree CharcellTree--disclosure-triangle">
<div class="CharcellTreeGroup CharcellTreeGroup--root">
<div
class="CharcellTreeGroup__summary"
role="button"
tabindex="0"
aria-expanded="true"
>
<span class="CharcellTreeGroup__summary-label">highway 9</span>
</div>
<div class="CharcellTreeGroup__children">
<button
class="CharcellTreeItem CharcellTreeItem--current"
type="button"
aria-current="true"
>
<span class="CharcellTreeItem__content">kickstand</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">melonweed</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">mink ranch</span>
</button>
<div class="CharcellTreeGroup">
<div
class="CharcellTreeGroup__summary"
role="button"
tabindex="0"
aria-expanded="false"
>
<span class="CharcellTreeGroup__summary-label">the gorge</span>
</div>
<div class="CharcellTreeGroup__children">
<button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">tourist stop</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">ricky's ramp</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">ex-bridge</span>
</button>
</div>
</div>
<button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">smash-a-torium</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">corley motors</span>
</button>
</div>
</div>
</div>
<!-- /component -->▴
▾
import { Tree, TreeGroup, TreeItem } from 'charcell/react';
export function TreeExample() {
return (
<Tree disclosurePosition="label">
<TreeGroup label="highway 9" root>
<TreeItem label="kickstand" current />
<TreeItem label="melonweed" />
<TreeItem label="mink ranch" />
<TreeGroup label="the gorge" defaultOpen={false}>
<TreeItem label="tourist stop" />
<TreeItem label="ricky's ramp" />
<TreeItem label="ex-bridge" />
</TreeGroup>
<TreeItem label="smash-a-torium" />
<TreeItem label="corley motors" />
</TreeGroup>
</Tree>
);
}▴
▾
<script setup lang="ts">
import { Tree, TreeGroup, TreeItem } from 'charcell/vue';
</script>
<template>
<Tree disclosurePosition="label">
<TreeGroup label="highway 9" root>
<TreeItem label="kickstand" current />
<TreeItem label="melonweed" />
<TreeItem label="mink ranch" />
<TreeGroup label="the gorge" :defaultOpen="false">
<TreeItem label="tourist stop" />
<TreeItem label="ricky's ramp" />
<TreeItem label="ex-bridge" />
</TreeGroup>
<TreeItem label="smash-a-torium" />
<TreeItem label="corley motors" />
</TreeGroup>
</Tree>
</template>▴
▾
<script lang="ts">
import { Tree, TreeGroup, TreeItem } from 'charcell/svelte';
</script>
<Tree disclosurePosition="label">
<TreeGroup label="highway 9" root>
<TreeItem label="kickstand" current /><TreeItem
label="melonweed"
/><TreeItem label="mink ranch" /><TreeGroup
label="the gorge"
defaultOpen={false}
>
<TreeItem label="tourist stop" /><TreeItem
label="ricky's ramp"
/><TreeItem label="ex-bridge" />
</TreeGroup><TreeItem label="smash-a-torium" /><TreeItem
label="corley motors"
/>
</TreeGroup>
</Tree>▴
▾
<!-- component: TreeDriver (behavior not included) -->
<div class="CharcellTree CharcellTree--disclosure-label">
<div class="CharcellTreeGroup CharcellTreeGroup--root">
<div
class="CharcellTreeGroup__summary"
role="button"
tabindex="0"
aria-expanded="true"
>
<span class="CharcellTreeGroup__summary-label">highway 9</span>
</div>
<div class="CharcellTreeGroup__children">
<button
class="CharcellTreeItem CharcellTreeItem--current"
type="button"
aria-current="true"
>
<span class="CharcellTreeItem__content">kickstand</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">melonweed</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">mink ranch</span>
</button>
<div class="CharcellTreeGroup">
<div
class="CharcellTreeGroup__summary"
role="button"
tabindex="0"
aria-expanded="false"
>
<span class="CharcellTreeGroup__summary-label">the gorge</span>
</div>
<div class="CharcellTreeGroup__children">
<button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">tourist stop</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">ricky's ramp</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">ex-bridge</span>
</button>
</div>
</div>
<button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">smash-a-torium</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">corley motors</span>
</button>
</div>
</div>
</div>
<!-- /component -->▴
▾
import { Tree, TreeGroup, TreeItem } from 'charcell/react';
export function TreeExample() {
return (
<Tree disclosurePosition="start">
<TreeGroup label="highway 9" root>
<TreeItem label="kickstand" current />
<TreeItem label="melonweed" />
<TreeItem label="mink ranch" />
<TreeGroup label="the gorge" defaultOpen={false}>
<TreeItem label="tourist stop" />
<TreeItem label="ricky's ramp" />
<TreeItem label="ex-bridge" />
</TreeGroup>
<TreeItem label="smash-a-torium" />
<TreeItem label="corley motors" />
</TreeGroup>
</Tree>
);
}▴
▾
<script setup lang="ts">
import { Tree, TreeGroup, TreeItem } from 'charcell/vue';
</script>
<template>
<Tree disclosurePosition="start">
<TreeGroup label="highway 9" root>
<TreeItem label="kickstand" current />
<TreeItem label="melonweed" />
<TreeItem label="mink ranch" />
<TreeGroup label="the gorge" :defaultOpen="false">
<TreeItem label="tourist stop" />
<TreeItem label="ricky's ramp" />
<TreeItem label="ex-bridge" />
</TreeGroup>
<TreeItem label="smash-a-torium" />
<TreeItem label="corley motors" />
</TreeGroup>
</Tree>
</template>▴
▾
<script lang="ts">
import { Tree, TreeGroup, TreeItem } from 'charcell/svelte';
</script>
<Tree disclosurePosition="start">
<TreeGroup label="highway 9" root>
<TreeItem label="kickstand" current /><TreeItem
label="melonweed"
/><TreeItem label="mink ranch" /><TreeGroup
label="the gorge"
defaultOpen={false}
>
<TreeItem label="tourist stop" /><TreeItem
label="ricky's ramp"
/><TreeItem label="ex-bridge" />
</TreeGroup><TreeItem label="smash-a-torium" /><TreeItem
label="corley motors"
/>
</TreeGroup>
</Tree>▴
▾
<!-- component: TreeDriver (behavior not included) -->
<div class="CharcellTree CharcellTree--disclosure-start">
<div class="CharcellTreeGroup CharcellTreeGroup--root">
<div
class="CharcellTreeGroup__summary"
role="button"
tabindex="0"
aria-expanded="true"
>
<span class="CharcellTreeGroup__summary-label">highway 9</span>
</div>
<div class="CharcellTreeGroup__children">
<button
class="CharcellTreeItem CharcellTreeItem--current"
type="button"
aria-current="true"
>
<span class="CharcellTreeItem__content">kickstand</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">melonweed</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">mink ranch</span>
</button>
<div class="CharcellTreeGroup">
<div
class="CharcellTreeGroup__summary"
role="button"
tabindex="0"
aria-expanded="false"
>
<span class="CharcellTreeGroup__summary-label">the gorge</span>
</div>
<div class="CharcellTreeGroup__children">
<button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">tourist stop</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">ricky's ramp</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">ex-bridge</span>
</button>
</div>
</div>
<button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">smash-a-torium</span></button
><button class="CharcellTreeItem" type="button">
<span class="CharcellTreeItem__content">corley motors</span>
</button>
</div>
</div>
</div>
<!-- /component -->▴
▾
as text
highway 9 [–] ├─ kickstand ├─ melonweed ├─ mink ranch ├─ the gorge [+] ├─ smash-a-torium └─ corley motors
highway 9 [–] ├─ kickstand ├─ melonweed ├─ mink ranch ├─ the gorge [+] ├─ smash-a-torium └─ corley motors
highway 9 [–] ├─ kickstand ├─ melonweed ├─ mink ranch ├─ the gorge [+] ├─ smash-a-torium └─ corley motors
highway 9 [–] ├─ kickstand ├─ melonweed ├─ mink ranch ├─ the gorge [+] ├─ smash-a-torium └─ corley motors
❯highway 9 [–] ├─ kickstand ├─ melonweed ├─ mink ranch ├─ the gorge [+] ├─ smash-a-torium └─ corley motors
highway 9 [–] ├─❯kickstand ├─ melonweed ├─ mink ranch ├─ the gorge [+] ├─ smash-a-torium └─ corley motors
highway 9 [–] ├─ kickstand │ ├─ melonweed │ ├─ mink ranch │ ├─ the gorge [+] │ ├─ smash-a-torium │ └─ corley motors
highway 9 [–] ├─ kickstand │ ├─ melonweed │ ├─ mink ranch │ ├─ the gorge [+] │ ├─ smash-a-torium │ └─ corley motors
highway 9 [–] ├─ kickstand │ ├─ melonweed │ ├─ mink ranch │ ├─ the gorge [+] │ ├─ smash-a-torium │ └─ corley motors
highway 9 [–] ├─ kickstand │ ├─ melonweed │ ├─ mink ranch │ ├─ the gorge [+] │ ├─ smash-a-torium │ └─ corley motors
❯highway 9 [–] ├─ kickstand │ ├─ melonweed │ ├─ mink ranch │ ├─ the gorge [+] │ ├─ smash-a-torium │ └─ corley motors
highway 9 [–] ├─❯kickstand │ ├─ melonweed │ ├─ mink ranch │ ├─ the gorge [+] │ ├─ smash-a-torium │ └─ corley motors
highway 9 ▾ ├─ kickstand ├─ melonweed ├─ mink ranch ├─ the gorge ▸ ├─ smash-a-torium └─ corley motors
highway 9 ▾ ├─ kickstand ├─ melonweed ├─ mink ranch ├─ the gorge ▸ ├─ smash-a-torium └─ corley motors
highway 9 ▾ ├─ kickstand ├─ melonweed ├─ mink ranch ├─ the gorge ▸ ├─ smash-a-torium └─ corley motors
highway 9 ▾ ├─ kickstand ├─ melonweed ├─ mink ranch ├─ the gorge ▸ ├─ smash-a-torium └─ corley motors
❯highway 9 ▾ ├─ kickstand ├─ melonweed ├─ mink ranch ├─ the gorge ▸ ├─ smash-a-torium └─ corley motors
highway 9 ▾ ├─❯kickstand ├─ melonweed ├─ mink ranch ├─ the gorge ▸ ├─ smash-a-torium └─ corley motors
highway 9 [–] ├─ kickstand ├─ melonweed ├─ mink ranch ├─ the gorge [+] ├─ smash-a-torium └─ corley motors
highway 9 [–] ├─ kickstand ├─ melonweed ├─ mink ranch ├─ the gorge [+] ├─ smash-a-torium └─ corley motors
highway 9 [–] ├─ kickstand ├─ melonweed ├─ mink ranch ├─ the gorge [+] ├─ smash-a-torium └─ corley motors
highway 9 [–] ├─ kickstand ├─ melonweed ├─ mink ranch ├─ the gorge [+] ├─ smash-a-torium └─ corley motors
❯highway 9 [–] ├─ kickstand ├─ melonweed ├─ mink ranch ├─ the gorge [+] ├─ smash-a-torium └─ corley motors
highway 9 [–] ├─❯kickstand ├─ melonweed ├─ mink ranch ├─ the gorge [+] ├─ smash-a-torium └─ corley motors
[–] highway 9 ├─ kickstand ├─ melonweed ├─ mink ranch ├─ [+] the gorge ├─ smash-a-torium └─ corley motors
[–] highway 9 ├─ kickstand ├─ melonweed ├─ mink ranch ├─ [+] the gorge ├─ smash-a-torium └─ corley motors
[–] highway 9 ├─ kickstand ├─ melonweed ├─ mink ranch ├─ [+] the gorge ├─ smash-a-torium └─ corley motors
[–] highway 9 ├─ kickstand ├─ melonweed ├─ mink ranch ├─ [+] the gorge ├─ smash-a-torium └─ corley motors
❯[–] highway 9 ├─ kickstand ├─ melonweed ├─ mink ranch ├─ [+] the gorge ├─ smash-a-torium └─ corley motors
[–] highway 9 ├─❯kickstand ├─ melonweed ├─ mink ranch ├─ [+] the gorge ├─ smash-a-torium └─ corley motors
props
Tree
- spaciousboolean
- Gives each row two, its label in the first: a 32px target, which meets WCAG 2.5.8. One-row rows miss it.
- disclosure'brackets' | 'triangle'= 'brackets'
- How a group marks its open state:
brackets,[–]and[+], ortriangle,▾and▸. - disclosurePosition'end' | 'label' | 'start'= 'end'
- Where a group's mark sits: at the row's
end, a cell in from its edge; right after thelabel; or at thestart, before the label, which indents a group's label past its sibling rows'.
TreeGroup
- labelstring
- The folder row's text.
- defaultOpenboolean= true
- The initial open state; the group owns it from there.
- openboolean
- The open state, held by the consumer; pair it with
onOpenChange. - binds with
v-model:openin vue,bind:openin svelte - onOpenChange(open: boolean) => void
- Called with the new open state when the group opens or closes.
- rootboolean
- The top-level section: a bold label row.
- collapsibleboolean= true
falsekeeps the section open, with no glyph and nothing to press.
it also takes any other attribute of its <div>.
TreeItem
- labelstring
- The row's text; a long one ellipsizes.
- hrefstring
- A row that navigates: the row is a link to it instead of a button.
- currentboolean
- The current row: inverted, and
aria-current(pageon a link,locationon a link into the same page). - rootboolean
- The bold variant for a top-level entry.
- onClick(event: MouseEvent) => void
- Called with the click event.
it also takes any other attribute of its <button>.
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.
Tree
- default
- The tree's rows:
TreeGroups andTreeItems, nested as deep as they go.
TreeGroup
- summary
- Content on the group's row after
label, such as a count. - default
- The group's rows, under its own.
TreeItem
- default
- Content after
label, or the row's whole content without one.
▴
▾