Grok Project Picker
brainless/grok-project-pickerFreeComponent
Run Grok Build in a project directory? — left-border chooser with recent dirs and a free-text option.
Install it
npx shadcn@latest add https://brainless.swerdlow.dev/r/grok-project-picker.jsonSource
1"use client";23import * as React from "react";4import { cn } from "@/lib/utils";56/**7 * GrokProjectPicker — "Run Grok Build in a project directory?" chooser.8 *9 * Captured from a fresh launch outside a trusted project: left-border card10 * with `(○)` radios for recent dirs plus a free-text `z` option.11 */12const BORDER = "#808080";13const FG = "#e1e1e1";14const MUTED = "#8b8b90";15const DIM = "#6c6c6c";1617export type GrokProject = {18 id: string;19 name: string;20 path: string;21 meta?: string;22};2324const DEFAULT_PROJECTS: GrokProject[] = [25 {26 id: "current",27 name: "brainless",28 path: "~/dev/brainless",29 meta: "current",30 },31 {32 id: "cloudstate",33 name: "freestyle-cloudstate",34 path: "~/Documents/GitHub/freestyle-cloudstate",35 meta: "5h ago",36 },37 {38 id: "conduit",39 name: "Conduit",40 path: "~/Documents/Conduit",41 meta: "5h ago",42 },43];4445export function GrokProjectPicker({46 title = "Run Grok Build in a project directory?",47 description = "This gives Grok Build full context of your codebase for better results.",48 projects = DEFAULT_PROJECTS,49 defaultSelected = 0,50 onChoose,51 className,52}: {53 title?: string;54 description?: string;55 projects?: GrokProject[];56 defaultSelected?: number;57 onChoose?: (index: number | "custom") => void;58 className?: string;59}) {60 const [sel, setSel] = React.useState(defaultSelected);61 const customIndex = projects.length;6263 const options = [64 ...projects.map((p, i) => ({65 key: p.id,66 index: i,67 label: (68 <>69 <span style={{ color: FG }}>{p.name}</span>70 {p.meta === "current" ? (71 <span style={{ color: DIM }}> (current)</span>72 ) : null}73 <span style={{ color: DIM }}> {p.path}</span>74 {p.meta && p.meta !== "current" ? (75 <span style={{ color: DIM }}> ({p.meta})</span>76 ) : null}77 </>78 ),79 })),80 {81 key: "custom",82 index: customIndex,83 label: <span style={{ color: MUTED }}>Type your answer here</span>,84 },85 ];8687 function onKey(e: React.KeyboardEvent, i: number) {88 if (e.key === "ArrowDown" || e.key === "ArrowUp") {89 e.preventDefault();90 const next =91 e.key === "ArrowDown"92 ? (i + 1) % options.length93 : (i - 1 + options.length) % options.length;94 setSel(next);95 (e.currentTarget.parentElement?.children[next] as HTMLElement)?.focus();96 } else if (e.key === "Enter" || e.key === " ") {97// … truncated
Files it writes
More from brainless
All 40 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Claude Diffclaude-diff | brainless | Components | Free | no deps | |
| Claude Headerclaude-header | brainless | Components | Free | no deps | |
| Claude Messageclaude-message | brainless | Components | Free | no deps | |
| Claude Permissionclaude-permission | brainless | Components | Free | no deps | |
| Claude Promptclaude-prompt | brainless | Components | Free | no deps | |
| Claude Slash Menuclaude-slash-menu | brainless | Components | Free | no deps | |
| Claude Thinkingclaude-thinking | brainless | Components | Free | no deps | |
| Claude Todo Listclaude-todo-list | brainless | Components | Free | no deps |
