|
|
5 months ago | |
|---|---|---|
| .. | ||
| components | 5 months ago | |
| README.md | 6 months ago | |
| editable-provider.svelte.test.ts | 5 months ago | |
| editable-provider.svelte.ts | 5 months ago | |
| exports.ts | 5 months ago | |
| index.ts | 6 months ago | |
| langs.ts | 5 months ago | |
| types.ts | 5 months ago | |
README.md
Editable
Inline editable text that toggles between a preview display and an input field. Supports multiple activation and submit modes, auto-resize, draft tracking, and keyboard shortcuts.
Anatomy
<Editable.Provider bind:value>
<Editable.Area>
<Editable.Preview />
<Editable.Input />
</Editable.Area>
<Editable.EditTrigger>Edit</Editable.EditTrigger>
<Editable.SubmitTrigger>Save</Editable.SubmitTrigger>
<Editable.CancelTrigger>Cancel</Editable.CancelTrigger>
</Editable.Provider>
Preview and Input swap visibility based on editing state. Trigger buttons are optional — activation can happen via focus, click, or double-click on the preview.
Parts
| Part | Element | Description |
|---|---|---|
Provider |
<div> |
Root container. Manages value, draft, editing state. |
Area |
<div> |
Wrapper for Preview + Input. |
Preview |
<div> |
Static display of the committed value or placeholder. |
Input |
<input> |
Text editing field. Hidden when not editing. Use child snippet for textarea. |
EditTrigger |
<button> |
Enter edit mode. Hidden when editing. |
SubmitTrigger |
<button> |
Commit changes. Hidden when not editing. |
CancelTrigger |
<button> |
Discard changes. Hidden when not editing. |
Data Attributes
| Part | Attribute | Values |
|---|---|---|
| Provider | data-editable |
Always present |
| Provider | data-editing |
Present when in edit mode |
| Provider | data-empty |
Present when value is empty |
| Provider | data-disabled |
Present when disabled |
| Provider | data-readonly |
Present when readonly |
| Area | data-editable-area |
Always present |
| Area | data-editing |
Present when in edit mode |
| Area | data-disabled |
Present when disabled |
| Area | data-readonly |
Present when readonly |
| Preview | data-editable-preview |
Always present |
| Preview | data-placeholder-shown |
Present when showing placeholder |
| Preview | data-disabled |
Present when disabled |
| Preview | data-readonly |
Present when readonly |
| Input | data-editable-input |
Always present |
| Input | data-disabled |
Present when disabled |
| Input | data-readonly |
Present when readonly |
Keyboard
| Key | Action |
|---|---|
Enter |
Submit changes (if submitMode includes 'enter') |
Escape |
Cancel changes and exit edit mode |
Tab (from input) |
Submit if submitMode='blur'/'both', cancel otherwise |
Behavior
Activation modes
| Mode | Behavior |
|---|---|
focus |
Focus the preview to start editing (default) |
click |
Click the preview to start editing |
dblclick |
Double-click the preview to start editing |
none |
Only via EditTrigger or programmatically |
Submit modes
| Mode | Behavior |
|---|---|
blur |
Blur commits changes (default) |
enter |
Enter key commits changes |
both |
Both Enter and blur commit |
none |
Only via SubmitTrigger or programmatically |
Draft tracking
Edits are stored in a draft until submitted. Cancel reverts to the last committed value.
Auto-resize
When autoResize is true, the input uses field-sizing: content to grow with its content.
Select on focus
When selectOnFocus is true (default), all text is selected when entering edit mode.
Blur handling
Blur to SubmitTrigger, CancelTrigger, or EditTrigger does NOT trigger blur-submit/cancel — only blur to other elements does.
Textarea support
Use the child snippet on Input to render a textarea:
<Editable.Input>
{#snippet child({ props })}
<textarea {...props}></textarea>
{/snippet}
</Editable.Input>
Usage
Basic (focus to edit, blur to submit)
<script>
import { Editable } from '$soma/components';
let name = $state('John Doe');
</script>
<Editable.Provider bind:value={name}>
<Editable.Area>
<Editable.Preview />
<Editable.Input />
</Editable.Area>
</Editable.Provider>
Double-click to edit, Enter to submit
<Editable.Provider bind:value={name} activationMode="dblclick" submitMode="enter">
<Editable.Area>
<Editable.Preview />
<Editable.Input />
</Editable.Area>
</Editable.Provider>
With trigger buttons
<Editable.Provider bind:value={name} activationMode="none" submitMode="none">
<Editable.Area>
<Editable.Preview />
<Editable.Input />
</Editable.Area>
<Editable.EditTrigger>Edit</Editable.EditTrigger>
<Editable.SubmitTrigger>Save</Editable.SubmitTrigger>
<Editable.CancelTrigger>Cancel</Editable.CancelTrigger>
</Editable.Provider>
With placeholder
<Editable.Provider bind:value={bio} placeholder="Click to add bio...">...</Editable.Provider>
Max length
<Editable.Provider bind:value={username} maxLength={20}>...</Editable.Provider>
Comparison with reference libraries
| Feature | Ark UI | Radix Vue | Chakra v3 | Bits UI | Soma |
|---|---|---|---|---|---|
| Parts | Root, Label, Area, Preview, Input, Control, EditTrigger, SubmitTrigger, CancelTrigger | Root, Area, Preview, Input, EditTrigger, SubmitTrigger, CancelTrigger | Same as Ark | No Editable | Provider, Area, Preview, Input, EditTrigger, SubmitTrigger, CancelTrigger |
| activationMode | focus/click/dblclick/none | focus/dblclick/none | Yes (via Ark) | N/A | focus/click/dblclick/none |
| submitMode | enter/blur/both/none | blur/enter/both/none | Yes (via Ark) | N/A | enter/blur/both/none |
| autoResize | Yes | Yes | Yes | N/A | Yes (field-sizing: content) |
| maxLength | Yes | Yes | Yes | N/A | Yes |
| selectOnFocus | Yes | Yes | Yes | N/A | Yes |
| Placeholder | { edit, preview } | Single string | Yes (via Ark) | N/A | Single string |
| Textarea support | Via asChild | Yes | Textarea part | N/A | Via child snippet |
| Draft tracking | Yes | Yes | Yes | N/A | Yes |
| onValueCommit | Yes | Implicit | Yes | N/A | Yes |
| onValueRevert | Yes | Implicit | Yes | N/A | Yes |
| Blur to triggers handled | Yes | Yes | Yes | N/A | Yes |
| disabled / readonly | Yes | Yes | Yes | N/A | Yes |
| data-* attributes | Extensive | Moderate | Via Ark | N/A | Comprehensive |
| ARIA | Full | Basic | Via Ark | N/A | Semantic HTML + aria-label on triggers |