# Editable Record Detail URL: /docs/web/components/editable-record-detail Inline record editing with change tracking, validation, hidden fields, and a floating action bar. **Demo:** ```tsx 'use client'; import { useCallback, useState } from 'react'; import { type EnumOption } from '@docyrus/ui/components/form-fields'; import { EditableRecordDetail, EditableRecordDetailField, type FieldChange, type RecordDetailField } from '@docyrus/ui/components/editable-record-detail'; import { cn } from '@docyrus/ui/primitives/lib/utils'; import { Switch } from '@docyrus/ui/primitives/ui/switch'; // ── Field configs ────────────────────────────────────────── const PRIORITY_OPTIONS: Array ); } ``` ## Installation ```bash pnpm dlx @docyrus/cli add @docyrus/ui-editable-record-detail ``` **Dependencies:** - [lucide-react](https://www.npmjs.com/package/lucide-react) ## Usage ```tsx import { EditableRecordDetail, EditableRecordDetailField, useEditableRecordDetail } from "@docyrus/ui/components/editable-record-detail"; ``` ## API Reference ### EditableRecordDetailProps | Prop | Type | Default | Description | |------|------|---------|-------------| | `fields` | `Array` | — | Field configurations | | `record` | `Record` | — | Current record values keyed by field slug | | `onSave` | `(changes: Array, values: Record) => void \| Promise` | — | Called when save is triggered | | `onCancel` | `() => void` | — | Called when cancel is triggered | | `form` | `any` | — | External TanStack Form instance (skips internal macro-form) | | `readOnly` | `boolean` | `false` | Whether all fields are read-only | | `disabled` | `boolean` | `false` | Whether all fields are disabled | | `trackChanges` | `boolean` | `true` | Whether changed fields should be visually highlighted | | `actionBarSideOffset` | `number` | — | Side offset for the floating action bar | | `children` | `ReactNode` | — | Content (EditableRecordDetailField components) | | `className` | `string` | — | Additional CSS class | ### RecordDetailField | Property | Type | Default | Description | |----------|------|---------|-------------| | `field` | `IField` | — | Field configuration object | | `enumOptions` | `Array` | — | Enum options for select-based fields | | `readOnly` | `boolean` | — | Whether this field is read-only | | `required` | `boolean \| ((values: Record) => boolean)` | — | Whether the field is required. Supports a callback for computed required based on other field values | | `hidden` | `boolean \| ((values: Record) => boolean)` | — | Whether the field should be hidden. Supports a callback for computed visibility based on other field values. Hidden fields are excluded from validation | | `appSlug` | `string` | — | App slug for dynamic enum loading | | `dataSourceSlug` | `string` | — | Data source slug for dynamic enum loading | ### EditableRecordDetailFieldProps | Prop | Type | Default | Description | |------|------|---------|-------------| | `slug` | `string` | — | Field slug (looks up config from context) | | `label` | `ReactNode` | — | Optional label override | | `showLabel` | `boolean` | `true` | Render label + value row | | `className` | `string` | — | Additional CSS class | ### useEditableRecordDetail Hook to access the EditableRecordDetail context from within the provider. | Return | Type | Description | |--------|------|-------------| | `form` | `any` | The form instance (internal macro-form or external) | | `values` | `Record` | Current record values | | `changedFields` | `Set` | Set of changed field slugs | | `changedFieldCount` | `number` | Number of changed fields | | `valuesVersion` | `number` | Counter that increments on every field value change. Use to trigger re-renders for cross-field reactivity | | `isFieldChanged` | `(slug: string) => boolean` | Check if a specific field has changed | | `getFieldValue` | `(slug: string) => unknown` | Get the current value of a field | | `setFieldValue` | `(slug: string, value: unknown) => void` | Programmatically set a field value and trigger re-render | | `getChanges` | `() => Array` | Get all pending changes | | `handleSave` | `() => Promise` | Trigger save with validation | | `handleCancel` | `() => void` | Discard all changes and reset to original values | | `isSaving` | `boolean` | Whether a save is in progress | ### FieldChange | Property | Type | Description | |----------|------|-------------| | `fieldSlug` | `string` | Field slug | | `fieldName` | `string` | Field display name | | `originalValue` | `unknown` | Value before change | | `newValue` | `unknown` | Current value |