BlockDex

Components

Registries

Free blocks

Method

BlockDex

Components

Registries

Free blocks

Method

Open API

BlockDex

Components

Registries

Free blocks

Method

Open API

Components/grida/tree-view-row

Tree View Row

grida/tree-view-row
FreeComponent

Canonical shadcn-styled row for `@grida/tree-view`.

Live preview

live · rendered by the registry
Rendered by grida on their own page — this is the component running, not a screenshot of it.

Install it

npx shadcn@latest add https://grida.co/r/tree-view-row.json

Source

components/tree-view-row.tsxgrida.co/r/tree-view-row.json
1"use client";
2
3import type { Row } from "@grida/tree-view";
4import { useTree, useTreeSnapshot } from "@grida/tree-view/react";
5import { cn } from "@/lib/utils";
6import { ChevronDownIcon, ChevronRightIcon } from "lucide-react";
7import * as React from "react";
8
9export interface TreeViewRowProps {
10 /** Row produced by `controller.getRows()`. */
11 row: Row;
12 /** Optional label override. Falls back to `row.meta.label ?? row.id`. */
13 label?: React.ReactNode;
14 /** Optional leading icon. */
15 icon?: React.ReactNode;
16 /** Number of pixels per depth step. Defaults to 16. */
17 indent?: number;
18}
19
20/**
21 * Canonical shadcn-styled row for `@grida/tree-view`.
22 *
23 * - Subscribes to its own selection / focus / expanded slice via
24 * `useTreeSnapshot` so siblings don't re-render when only your row's
25 * state changes.
26 * - Drives a single `data-state` attribute so Tailwind variants can style
27 * every state from one className.
28 * - Toggles expansion on chevron click; emits selection on the row body.
29 */
30export function TreeViewRow({
31 row,
32 label,
33 icon,
34 indent = 16,
35}: TreeViewRowProps) {
36 const controller = useTree();
37 const isContainer =
38 controller.source.isContainer?.(row.id) ?? row.isContainer;
39
40 const state = useTreeSnapshot(
41 (c) => ({
42 selected: c.getSelection().includes(row.id),
43 focused: c.getFocused() === row.id,
44 expanded: c.isExpanded(row.id),
45 }),
46 (a, b) =>
47 a.selected === b.selected &&
48 a.focused === b.focused &&
49 a.expanded === b.expanded
50 );
51
52 const dataState = state.selected
53 ? "selected"
54 : state.focused
55 ? "focused"
56 : "idle";
57
58 const handleToggle = (e: React.MouseEvent) => {
59 e.stopPropagation();
60 if (state.expanded) controller.collapse(row.id);
61 else controller.expand(row.id);
62 };
63
64 const handleSelect = (e: React.MouseEvent) => {
65 const mode = e.shiftKey
66 ? "range"
67 : e.metaKey || e.ctrlKey
68 ? "toggle"
69 : "replace";
70 controller.select([row.id], mode);
71 controller.focus(row.id);
72 };
73
74 return (
75 <div
76 role="treeitem"
77 aria-selected={state.selected}
78 aria-expanded={isContainer ? state.expanded : undefined}
79 data-state={dataState}
80 onClick={handleSelect}
81 style={{ paddingLeft: row.depth * indent }}
82 className={cn(
83 "flex h-7 items-center gap-1.5 px-1.5 text-sm cursor-default select-none rounded-sm",
84// … truncated

Files it writes

  • components/tree-view-row.tsx

Facts

Registry
grida
Type
registry:component
Access
Free
Files written
1
Licence
Apache-2.0
First indexed
2026-08-02
Last confirmed
today

Go to the source

Docs on grida grida.co gridaco/grida on GitHub Raw registry item This item as JSON
BlockDex

Built by

Kynth Studio

Index

Components
Registries
Method
Open API

Guides

shadcn component libraries
Best shadcn registries
Free shadcn blocks

Reference

Corpus counts
Crawl health
hello@kynth.studio
Privacy
Terms

BlockDex

BlockDex

Built by

Kynth Studio

Index

Components
Registries
Method
Open API

Guides

shadcn component libraries
Best shadcn registries
Free shadcn blocks

Reference

Corpus counts
Crawl health
hello@kynth.studio
Privacy
Terms

BlockDex

BlockDex

Built by

Kynth Studio

Index

Components
Registries
Method
Open API

Guides

shadcn component libraries
Best shadcn registries
Free shadcn blocks

Reference

Corpus counts
Crawl health
hello@kynth.studio
Privacy
Terms

BlockDex