# `PhiaUi.Components.Editable`
[🔗](https://github.com/charlenopires/PhiaUI/blob/v0.1.17/lib/phia_ui/components/inputs/editable.ex#L1)

Inline-editable field component — click to edit, Enter to submit, Escape to cancel.

Follows the shadcn/ui "Editable" pattern adapted for Phoenix LiveView. The component
renders in two modes controlled entirely by the `PhiaEditable` JavaScript hook:

- **Preview mode** — shows slot content (or placeholder). A click or keyboard
  activation switches to edit mode.
- **Edit mode** — shows the `:input` slot (an `<input>` or `<textarea>`). `Enter`
  submits the value via `pushEvent/3`; `Escape` cancels without saving. Clicking
  outside the element also cancels.

Zero external JS dependencies — the hook is vanilla JS.

## Usage

    <.editable id="title-edit" value={@title} on_submit="update_title" placeholder="Click to edit">
      <:preview>{@title}</:preview>
      <:input>
        <input type="text" id="title-edit-input" name="title" value={@title}
               class="w-full border rounded px-2 py-1" />
      </:input>
    </.editable>

In your LiveView, handle the submitted value:

    def handle_event("update_title", %{"value" => value}, socket) do
      {:noreply, assign(socket, title: value)}
    end

## Attributes

| Attribute     | Type     | Default           | Description                                  |
|---------------|----------|-------------------|----------------------------------------------|
| `id`          | string   | **required**      | Unique element ID (required by the hook)     |
| `value`       | string   | `nil`             | Current value (for reference; not rendered)  |
| `placeholder` | string   | `"Click to edit"` | Text shown when preview slot is empty        |
| `on_submit`   | string   | `nil`             | LiveView event pushed when user submits       |
| `class`       | string   | `nil`             | Extra classes merged onto the container div  |

## Slots

| Slot      | Required | Description                                         |
|-----------|----------|-----------------------------------------------------|
| `preview` | yes      | Content rendered in preview (read) mode             |
| `input`   | yes      | Content rendered in edit mode (typically `<input>`) |

## Accessibility

- The preview div has `role="button"` and `tabindex="0"` so keyboard users can
  activate it with `Enter` or `Space`.
- `aria-label="Click to edit"` provides a descriptive accessible name.
- The edit-mode input receives focus automatically on activation.

## JS Hook: `PhiaEditable`

Register the hook exported from `priv/templates/js/hooks/editable.js`:

    import PhiaEditable from "../../../deps/phia_ui/priv/templates/js/hooks/editable"

    let liveSocket = new LiveSocket("/live", Socket, {
      hooks: { PhiaEditable }
    })

# `editable`

Renders an inline-editable field.

The component shows the `:preview` slot by default. Clicking (or pressing
`Enter`/`Space`) on the preview activates edit mode and shows the `:input`
slot. The `PhiaEditable` JS hook manages the mode toggle, focus, keyboard
handling, and event dispatch.

## Example

    <.editable id="bio-edit" value={@bio} on_submit="update_bio" placeholder="Add a bio…">
      <:preview>{@bio}</:preview>
      <:input>
        <textarea id="bio-edit-input" name="bio" rows="3"
                  class="w-full border rounded px-2 py-1"><%= @bio %></textarea>
      </:input>
    </.editable>

## Attributes

* `id` (`:string`) (required) - Unique element ID required by the PhiaEditable hook.
* `value` (`:string`) - Current value of the field. Passed to the component for reference. Defaults to `nil`.
* `placeholder` (`:string`) - Placeholder text shown when the preview slot renders no content. Defaults to `"Click to edit"`.
* `on_submit` (`:string`) - LiveView event name pushed when the user submits the new value. Omit to disable submission. Defaults to `nil`.
* `class` (`:string`) - Additional CSS classes merged onto the container div via `cn/1`. Defaults to `nil`.
## Slots

* `preview` (required) - Content displayed in preview (read) mode. May be plain text or rich HTML.
* `input` (required) - Content displayed in edit mode. Should contain an `<input>` or `<textarea>`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
