tsf-inline-edit
shuip/tsf-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/tsf-inline-edit.jsonSource
1'use client';23import { InfoIcon } from 'lucide-react';4import * as React from 'react';5import { Field, FieldLabel } from '@/components/ui/field';6import { Input } from '@/components/ui/input';7import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';8import { useFieldContext } from '@/components/ui/shuip/tanstack-form/form-context';9import { Textarea } from '@/components/ui/textarea';10import { cn } from '@/lib/utils';1112type InlineEditSize = 'sm' | 'default' | 'title';13type InlineEditVariant = 'ghost' | 'boxed';14type InlineEditInput = 'text' | 'textarea';1516interface InlineEditProps {17 value: string;18 onCommit: (next: string) => Promise<string | undefined> | string | undefined;19 input?: InlineEditInput;20 variant?: InlineEditVariant;21 size?: InlineEditSize;22 placeholder?: string;23 canEdit?: boolean;24 children?: (api: {25 value: string;26 setValue: (v: string) => void;27 commit: (next?: string) => void;28 cancel: () => void;29 className: string;30 autoFocus: true;31 }) => React.ReactNode;32}3334type State =35 | { kind: 'reading' }36 | { kind: 'editing'; draft: string; error?: string }37 | { kind: 'saving'; draft: string };3839const sizeClasses: Record<InlineEditSize, string> = {40 sm: 'px-1.5 py-0.5 text-xs',41 default: 'px-2 py-1 text-sm',42 title: 'px-2 py-1 text-3xl font-semibold tracking-tight',43};4445const variantClasses: Record<InlineEditVariant, string> = {46 ghost:47 'border border-transparent bg-transparent hover:bg-muted focus-visible:bg-muted dark:bg-transparent dark:hover:bg-muted',48 boxed: 'border border-input bg-transparent shadow-xs focus-visible:border-ring',49};5051function InlineEdit({52 value,53 onCommit,54 input = 'text',55 variant = 'ghost',56 size = 'default',57 placeholder = '—',58 canEdit = true,59 children,60}: InlineEditProps) {61 const [state, setState] = React.useState<State>({ kind: 'reading' });62 const errorId = React.useId();6364 const fieldClassName = cn(65 'w-full rounded-md text-left outline-none transition-colors focus-visible:ring-[3px] focus-visible:ring-ring/50',66 sizeClasses[size],67 variantClasses[variant],68 );6970 const startEdit = () => {71 if (canEdit) setState({ kind: 'editing', draft: value });72 };7374 const cancel = () => setState({ kind: 'reading' });7576 const setDraft = (draft: string) => setState((s) => (s.kind === 'editing' ? { kind: 'editing', draft } : s));7778 const commit = async (override?: string) => {79 if (state.kind !== 'editing') return;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 |
