BranchPicker
neon-ui/branch-pickerFreeComponent
A searchable branch selector with default/protected status and an inline create-branch affordance.
Install it
npx shadcn@latest add https://ui.neon.com/r/branch-picker.jsonSource
1/* oxlint-disable jsx-a11y/prefer-tag-over-role -- a custom ARIA listbox; a native select cannot filter, create, or draw the tree. */2"use client";34import {5 ArrowDown01Icon,6 ArrowLeft01Icon,7 GitBranchIcon,8 PlusSignIcon,9 Search01Icon,10 SquareLock01Icon,11 Tick02Icon,12} from "@hugeicons/core-free-icons";13import { HugeiconsIcon } from "@hugeicons/react";14import { useEffect, useRef, useState } from "react";15import type { ComponentProps, FormEvent, KeyboardEvent } from "react";1617import { Button } from "@/components/ui/button";18import { Input } from "@/components/ui/input";19import {20 Popover,21 PopoverContent,22 PopoverTrigger,23} from "@/components/ui/popover";24import {25 Tooltip,26 TooltipContent,27 TooltipProvider,28 TooltipTrigger,29} from "@/components/ui/tooltip";30import { cn } from "@/lib/utils";3132export interface Branch {33 id: string;34 name: string;35 /** The project's default branch. */36 default?: boolean;37 /** A protected branch. */38 protected?: boolean;39 /** The parent branch's id; drives the drawn hierarchy. */40 parent?: string;41}4243interface TreeNode {44 branch: Branch;45 depth: number;46}4748/* ─────────────────────────────────────────────────────────49 * GEOMETRY50 *51 * The list draws a real branch graph, not indent guides:52 * a branch sits in the lane of its depth, and a curved edge53 * runs from its parent's node into it. Tuned tight for the54 * 32px popover rows. While searching, the list flattens to55 * one lane and drops the edges.56 * ───────────────────────────────────────────────────────── */57const ROW_H = 32;58const LANE_W = 18;59const PAD_X = 12;60const DOT_R = 3;61const CORNER = 8;6263const laneX = (depth: number) => PAD_X + depth * LANE_W;64const rowY = (row: number) => row * ROW_H + ROW_H / 2;6566/** Depth-first flatten, assigning each branch a depth lane. */67const buildTree = (branches: Branch[]): TreeNode[] => {68 const ids = new Set(branches.map((branch) => branch.id));69 const parentOf = (branch: Branch) =>70 branch.parent && ids.has(branch.parent) ? branch.parent : undefined;71 const childrenOf = (id?: string) =>72 branches.filter((branch) => parentOf(branch) === id);7374 const nodes: TreeNode[] = [];7576 const walk = (branch: Branch, depth: number) => {77 nodes.push({ branch, depth });78// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from neon-ui
All 77 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| ActivityFeedactivity-feed | neon-ui | Components | Free | 2 deps | |
| AgentChatagent-chat | neon-ui | Components | Free | 6 deps | |
| AnimatedWashanimated-wash | neon-ui | Components | Free | no deps · 2 files | |
| ApiKeyListapi-key-list | neon-ui | Components | Free | 2 deps | |
| AppCardapp-card | neon-ui | Components | Free | 2 deps | |
| AppCreatorapp-creator | neon-ui | Components | Free | 2 deps | |
| AuthFormauth-form | neon-ui | Components | Free | no deps | |
| AutoscaleChartautoscale-chart | neon-ui | Components | Free | 1 dep |
