Components
Editable

Editable

A component that allows users to edit text in place.

Double click to edit

Anatomy

To set up the editable correctly, you'll need to understand its anatomy and how we name its parts.

Each part includes a data-part attribute to help identify them in the DOM.

Examples

Learn how to use the Editable component in your project. Let's take a look at the most basic example:

import { Editable } from '@ark-ui/solid/editable'

export const Basic = () => (
  <Editable.Root placeholder="Placeholder">
    <Editable.Label>Label</Editable.Label>
    <Editable.Area>
      <Editable.Input />
      <Editable.Preview />
    </Editable.Area>
  </Editable.Root>
)

Using custom 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.

import { Editable } from '@ark-ui/solid/editable'
import { Show } from 'solid-js'

export const CustomControls = () => (
  <Editable.Root placeholder="enter a value" value="Chakra">
    <Editable.Label>Label</Editable.Label>
    <Editable.Area>
      <Editable.Input />
      <Editable.Preview />
    </Editable.Area>
    <Editable.Context>
      {(editable) => (
        <Editable.Control>
          <Show
            when={editable().editing}
            fallback={<Editable.EditTrigger>Edit</Editable.EditTrigger>}
          >
            <Editable.SubmitTrigger>Save</Editable.SubmitTrigger>
            <Editable.CancelTrigger>Canvel</Editable.CancelTrigger>
          </Show>
        </Editable.Control>
      )}
    </Editable.Context>
  </Editable.Root>
)

Auto-resizing the editable

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

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

Setting a maxWidth

It is a common pattern to set a maximum of the editable as it auto-grows. To achieve this, set the maxWidth prop to the desired value.

<Editable.Root placeholder="Placeholder" autoResize maxWidth="320px">
  {/*...*/}
</Editable.Root>

Editing with 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".

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

Using the Field Component

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.

import { Editable } from '@ark-ui/solid/editable'
import { Field } from '@ark-ui/solid/field'

export const WithField = (props: Field.RootProps) => (
  <Field.Root {...props} readOnly>
    <Editable.Root placeholder="Placeholder" activationMode="dblclick">
      <Editable.Label>Label</Editable.Label>
      <Editable.Area>
        <Editable.Input />
        <Editable.Preview />
      </Editable.Area>
    </Editable.Root>
    <Field.HelperText>Additional Info</Field.HelperText>
    <Field.ErrorText>Error Info</Field.ErrorText>
  </Field.Root>
)

Using the Root Provider

The RootProvider component provides a context for the editable. It accepts the value of the useEditable hook. You can leverage it to access the component state and methods from outside the editable.

import { Editable, useEditable } from '@ark-ui/solid/editable'

export const RootProvider = () => {
  const editable = useEditable({ placeholder: 'Placeholder' })

  return (
    <>
      <button onClick={() => editable().edit()}>Edit</button>

      <Editable.RootProvider value={editable}>
        <Editable.Label>Label</Editable.Label>
        <Editable.Area>
          <Editable.Input />
          <Editable.Preview />
        </Editable.Area>
      </Editable.RootProvider>
    </>
  )
}

If you're using the RootProvider component, you don't need to use the Root component.

API Reference

Root

PropDefaultType
activationMode'focus'
ActivationMode

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

asChild
(props: ParentProps<'div'>) => Element

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
autoResize
boolean

Whether the editable should auto-resize to fit the content.

defaultEdit
boolean

The initial edit state of the editable when it is first rendered. Use when you do not need to control its edit state.

defaultValue
string

The initial value of the editable when it is first rendered. Use when you do not need to control the state of the editable.

disabled
boolean

Whether the editable is disabled

edit
boolean

Whether the editable is in edit mode.

finalFocusEl
() => HTMLElement | null

The element that should receive focus when the editable is closed. By default, it will focus on the trigger element.

form
string

The associate form of the underlying input.

ids
Partial<{ root: string area: string label: string preview: string input: string control: string submitTrigger: string cancelTrigger: string editTrigger: string }>

The ids of the elements in the editable. Useful for composition.

invalid
boolean

Whether the input's value is invalid.

maxLength
number

The maximum number of characters allowed in the editable

name
string

The name attribute of the editable component. Used for form submission.

onEditChange
(details: EditChangeDetails) => void

The callback that is called when the edit mode is changed

onFocusOutside
(event: FocusOutsideEvent) => void

Function called when the focus is moved outside the component

onInteractOutside
(event: InteractOutsideEvent) => void

Function called when an interaction happens outside the component

onPointerDownOutside
(event: PointerDownOutsideEvent) => void

Function called when the pointer is pressed down outside the component

onValueChange
(details: ValueChangeDetails) => void

The callback that is called when the editable's value is changed

onValueCommit
(details: ValueChangeDetails) => void

The callback that is called when the editable's value is submitted.

onValueRevert
(details: ValueChangeDetails) => void

The callback that is called when the esc key is pressed or the cancel button is clicked

placeholder
string | { edit: string; preview: string }

The placeholder value to show when the `value` is empty

readOnly
boolean

Whether the editable is readonly

required
boolean

Whether the editable is required

selectOnFocustrue
boolean

Whether to select the text in the input when it is focused.

submitMode'both'
SubmitMode

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
IntlTranslations

Specifies the localized strings that identifies the accessibility elements and their states

value
string

The value of the editable in both edit and preview mode

Area

PropDefaultType
asChild
(props: ParentProps<'div'>) => Element

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[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

PropDefaultType
asChild
(props: ParentProps<'button'>) => Element

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Control

PropDefaultType
asChild
(props: ParentProps<'div'>) => Element

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

EditTrigger

PropDefaultType
asChild
(props: ParentProps<'button'>) => Element

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Input

PropDefaultType
asChild
(props: ParentProps<'input'>) => Element

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[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

PropDefaultType
asChild
(props: ParentProps<'label'>) => Element

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]editable
[data-part]label
[data-focus]Present when focused
[data-invalid]Present when invalid

Preview

PropDefaultType
asChild
(props: ParentProps<'span'>) => Element

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[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

PropDefaultType
value
UseEditableReturn

asChild
(props: ParentProps<'div'>) => Element

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

SubmitTrigger

PropDefaultType
asChild
(props: ParentProps<'button'>) => Element

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Accessibility

Keyboard Support

KeyDescription
Enter
Saves the edited content and exits edit mode.
Escape
Discards the changes and exits edit mode.