# Editable

URL: https://ark-ui.com/docs/components/editable
LLM: https://ark-ui.com/llms.txt/components/editable

A component that allows users to edit text in place.

---



## Anatomy



```tsx
<Editable.Root>
  <Editable.Label />
  <Editable.Area>
    <Editable.Input />
    <Editable.Preview />
  </Editable.Area>
  <Editable.Control>
    <Editable.EditTrigger />
    <Editable.SubmitTrigger />
    <Editable.CancelTrigger />
  </Editable.Control>
</Editable.Root>
```

## Examples

```tsx
import { Editable } from '@ark-ui/react/editable'
import { PencilIcon } from 'lucide-react'
import styles from 'styles/editable.module.css'

export const Basic = () => (
  <Editable.Root className={styles.Root} placeholder="Enter text..." defaultValue="Hello World">
    <Editable.Label className={styles.Label}>Label</Editable.Label>
    <Editable.Area className={styles.Area}>
      <Editable.Input className={styles.Input} />
      <Editable.Preview className={styles.Preview} />
    </Editable.Area>
    <Editable.Control className={styles.Control}>
      <Editable.EditTrigger className={styles.EditTrigger}>
        <PencilIcon />
      </Editable.EditTrigger>
    </Editable.Control>
  </Editable.Root>
)
```

### Controlled

Use the `value` and `onValueChange` props to control the editable state.

```tsx
import { Editable } from '@ark-ui/react/editable'
import { PencilIcon } from 'lucide-react'
import { useState } from 'react'
import styles from 'styles/editable.module.css'

export const Controlled = () => {
  const [value, setValue] = useState('Hello World')

  return (
    <Editable.Root
      className={styles.Root}
      placeholder="Enter text..."
      value={value}
      onValueChange={(e) => setValue(e.value)}
    >
      <Editable.Label className={styles.Label}>Label</Editable.Label>
      <Editable.Area className={styles.Area}>
        <Editable.Input className={styles.Input} />
        <Editable.Preview className={styles.Preview} />
      </Editable.Area>
      <Editable.Control className={styles.Control}>
        <Editable.EditTrigger className={styles.EditTrigger}>
          <PencilIcon />
        </Editable.EditTrigger>
      </Editable.Control>
    </Editable.Root>
  )
}
```

### Root Provider

An alternative way to control the editable is to use the `RootProvider` component and the `useEditable` hook. This way
you can access the state and methods from outside the component.

```tsx
import { Editable, useEditable } from '@ark-ui/react/editable'
import { PencilIcon } from 'lucide-react'
import styles from 'styles/editable.module.css'

export const RootProvider = () => {
  const editable = useEditable({ defaultValue: 'Hello World' })

  return (
    <Editable.RootProvider className={styles.Root} value={editable}>
      <Editable.Label className={styles.Label}>Label</Editable.Label>
      <Editable.Area className={styles.Area}>
        <Editable.Input className={styles.Input} />
        <Editable.Preview className={styles.Preview} />
      </Editable.Area>
      <Editable.Control className={styles.Control}>
        <Editable.EditTrigger className={styles.EditTrigger}>
          <PencilIcon />
        </Editable.EditTrigger>
      </Editable.Control>
    </Editable.RootProvider>
  )
}
```

### Context

Access the editable's state with `Editable.Context` or the `useEditableContext` hook—great for showing keyboard hints
when editing.

```tsx
import { Editable } from '@ark-ui/react/editable'
import { PencilIcon } from 'lucide-react'
import styles from 'styles/editable.module.css'

export const Context = () => (
  <Editable.Root className={styles.Root} placeholder="Enter text..." defaultValue="Hello World">
    <Editable.Label className={styles.Label}>Label</Editable.Label>
    <Editable.Area className={styles.Area}>
      <Editable.Input className={styles.Input} />
      <Editable.Preview className={styles.Preview} />
    </Editable.Area>
    <Editable.Context>
      {(editable) =>
        editable.editing ? (
          <span className={styles.HelperText}>Enter to save, Esc to cancel</span>
        ) : (
          <Editable.Control className={styles.Control}>
            <Editable.EditTrigger className={styles.EditTrigger}>
              <PencilIcon />
            </Editable.EditTrigger>
          </Editable.Control>
        )
      }
    </Editable.Context>
  </Editable.Root>
)
```

### Controls

In some cases, you might need to use custom controls to toggle the edit and read mode. We use the render prop pattern to
provide access to the internal state of the component.

```tsx
import { Editable } from '@ark-ui/react/editable'
import { CheckIcon, PencilIcon, XIcon } from 'lucide-react'
import styles from 'styles/editable.module.css'

export const Controls = () => (
  <Editable.Root className={styles.Root} defaultValue="Click edit to start">
    <Editable.Label className={styles.Label}>Label</Editable.Label>
    <Editable.Area className={styles.Area}>
      <Editable.Input className={styles.Input} />
      <Editable.Preview className={styles.Preview} />
    </Editable.Area>
    <Editable.Context>
      {(editable) => (
        <Editable.Control className={styles.Control}>
          {editable.editing ? (
            <>
              <Editable.SubmitTrigger className={styles.SubmitTrigger}>
                <CheckIcon />
              </Editable.SubmitTrigger>
              <Editable.CancelTrigger className={styles.CancelTrigger}>
                <XIcon />
              </Editable.CancelTrigger>
            </>
          ) : (
            <Editable.EditTrigger className={styles.EditTrigger}>
              <PencilIcon />
            </Editable.EditTrigger>
          )}
        </Editable.Control>
      )}
    </Editable.Context>
  </Editable.Root>
)
```

### Textarea

Use the `asChild` prop on `Editable.Input` to render a textarea for multi-line editing.

```tsx
import { Editable } from '@ark-ui/react/editable'
import styles from 'styles/editable.module.css'

export const Textarea = () => (
  <Editable.Root
    className={styles.Root}
    placeholder="Enter a description..."
    defaultValue="Ark UI is a headless component library for building reusable, scalable design systems."
    activationMode="dblclick"
  >
    <Editable.Label className={styles.Label}>Description</Editable.Label>
    <Editable.Area className={styles.Area}>
      <Editable.Input className={styles.Textarea} asChild>
        <textarea />
      </Editable.Input>
      <Editable.Preview className={styles.Textarea} />
    </Editable.Area>
    <div className={styles.HelperText}>Press Cmd + Enter to save</div>
  </Editable.Root>
)
```

### Field

The `Field` component helps manage form-related state and accessibility attributes of an editable. It includes handling
ARIA labels, helper text, and error text to ensure proper accessibility.

```tsx
import { Editable } from '@ark-ui/react/editable'
import { Field } from '@ark-ui/react/field'
import field from 'styles/field.module.css'
import styles from 'styles/editable.module.css'

export const WithField = () => (
  <Field.Root className={field.Root}>
    <Editable.Root className={styles.Root} placeholder="Enter your bio">
      <Editable.Label className={field.Label}>Bio</Editable.Label>
      <Editable.Area className={styles.Area}>
        <Editable.Input className={styles.Input} />
        <Editable.Preview className={styles.Preview} />
      </Editable.Area>
    </Editable.Root>
    <Field.HelperText className={field.HelperText}>Click to edit your bio</Field.HelperText>
    <Field.ErrorText className={field.ErrorText}>Bio is required</Field.ErrorText>
  </Field.Root>
)
```

## Guides

### Auto-resizing

To auto-grow the editable as the content changes, set the `autoResize` prop to `true`.

```tsx
<Editable.Root placeholder="Placeholder" autoResize>
  {/*...*/}
</Editable.Root>
```

### Max Length

Use the `maxLength` prop to set a maximum number of characters that can be entered into the editable.

```tsx
<Editable.Root placeholder="Placeholder" autoResize maxLength={10}>
  {/*...*/}
</Editable.Root>
```

### Double Click

The editable supports two modes of activating the "edit" state:

- when the preview part is focused (with pointer or keyboard).
- when the preview part is double-clicked.

To change the mode to double-click, pass the prop `activationMode="dblclick"`.

```tsx
<Editable.Root placeholder="Placeholder" activationMode="dblclick">
  {/*...*/}
</Editable.Root>
```

## API Reference

### Props

### Root

#### Props

**`activationMode`**
Type: `ActivationMode`
Required: false
Default Value: `"focus"`
Description: The activation mode for the preview element.

- "focus" - Enter edit mode when the preview is focused
- "dblclick" - Enter edit mode when the preview is double-clicked
- "click" - Enter edit mode when the preview is clicked
- "none" - Edit can be triggered programmatically only

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

**`autoResize`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the editable should auto-resize to fit the content.

**`defaultEdit`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the editable is in edit mode by default.

**`defaultValue`**
Type: `string`
Required: false
Default Value: `undefined`
Description: The initial value of the editable when rendered.
Use when you don't need to control the value of the editable.

**`disabled`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the editable is disabled.

**`edit`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the editable is in edit mode.

**`finalFocusEl`**
Type: `() => HTMLElement | null`
Required: false
Default Value: `undefined`
Description: The element to receive focus when the editable is closed.

**`form`**
Type: `string`
Required: false
Default Value: `undefined`
Description: The associate form of the underlying input.

**`id`**
Type: `string`
Required: false
Default Value: `undefined`
Description: The unique identifier of the machine.

**`ids`**
Type: `Partial<{
  root: string
  area: string
  label: string
  preview: string
  input: string
  control: string
  submitTrigger: string
  cancelTrigger: string
  editTrigger: string
}>`
Required: false
Default Value: `undefined`
Description: The ids of the elements in the editable. Useful for composition.

**`invalid`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the input's value is invalid.

**`maxLength`**
Type: `number`
Required: false
Default Value: `undefined`
Description: The maximum number of characters allowed in the editable

**`name`**
Type: `string`
Required: false
Default Value: `undefined`
Description: The name attribute of the editable component. Used for form submission.

**`onEditChange`**
Type: `(details: EditChangeDetails) => void`
Required: false
Default Value: `undefined`
Description: Function to call when the edit mode changes.

**`onFocusOutside`**
Type: `(event: FocusOutsideEvent) => void`
Required: false
Default Value: `undefined`
Description: Function called when the focus is moved outside the component

**`onInteractOutside`**
Type: `(event: InteractOutsideEvent) => void`
Required: false
Default Value: `undefined`
Description: Function called when an interaction happens outside the component

**`onPointerDownOutside`**
Type: `(event: PointerDownOutsideEvent) => void`
Required: false
Default Value: `undefined`
Description: Function called when the pointer is pressed down outside the component

**`onValueChange`**
Type: `(details: ValueChangeDetails) => void`
Required: false
Default Value: `undefined`
Description: Function to call when the value changes.

**`onValueCommit`**
Type: `(details: ValueChangeDetails) => void`
Required: false
Default Value: `undefined`
Description: Function to call when the value is committed.

**`onValueRevert`**
Type: `(details: ValueChangeDetails) => void`
Required: false
Default Value: `undefined`
Description: Function to call when the value is reverted.

**`placeholder`**
Type: `string | { edit: string; preview: string }`
Required: false
Default Value: `undefined`
Description: The placeholder text for the editable.

**`readOnly`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the editable is read-only.

**`required`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Whether the editable is required.

**`selectOnFocus`**
Type: `boolean`
Required: false
Default Value: `true`
Description: Whether to select the text in the input when it is focused.

**`submitMode`**
Type: `SubmitMode`
Required: false
Default Value: `"both"`
Description: The action that triggers submit in the edit mode:

- "enter" - Trigger submit when the enter key is pressed
- "blur" - Trigger submit when the editable is blurred
- "none" - No action will trigger submit. You need to use the submit button
- "both" - Pressing `Enter` and blurring the input will trigger submit

**`translations`**
Type: `IntlTranslations`
Required: false
Default Value: `undefined`
Description: The translations for the editable.

**`value`**
Type: `string`
Required: false
Default Value: `undefined`
Description: The controlled value of the editable.

### Area

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-scope`**: editable
**`data-part`**: area
**`data-focus`**: Present when focused
**`data-disabled`**: Present when disabled
**`data-placeholder-shown`**: Present when placeholder is shown

### CancelTrigger

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### Control

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### EditTrigger

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### Input

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-scope`**: editable
**`data-part`**: input
**`data-disabled`**: Present when disabled
**`data-readonly`**: Present when read-only
**`data-invalid`**: Present when invalid
**`data-autoresize`**: 

### Label

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-scope`**: editable
**`data-part`**: label
**`data-focus`**: Present when focused
**`data-invalid`**: Present when invalid
**`data-required`**: Present when required

### Preview

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

#### Data Attributes

**`data-scope`**: editable
**`data-part`**: preview
**`data-placeholder-shown`**: Present when placeholder is shown
**`data-readonly`**: Present when read-only
**`data-disabled`**: Present when disabled
**`data-invalid`**: Present when invalid
**`data-autoresize`**: 

### RootProvider

#### Props

**`value`**
Type: `UseEditableReturn`
Required: true
Default Value: `undefined`
Description: undefined

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### SubmitTrigger

#### Props

**`asChild`**
Type: `boolean`
Required: false
Default Value: `undefined`
Description: Use the provided child element as the default rendered element, combining their props and behavior.

### Context

**API:**

| Property | Type | Description |
|----------|------|-------------|
| `editing` | `boolean` | Whether the editable is in edit mode |
| `empty` | `boolean` | Whether the editable value is empty |
| `value` | `string` | The current value of the editable |
| `valueText` | `string` | The current value of the editable, or the placeholder if the value is empty |
| `setValue` | `(value: string) => void` | Function to set the value of the editable |
| `clearValue` | `VoidFunction` | Function to clear the value of the editable |
| `edit` | `VoidFunction` | Function to enter edit mode |
| `cancel` | `VoidFunction` | Function to exit edit mode, and discard any changes |
| `submit` | `VoidFunction` | Function to exit edit mode, and submit any changes |


## Accessibility

### Keyboard Support

**`Enter`**
Description: Saves the edited content and exits edit mode.

**`Escape`**
Description: Discards the changes and exits edit mode.