# or
yarn add @zag-js/editable @zag-js/vue
```

## 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.



## Usage

First, import the editable package into your project

```jsx
import * as editable from "@zag-js/editable"
```

The editable package exports two key functions:

- `machine` â The state machine logic for the editable widget.
- `connect` â The function that translates the machine's state to JSX attributes
  and event handlers.

> You'll need to provide a unique `id` to the `useMachine` hook. This is used to
> ensure that every part has a unique identifier.

Next, import the required hooks and functions for your framework and use the
editable machine in your project ð¥

```html
<script setup>
  import * as editable from "@zag-js/editable"
  import { normalizeProps, useMachine } from "@zag-js/vue"
  import { computed } from "vue"

  const service = useMachine(editable.machine, { id: "1" })
  const api = computed(() => editable.connect(service, normalizeProps))
</script>

<template>
  <div ref="ref" v-bind="api.getRootProps()">
    <div v-bind="api.getAreaProps()">
      <input v-bind="api.getInputProps()" />
      <span v-bind="api.getPreviewProps()" />
    </div>
  </div>
</template>
```

### Setting the initial value

To set the initial value of the editable, pass the `defaultValue` property to
the machine's context.

```jsx {2}
const service = useMachine(editable.machine, {
  defaultValue: "Hello World",
})
```

### Listening for value changes

The editable machine supports two ways of listening for value changes:

- `onValueChange`: called when value changes.
- `onValueCommit`: called when the value is committed.

```jsx {2-4}
const service = useMachine(editable.machine, {
  onValueChange(details) {
    console.log("Value changed", details.value)
  },
  onValueCommit(details) {
    console.log("Value submitted", details.value)
  },
})
```

### 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.

```html
<script setup>
  import * as editable from "@zag-js/editable"
  import { normalizeProps, useMachine } from "@zag-js/vue"
  import { computed } from "vue"

  const service = useMachine(editable.machine, { id: "1" })

  const api = computed(() => editable.connect(service, normalizeProps))
</script>

<template>
  <div ref="ref" v-bind="api.getRootProps()">
    <div v-bind="api.getAreaProps()">
      <input v-bind="api.getInputProps()" />
      <span v-bind="api.getPreviewProps()" />
    </div>
    <div>
      <div v-if="api.editing">
        <button v-bind="api.getSubmitTriggerProps()">Save</button>
        <button v-bind="api.getCancelTriggerProps()">Cancel</button>
      </div>
      <button v-else v-bind="api.getEditTriggerProps()">Edit</button>
    </div>
  </div>
</template>
```

### Auto-resizing

To auto-grow the editable as the content changes, pass the `autoResize: true`
property to the machine's context.

```jsx {2}
const service = useMachine(editable.machine, {
  autoResize: true,
})
```

When using autoresize, the input and preview elements should not have any
styles. Use `all: unset` if needed and pass any styles to the "area" element
since its shared by the input and preview elements.

### 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` property of the machine's context to the
desired value.

```jsx {2-3}
const service = useMachine(editable.machine, {
  autoResize: true,
  maxWidth: "320px",
})
```

When the editable reaches the specified max-width, it'll clip the preview text
with an ellipsis.

### 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", set the `activationMode: 'dblclick'`
property in the machine's context.

```jsx {2}
const service = useMachine(editable.machine, {
  activationMode: "dblclick",
})
```

### Usage with Textarea

The editable machine supports using a `textarea` instead of an `input` field.
When a textarea is used, the editable will commit the value on `Cmd + Enter` or
`Ctrl + Enter`.

> Use the `api.inputProps` to spread the input props to the textarea element.
> You might need to cast the input props to the correct type.

```tsx {2}
<textarea {...(api.inputProps as HTMLTextareaProps<HTMLTextareaElement>)} />
```

## Styling guide

Earlier, we mentioned that each editable part has a `data-part` attribute added
to them to select and style them in the DOM.

### Focused state

When the editable is in the focused mode, we set a `data-focus` attribute on the
"area" part.

```css
[data-part="area"][data-focus] {
  /* CSS for the editable's focus state */
}
```

### Empty state

When the editable's value is empty, we set a `data-empty` attribute on the
"area" part.

```css
[data-part="area"][data-empty] {
  /* CSS for the editable's focus state */
}
```

### Disabled state

When the editable is disabled, we set a `data-disabled` attribute on the "area"
part.

```css
[data-part="area"][data-disabled] {
  /* CSS for the editable's focus state */
}
```

## Methods and Properties

### Machine Context

The editable machine exposes the following context properties:

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

**`invalid`**
Type: `boolean`
Description: Whether the input's value is invalid.

**`name`**
Type: `string`
Description: The name attribute of the editable component. Used for form submission.

**`form`**
Type: `string`
Description: The associate form of the underlying input.

**`autoResize`**
Type: `boolean`
Description: Whether the editable should auto-resize to fit the content.

**`activationMode`**
Type: `ActivationMode`
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

**`submitMode`**
Type: `SubmitMode`
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

**`selectOnFocus`**
Type: `boolean`
Description: Whether to select the text in the input when it is focused.

**`edit`**
Type: `boolean`
Description: Whether the editable is in edit mode.

**`defaultEdit`**
Type: `boolean`
Description: Whether the editable is in edit mode by default.

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

**`maxLength`**
Type: `number`
Description: The maximum number of characters allowed in the editable

**`disabled`**
Type: `boolean`
Description: Whether the editable is disabled.

**`readOnly`**
Type: `boolean`
Description: Whether the editable is read-only.

**`required`**
Type: `boolean`
Description: Whether the editable is required.

**`placeholder`**
Type: `string | { edit: string; preview: string; }`
Description: The placeholder text for the editable.

**`translations`**
Type: `IntlTranslations`
Description: The translations for the editable.

**`finalFocusEl`**
Type: `() => HTMLElement`
Description: The element to receive focus when the editable is closed.

**`value`**
Type: `string`
Description: The controlled value of the editable.

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

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

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

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

**`dir`**
Type: `"ltr" | "rtl"`
Description: The document's text/writing direction.

**`id`**
Type: `string`
Description: The unique identifier of the machine.

**`getRootNode`**
Type: `() => Node | ShadowRoot | Document`
Description: A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.

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

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

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

### Machine API

The editable `api` exposes the following methods:

**`editing`**
Type: `boolean`
Description: Whether the editable is in edit mode

**`empty`**
Type: `boolean`
Description: Whether the editable value is empty

**`value`**
Type: `string`
Description: The current value of the editable

**`valueText`**
Type: `string`
Description: The current value of the editable, or the placeholder if the value is empty

**`setValue`**
Type: `(value: string) => void`
Description: Function to set the value of the editable

**`clearValue`**
Type: `VoidFunction`
Description: Function to clear the value of the editable

**`edit`**
Type: `VoidFunction`
Description: Function to enter edit mode

**`cancel`**
Type: `VoidFunction`
Description: Function to exit edit mode, and discard any changes

**`submit`**
Type: `VoidFunction`
Description: Function to exit edit mode, and submit any changes

### Data Attributes

**`Area`**

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

**`Label`**

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

**`Input`**

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

**`Preview`**

**`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`**: 

## Accessibility

### Keyboard Interactions

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

**`Escape`**
Description: Discards the changes and exits edit mode.
File upload component is used to upload multiple files.

The native input file element is quite difficult to style and doesn't provide a
drag-n-drop version.

> The file upload component doesn't handle the actual file uploading process. It
> only handles the UI and the state of the file upload.

## Resources


[Latest version: v1.33.1](https://www.npmjs.com/package/@zag-js/file-upload)
[Logic Visualizer](https://zag-visualizer.vercel.app/file-upload)
[Source Code](https://github.com/chakra-ui/zag/tree/main/packages/machines/file-upload)



**Features**

- Supports a button to open the file dialog
- Supports drag and drop to upload files
- Set the maximum number of files that can be uploaded
- Set the maximum size of the files that can be uploaded
- Set the accepted file types

## Installation

To use the file upload machine in your project, run the following command in
your command line:

```bash
npm install @zag-js/file-upload @zag-js/vue