Skip to content

EditableActions

Reusable save/cancel action buttons for inline editing workflows.

Import

tsx
import { EditableActions } from '@/shared/ui/components/editable/EditableActions'

Props

EditableActionsProps

PropTypeDefaultDescription
onSave() => voidRequiredCallback when save button is clicked
onCancel() => voidRequiredCallback when cancel button is clicked
isSavingbooleanfalseWhether save operation is in progress
disabledbooleanfalseWhether actions are disabled
size'default' | 'sm' | 'icon''default'Button size variant
classNamestring-Additional CSS classes for container

Features

  • Consistent icons - Check (✓) for save, X for cancel
  • Loading state - Disables buttons during save
  • Size variants - Default, small, and icon-only sizes
  • Disabled state - Visual feedback when actions unavailable
  • Destructive styling - Cancel button uses destructive color

Examples

Basic Usage

tsx
<EditableActions
  onSave={handleSave}
  onCancel={handleCancel}
/>

With Loading State

tsx
<EditableActions
  onSave={handleSave}
  onCancel={handleCancel}
  isSaving={isSaving}
/>

Small Size

tsx
<EditableActions
  onSave={handleSave}
  onCancel={handleCancel}
  size="sm"
/>

Icon Size (Compact)

tsx
<EditableActions
  onSave={handleSave}
  onCancel={handleCancel}
  size="icon"
/>

Disabled State

tsx
<EditableActions
  onSave={handleSave}
  onCancel={handleCancel}
  disabled={!isValid}
/>

With Custom Styling

tsx
<EditableActions
  onSave={handleSave}
  onCancel={handleCancel}
  className="ml-auto"
/>

Size Variants

Default

Standard button size with padding:

tsx
<EditableActions size="default" {...props} />

Small

Reduced padding for compact UIs:

tsx
<EditableActions size="sm" {...props} />

Icon

Icon-only buttons (8x8 size):

tsx
<EditableActions size="icon" {...props} />

Behavior

Save Button

  • Icon: Check (✓)
  • Variant: Outline
  • Disabled when: disabled or isSaving is true
  • Action: Calls onSave

Cancel Button

  • Icon: X
  • Variant: Outline with destructive text color
  • Disabled when: isSaving is true
  • Action: Calls onCancel

Styling

The component renders as a flex container:

tsx
<div className="flex items-center gap-2">
  <Button variant="outline" size={size} onClick={onSave} disabled={disabled || isSaving}>
    <Check className="h-4 w-4" />
  </Button>
  <Button
    variant="outline"
    size={size}
    onClick={onCancel}
    disabled={isSaving}
    className="text-destructive hover:text-destructive"
  >
    <X className="h-4 w-4" />
  </Button>
</div>

Integration Examples

With InlineEditable

tsx
<InlineEditable
  value={value}
  onSave={handleSave}
  renderDisplay={...}
  renderEditor={({ onSave, onCancel, isSaving }) => (
    <div className="flex items-center gap-2">
      <Input {...inputProps} />
      <EditableActions
        onSave={onSave}
        onCancel={onCancel}
        isSaving={isSaving}
      />
    </div>
  )}
/>

With Custom Input

tsx
function CustomEditor({ value, onChange, onSave, onCancel, isSaving }) {
  return (
    <div className="flex flex-col gap-2">
      <Textarea
        value={value}
        onChange={(e) => onChange(e.target.value)}
        rows={4}
      />
      <EditableActions
        onSave={onSave}
        onCancel={onCancel}
        isSaving={isSaving}
        size="sm"
        className="self-end"
      />
    </div>
  )
}

In Table Cell

tsx
<EditableActions
  onSave={onSave}
  onCancel={onCancel}
  size="icon"
  className="ml-2"
/>

Accessibility

  • Keyboard navigation: Tab between buttons
  • Visual feedback: Clear hover and focus states
  • Disabled state: Properly communicated to screen readers
  • Icon labels: Icons are semantic and recognizable

See Also