rhf-inline-edit
shuip/rhf-inline-editFreeComponent
shuip publishes no description for this item.
Live preview
live · rendered by the registry
Rendered by shuip on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://shuip.plvo.dev/r/rhf-inline-edit.jsonSource
1'use client';23import type { Lens } from '@hookform/lenses';4import { InfoIcon } from 'lucide-react';5import * as React from 'react';6import { useController, useFormContext } from 'react-hook-form';7import { Field, FieldLabel } from '@/components/ui/field';8import { Input } from '@/components/ui/input';9import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';10import { Textarea } from '@/components/ui/textarea';11import { cn } from '@/lib/utils';1213type InlineEditSize = 'sm' | 'default' | 'title';14type InlineEditVariant = 'ghost' | 'boxed';15type InlineEditInput = 'text' | 'textarea';1617interface InlineEditProps {18 value: string;19 onCommit: (next: string) => Promise<string | undefined> | string | undefined;20 input?: InlineEditInput;21 variant?: InlineEditVariant;22 size?: InlineEditSize;23 placeholder?: string;24 canEdit?: boolean;25 children?: (api: {26 value: string;27 setValue: (v: string) => void;28 commit: (next?: string) => void;29 cancel: () => void;30 className: string;31 autoFocus: true;32 }) => React.ReactNode;33}3435type State =36 | { kind: 'reading' }37 | { kind: 'editing'; draft: string; error?: string }38 | { kind: 'saving'; draft: string };3940const sizeClasses: Record<InlineEditSize, string> = {41 sm: 'px-1.5 py-0.5 text-xs',42 default: 'px-2 py-1 text-sm',43 title: 'px-2 py-1 text-3xl font-semibold tracking-tight',44};4546const variantClasses: Record<InlineEditVariant, string> = {47 ghost:48 'border border-transparent bg-transparent hover:bg-muted focus-visible:bg-muted dark:bg-transparent dark:hover:bg-muted',49 boxed: 'border border-input bg-transparent shadow-xs focus-visible:border-ring',50};5152function InlineEdit({53 value,54 onCommit,55 input = 'text',56 variant = 'ghost',57 size = 'default',58 placeholder = '—',59 canEdit = true,60 children,61}: InlineEditProps) {62 const [state, setState] = React.useState<State>({ kind: 'reading' });63 const errorId = React.useId();6465 const fieldClassName = cn(66 'w-full rounded-md text-left outline-none transition-colors focus-visible:ring-[3px] focus-visible:ring-ring/50',67 sizeClasses[size],68 variantClasses[variant],69 );7071 const startEdit = () => {72 if (canEdit) setState({ kind: 'editing', draft: value });73 };7475 const cancel = () => setState({ kind: 'reading' });7677 const setDraft = (draft: string) => setState((s) => (s.kind === 'editing' ? { kind: 'editing', draft } : s));7879 const commit = async (override?: string) => {80// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from shuip
All 52 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| confirmation-dialogconfirmation-dialog | shuip | Components | Free | 1 dep | |
| copy-buttoncopy-button | shuip | Components | Free | 3 deps | |
| hover-revealhover-reveal | shuip | Components | Free | 1 dep | |
| rhf-address-fieldrhf-address-field | shuip | Components | Free | 5 deps · 2 files | |
| rhf-autocomplete-fieldrhf-autocomplete-field | shuip | Components | Free | 4 deps | |
| rhf-checkbox-fieldrhf-checkbox-field | shuip | Components | Free | 3 deps | |
| rhf-combobox-fieldrhf-combobox-field | shuip | Components | Free | 5 deps | |
| rhf-date-fieldrhf-date-field | shuip | Components | Free | 6 deps |
