Editable
Use CEditable for compact names, titles, and labels that are usually read and occasionally changed. It keeps one native Input as form and validity truth.
Editable at a glance
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class EditableAtAGlance(Component):
template = """
<c-CField>
<c-fill name="label">Project name</c-fill>
<c-fill name="description">Use the pencil to rename this project in place.</c-fill>
<c-fill name="default">
<c-CEditable value="Aurora atlas" name="project-name" />
</c-fill>
</c-CField>
"""
preview = EditableAtAGlance()
preview # noqa: B018
Submit and reset a value
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class EditableForm(Component):
template = """
<form x-data @submit.prevent="result = Object.fromEntries(new FormData($event.target))">
<c-CField required>
<c-fill name="label">Workspace title</c-fill>
<c-fill name="default">
<c-CEditable value="Field notes" name="title" />
</c-fill>
</c-CField>
<c-CButton type="submit">Save form</c-CButton>
<c-CButton type="reset" variant="ghost">Reset</c-CButton>
<output x-text="JSON.stringify(result)"></output>
</form>
"""
preview = EditableForm()
preview # noqa: B018
Control the committed value
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class ControlledEditable(Component):
template = """
<div x-data>
<c-CEditable
value="Atlas"
$c-props="{
value:$store.editableExample.value,
onValueChange:(next) => $store.editableExample.value = next,
}"
/>
<p>Committed: <strong x-text="$store.editableExample.value"></strong></p>
</div>
"""
js = "Alpine.store('editableExample', {value:'Atlas'});"
preview = ControlledEditable()
preview # noqa: B018
Choose when editing commits
The default both mode commits with Enter or when focus leaves the whole component. enter, blur, and explicit narrow that behavior.
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class EditableSubmitModes(Component):
template = """
<c-CStack>
<c-CEditable value="Enter or blur" submit_mode="both" c-input_attrs="{'aria-label':'Both'}" />
<c-CEditable value="Enter only" submit_mode="enter" c-input_attrs="{'aria-label':'Enter only'}" />
<c-CEditable value="Blur only" submit_mode="blur" c-input_attrs="{'aria-label':'Blur only'}" />
<c-CEditable value="Buttons only" submit_mode="explicit" c-input_attrs="{'aria-label':'Explicit'}" />
</c-CStack>
"""
preview = EditableSubmitModes()
preview # noqa: B018
Place edit actions
Pencil, confirm, and cancel actions sit inside the Input at inline-end by default. Use action_position="outside" when they need independent space.
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class EditableActionPositions(Component):
template = """
<c-CStack>
<c-CEditable value="Actions inside by default" editing c-input_attrs="{'aria-label':'Inside actions'}" />
<c-CEditable
value="Actions beside the input" editing action_position="outside"
c-input_attrs="{'aria-label':'Outside actions'}"
/>
</c-CStack>
"""
preview = EditableActionPositions()
preview # noqa: B018
States, variants, and sizes
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class EditableStates(Component):
template = """
<c-CStack>
<c-CEditable value="Available" c-input_attrs="{'aria-label':'Available title'}" />
<c-CEditable value="Read only" readonly c-input_attrs="{'aria-label':'Read-only title'}" />
<c-CEditable value="Disabled" disabled c-input_attrs="{'aria-label':'Disabled title'}" />
<c-CEditable value="Needs review" invalid c-input_attrs="{'aria-label':'Invalid title'}" />
<c-CEditable placeholder="Empty value" c-input_attrs="{'aria-label':'Empty title'}" />
</c-CStack>
"""
preview = EditableStates()
preview # noqa: B018
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class EditableVariants(Component):
template = """
<c-CStack>
<c-CEditable value="Small outline" variant="outline" size="sm" />
<c-CEditable value="Medium filled" variant="filled" />
<c-CEditable value="Large plain" variant="plain" size="lg" />
</c-CStack>
"""
preview = EditableVariants()
preview # noqa: B018
Keyboard behavior
The edit Button enters edit mode. Enter commits when enabled by submit_mode, Escape cancels, and Tab follows ordinary page order. Blur modes commit only after focus leaves the Input and both edit actions.
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class EditableKeyboard(Component):
template = """
<c-CStack>
<p>Tab to Edit, press Enter to edit, then Enter to save or Escape to cancel.</p>
<c-CEditable value="Keyboard friendly" />
<c-CButton variant="outline">Next focus target</c-CButton>
</c-CStack>
"""
preview = EditableKeyboard()
preview # noqa: B018
Customize Editable
Show code
import citry_ui
from citry import Component, citry
citry.register_library(citry_ui)
class CustomizedEditable(Component):
template = """
<c-CEditable
value="Branded title" editing
style="--cui-editable-background:#fff8eb; --cui-editable-border-color:#f79009;
--cui-editable-focus-color:#b54708; --cui-editable-radius:1rem"
c-input_attrs="{'aria-label':'Branded title'}"
/>
"""
preview = CustomizedEditable()
preview # noqa: B018
Accessibility and forms
View mode exposes ordinary text and a named edit Button. Edit mode exposes one native text Input plus named confirm and cancel Buttons. The Input stays the successful form control in both modes and owns required validity and reset. Before client initialization the native Input is the visible fallback.
Use CInput for a value that is primarily edited, and CTextarea for multiline content.
API reference
Inputs
CEditable server inputs
Server inputs are passed in a template through <c-CEditable ... /> or in Python through CEditable(...).
| Input | Type | Default | Effect |
|---|---|---|---|
value | str | "" | Sets the initial committed and native form value. |
placeholder | str | "Click to edit" | Supplies author-localized empty preview and Input text. |
name | str | None | None | Sets the native form field name. |
form | str | None | None | Associates the native Input with a Form ID. |
id | str | None | None | Sets native Input identity. |
editing | bool | False | Sets initial edit mode. |
required | bool | None | None | Enables native required validity outside Field. |
disabled | bool | None | None | Disables editing and form contribution. |
readonly | bool | None | None | Preserves submission while preventing editing. |
invalid | bool | None | None | Adds owner-supplied invalid presentation. |
max_length | int | None | None | Sets native maximum length. |
autocomplete | str | None | None | Sets the native autocomplete hint. |
inputmode | str | None | None | Sets the native virtual-keyboard hint. |
submit_mode | "enter" | "blur" | "both" | "explicit" (CEditableSubmitMode) | "both" | Selects commit triggers. |
select_on_focus | bool | True | Selects the draft when editing begins. |
action_position | "inside" | "outside" (CEditableActionPosition) | "inside" | Places edit actions inside the Input at inline-end or outside it. |
edit_label | str | "Edit" | Names the pencil Button. |
submit_label | str | "Save" | Names the confirm Button. |
cancel_label | str | "Cancel" | Names the cancel Button. |
variant | "outline" | "filled" | "plain" (CEditableVariant) | "outline" | Selects surface treatment. |
size | "sm" | "md" | "lg" (CEditableSize) | "md" | Selects Input and action geometry. |
class_ | CClassValue | None | None | Adds root classes. |
style | CStyleValue | None | None | Adds root inline styles. |
attrs | Mapping[str, object] | None | None | Adds trusted nonconflicting root attributes. |
input_attrs | Mapping[str, object] | None | None | Adds trusted native Input attributes and relationships. |
preview_attrs | Mapping[str, object] | None | None | Adds trusted nonconflicting preview attributes. |
CEditable client inputs
Client inputs are passed in the browser through the $c-props="{ ... }" attribute on <c-CEditable />.
| Input | Type | Omitted behavior | Effect |
|---|---|---|---|
value | string | null | Releases control to the committed value. | Controls the committed value while supplied. |
editing | boolean | null | Releases control to committed edit mode. | Controls view or edit mode while supplied. |
required | bool | Uses the server or Field fallback. | Reactively changes required validity. |
disabled | bool | Uses the server or Field fallback. | Reactively disables editing. |
readonly | bool | Uses the server or Field fallback. | Reactively prevents editing while preserving submission. |
invalid | bool | Uses the server or Field fallback. | Reactively changes invalid presentation. |
submitMode | CEditableSubmitMode | Uses the server value. | Reactively changes commit triggers. |
selectOnFocus | bool | Uses the server value. | Reactively changes entry selection. |
actionPosition | CEditableActionPosition | Uses the server value. | Reactively places the actions inside or outside. |
variant | CEditableVariant | Uses the server value. | Reactively changes treatment. |
size | CEditableSize | Uses the server value. | Reactively changes geometry. |
onValueChange | ((value: string, detail: CEditableValueChangeDetail) => void) | undefined | No component callback runs. | Receives commit and reset requests. |
onEditChange | ((editing: boolean, detail: CEditableEditChangeDetail) => void) | undefined | No component callback runs. | Receives mode requests and forced closes. |
Slots
-
Events
Component events are callback inputs supplied through $c-props. Native browser events remain available through Alpine @... attributes.
CEditable events
| Event | Signature | Trigger and timing | Detail | Controlled and cancellation behavior |
|---|---|---|---|---|
onValueChange | (value: string, detail: CEditableValueChangeDetail) => void (CEditableValueChangeDetail) | Submit blur or reset request. | {value, previousValue, controlled, source, sourceEvent} (CEditableValueChangeDetail) | Commits immediately when uncontrolled and waits for owner acceptance when controlled. |
onEditChange | (editing: boolean, detail: CEditableEditChangeDetail) => void (CEditableEditChangeDetail) | Edit submit cancel blur reset or safety transition. | {editing, reason, controlled, forced, source} (CEditableEditChangeDetail) | Controlled requests notify without changing mode; forced safety transitions always close. |
Methods
-
CSS
CSS variables to theme the components. Set them on an ancestor or the component itself.
CEditable CSS variables
Apply these variables to CEditable or one of its ancestors.
| Variable | Type | Purpose | Default |
|---|---|---|---|
--cui-editable-background | color | Preview and Input surface. | Canvas |
--cui-editable-foreground | color | Primary text. | CanvasText |
--cui-editable-border-color | color | Surface border. | scheme-aware border |
--cui-editable-hover-border-color | color | Hover border. | scheme-aware strong border |
--cui-editable-focus-color | color | Focus outline. | Highlight |
--cui-editable-invalid-border-color | color | Invalid border. | scheme-aware red |
--cui-editable-muted-color | color | Empty preview foreground. | scheme-aware muted |
--cui-editable-action-background | color | Action Button surface. | CanvasText mix |
--cui-editable-action-foreground | color | Action Button foreground. | CanvasText |
--cui-editable-radius | length | Surface corners. | 0.5rem |
--cui-editable-height | length | Minimum surface height. | size-derived |
--cui-editable-padding | length | Surface padding. | size-derived |
--cui-editable-action-size | length | Action Button square size. | size-derived |
--cui-editable-gap | length | Action and outside-layout gap. | 0.375rem |
Attributes
HTML attributes defined on the components that you can refer to for CSS, inspection, and testing. Read-only.
CEditable attributes
| Attribute | Element | Type | Meaning |
|---|---|---|---|
data-editing | Root | present-or-absent | Mirrors effective edit mode. |
data-empty | Root | present-or-absent | Mirrors an empty committed value. |
data-required | Root | present-or-absent | Mirrors required validity. |
data-disabled | Root | present-or-absent | Mirrors effective disabled state. |
data-readonly | Root | present-or-absent | Mirrors read-only state. |
data-invalid | Root | present-or-absent | Mirrors external or native invalid state. |
data-submit-mode | Root | CEditableSubmitMode | Reflects commit behavior. |
data-action-position | Root | CEditableActionPosition | Reflects action placement. |
data-variant | Root | CEditableVariant | Reflects treatment. |
data-size | Root | CEditableSize | Reflects geometry. |
aria-invalid | Native Input | true or absent | Mirrors external or native invalid state. |
aria-describedby | Native Input | IDREF list or absent | Merges Field and trusted description relationships. |
aria-errormessage | Native Input | IDREF list or absent | Merges active Field and trusted error relationships. |
Selectors
Selectors for the DOM nodes in the components that you can use for CSS, inspection, and testing.
CEditable selectors
| Selector | Element | Purpose |
|---|---|---|
[data-citry-ui-part="root"] | Root div | Stable root and state surface. |
[data-citry-ui-part="preview"] | Preview div | View-mode surface. |
[data-citry-ui-part="preview-value"] | Preview span | Committed or placeholder text. |
[data-citry-ui-part="edit-action"] | Button | Enters edit mode. |
[data-citry-ui-part="edit-surface"] | Div | Input and edit action layout. |
[data-citry-ui-part="input"] | Native Input | Draft focus form and validity owner. |
[data-citry-ui-part="actions"] | Span | Confirm and cancel layout. |
[data-citry-ui-part="submit-action"] | Button | Commits the draft. |
[data-citry-ui-part="cancel-action"] | Button | Discards the draft. |
Interfaces
Aliases and data shapes referenced above.
Input type aliases
| Interface | Definition |
|---|---|
CEditableActionPosition | Literal["inside", "outside"] |
CEditableSubmitMode | Literal["enter", "blur", "both", "explicit"] |
CEditableVariant | Literal["outline", "filled", "plain"] |
CEditableSize | Literal["sm", "md", "lg"] |
CEditableValueSource | Literal["submit", "blur", "reset"] |
CEditableEditReason | Literal["edit", "submit", "cancel", "blur", "reset", "disabled", "readonly", "invalid"] |
CEditableValueChangeDetail
| Field | Type | Default | Meaning |
|---|---|---|---|
value | string | - | Requested value. |
previousValue | string | - | Previous committed value. |
controlled | bool | - | Whether client value owns the channel. |
source | CEditableValueSource | - | Commit source. |
sourceEvent | Event | None | - | Native source event when present. |
CEditableEditChangeDetail
| Field | Type | Default | Meaning |
|---|---|---|---|
editing | bool | - | Requested or forced mode. |
reason | CEditableEditReason | - | Mode reason. |
controlled | bool | - | Whether client editing owns the channel. |
forced | bool | - | Whether safety made closure nonrejectable. |
source | EventTarget | None | - | Native source or safety owner. |
Translation keys
Catalog keys used by this family. An explicit component input or slot listed in Override takes precedence over the catalog for that instance.
CEditable translation keys
| Key | Purpose | Variables | Override | Browser updates |
|---|---|---|---|---|
citry-ui-editable-click-to-edit | Supplies empty preview text and the editor placeholder. | None | placeholder input | i18n.bind() updates every stateful destination. |
citry-ui-editable-edit | Names the edit control. | None | edit_label input | $c-tr updates aria-label. |
citry-ui-editable-save | Names the save control. | None | submit_label input | $c-tr updates aria-label. |
citry-ui-editable-cancel | Names the cancel control. | None | cancel_label input | $c-tr updates aria-label. |