Editable Handle
simple-ai/editable-handleFreeComponent
A React Flow component that allows you to dynamically add, edit, or remove input/output handles on your nodes.
Live preview
live · rendered by the registry
Rendered by simple-ai on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://simple-ai.dev/r/editable-handle.jsonSource
1"use client";23import type { HandleProps, Node } from "@xyflow/react";4import { useOnSelectionChange } from "@xyflow/react";5import { Edit2, Trash } from "lucide-react";6import React, { useCallback, useState } from "react";7import { Button } from "@/components/ui/button";8import { Input } from "@/components/ui/input";9import {10 Popover,11 PopoverContent,12 PopoverTrigger,13} from "@/components/ui/popover";14import { Textarea } from "@/components/ui/textarea";15import { cn } from "@/lib/utils";16import { BaseHandle } from "@/registry/ui/flow/base-handle";1718type HandleEditorProps = {19 variant: "edit" | "create";20 label?: string;21 description?: string;22 onSave: (newLabel: string, newDescription?: string) => boolean;23 onCancel?: () => void;24 align?: "start" | "end";25 children: React.ReactNode;26 showDescription?: boolean;27};2829const EditableHandleDialog = ({30 variant,31 label,32 description,33 onSave,34 onCancel,35 align = "start",36 children,37 showDescription = false,38}: HandleEditorProps) => {39 const [isOpen, setIsOpen] = useState(false);40 const [localLabel, setLocalLabel] = useState(label ?? "");41 const [localDescription, setLocalDescription] = useState(description);4243 const handleSave = () => {44 // Trim and validate the label has no spaces45 const trimmedLabel = localLabel.trim();46 if (trimmedLabel.includes(" ")) {47 alert("Label cannot contain spaces");48 return;49 }50 const success = onSave(trimmedLabel, localDescription?.trim());51 if (success) {52 setIsOpen(false);53 if (variant === "create") {54 reset();55 }56 }57 };5859 const handleCancel = () => {60 setIsOpen(false);61 if (variant === "create") {62 reset();63 }64 onCancel?.();65 };6667 const reset = () => {68 setLocalLabel("");69 setLocalDescription("");70 };7172 return (73 <Popover open={isOpen} onOpenChange={setIsOpen}>74 <PopoverTrigger asChild>{children}</PopoverTrigger>75 <PopoverContent className="w-80 p-4" align={align}>76 <div className="flex flex-col gap-4">77 <div className="flex flex-col gap-2">78 <label htmlFor="label" className="text-sm font-medium">79 Label80 </label>81 <Input82 id="label"83 value={localLabel}84 onChange={(e) => setLocalLabel(e.target.value)}85 placeholder="Enter label"86 className="h-8"87 autoFocus88 />89 </div>90 {showDescription && (91 <div className="flex flex-col gap-2">92 <label93 htmlFor="description"94 className="text-sm font-medium"95 >96 Description (optional)97 </label>98// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from simple-ai
All 77 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| base-handlebase-handle | simple-ai | Components | Free | 1 dep | |
| base-nodebase-node | simple-ai | Components | Free | no deps | |
| Chat Inputchat-input | simple-ai | Components | Free | 7 deps | |
| Chat Messagechat-message | simple-ai | Components | Free | no deps | |
| Chat Message Areachat-message-area | simple-ai | Components | Free | 1 dep | |
| Chat Suggestionschat-suggestions | simple-ai | Components | Free | no deps | |
| Generate Text Nodegenerate-text-node | simple-ai | Components | Free | 1 dep | |
| JSON Schema Editorjson-schema-editor | simple-ai | Components | Free | 1 dep |
