Skip to main content

ActionConfirm

A floating action confirmation bar component at the bottom, used to confirm or cancel operations.

When to Use

  • Need user confirmation for form submission or modification operations
  • Confirmation needed after batch operations
  • Need to display fixed action buttons at the bottom of the page
  • Save/Cancel operations in edit scenarios

Examples

Basic Usage

ActionConfirm needs to be placed in a relatively positioned container, and it will be fixed at the bottom of the container.

Live Editor
function Demo() {
  const [visible, setVisible] = React.useState(true);

  return (
    <div style={{ position: 'relative', height: '200px', border: '1px solid #d8dee5', borderRadius: '4px', overflow: 'hidden' }}>
      <div style={{ padding: '20px' }}>
        <Button onClick={() => setVisible(!visible)}>
          {visible ? 'Hide Confirm Bar' : 'Show Confirm Bar'}
        </Button>
      </div>
      <ActionConfirm
        visible={visible}
        onOk={() => alert('Confirmed')}
        onCancel={() => setVisible(false)}
      />
    </div>
  );
}
Result
Loading...

Loading State

Display the loading state of the confirm button through the confirmLoading property, commonly used for asynchronous operations.

Live Editor
function Demo() {
  const [visible, setVisible] = React.useState(true);
  const [loading, setLoading] = React.useState(false);

  const handleOk = () => {
    setLoading(true);
    setTimeout(() => {
      setLoading(false);
      setVisible(false);
    }, 2000);
  };

  return (
    <div style={{ position: 'relative', height: '200px', border: '1px solid #d8dee5', borderRadius: '4px', overflow: 'hidden' }}>
      <div style={{ padding: '20px' }}>
        <Button onClick={() => setVisible(true)}>Show Confirm Bar</Button>
        <p style={{ marginTop: '12px', color: '#79879c', fontSize: '14px' }}>
          Loading state will be displayed after clicking the confirm button
        </p>
      </div>
      <ActionConfirm
        visible={visible}
        confirmLoading={loading}
        onOk={handleOk}
        onCancel={() => setVisible(false)}
      />
    </div>
  );
}
Result
Loading...

Custom Button Text

Customize button display content through okText and cancelText properties.

Live Editor
function Demo() {
  const [visible, setVisible] = React.useState(true);

  return (
    <div style={{ position: 'relative', height: '200px', border: '1px solid #d8dee5', borderRadius: '4px', overflow: 'hidden' }}>
      <div style={{ padding: '20px' }}>
        <Button onClick={() => setVisible(true)}>Show Confirm Bar</Button>
      </div>
      <ActionConfirm
        visible={visible}
        okText="Save"
        cancelText="Cancel"
        onOk={() => {
          alert('Saved');
          setVisible(false);
        }}
        onCancel={() => setVisible(false)}
      />
    </div>
  );
}
Result
Loading...

Form Edit Scenario

Typical usage for displaying action confirmation bar when editing forms.

Live Editor
function Demo() {
  const [visible, setVisible] = React.useState(false);
  const [loading, setLoading] = React.useState(false);
  const [name, setName] = React.useState('nginx-deployment');

  const handleChange = (e) => {
    setName(e.target.value);
    setVisible(true);
  };

  const handleSave = () => {
    setLoading(true);
    setTimeout(() => {
      setLoading(false);
      setVisible(false);
      alert(`Saved: ${name}`);
    }, 1000);
  };

  const handleCancel = () => {
    setName('nginx-deployment');
    setVisible(false);
  };

  return (
    <div style={{ position: 'relative', height: '250px', border: '1px solid #d8dee5', borderRadius: '4px', overflow: 'hidden' }}>
      <div style={{ padding: '20px' }}>
        <div style={{ marginBottom: '12px', fontWeight: 600 }}>Edit Workload</div>
        <Input
          value={name}
          onChange={handleChange}
          placeholder="Enter name"
          style={{ width: '300px' }}
        />
        <p style={{ marginTop: '12px', color: '#79879c', fontSize: '14px' }}>
          Confirmation bar will appear after modifying the input
        </p>
      </div>
      <ActionConfirm
        visible={visible}
        confirmLoading={loading}
        okText="Save"
        cancelText="Cancel"
        onOk={handleSave}
        onCancel={handleCancel}
      />
    </div>
  );
}
Result
Loading...

With Card Component

Using action confirmation bar within a card component.

Live Editor
function Demo() {
  const [visible, setVisible] = React.useState(false);
  const [loading, setLoading] = React.useState(false);

  const handleSave = () => {
    setLoading(true);
    setTimeout(() => {
      setLoading(false);
      setVisible(false);
    }, 1000);
  };

  return (
    <div style={{ backgroundColor: '#eff4f9', padding: '20px' }}>
      <Card style={{ position: 'relative', height: '280px', overflow: 'hidden' }}>
        <div style={{ marginBottom: '16px', fontWeight: 600 }}>Resource Configuration</div>
        <Group direction="column" spacing="md">
          <Input placeholder="Name" style={{ width: '300px' }} onChange={() => setVisible(true)} />
          <Input placeholder="Description" style={{ width: '300px' }} onChange={() => setVisible(true)} />
        </Group>
        <ActionConfirm
          visible={visible}
          confirmLoading={loading}
          okText="Save"
          cancelText="Cancel"
          onOk={handleSave}
          onCancel={() => setVisible(false)}
        />
      </Card>
    </div>
  );
}
Result
Loading...

Delete Confirmation

Used for confirmation scenarios of dangerous operations.

Live Editor
function Demo() {
  const [visible, setVisible] = React.useState(false);
  const [loading, setLoading] = React.useState(false);

  const handleDelete = () => {
    setLoading(true);
    setTimeout(() => {
      setLoading(false);
      setVisible(false);
      alert('Deleted');
    }, 1000);
  };

  return (
    <div style={{ position: 'relative', height: '200px', border: '1px solid #d8dee5', borderRadius: '4px', overflow: 'hidden' }}>
      <div style={{ padding: '20px' }}>
        <Button color="error" onClick={() => setVisible(true)}>
          Delete Resource
        </Button>
        <p style={{ marginTop: '12px', color: '#79879c', fontSize: '14px' }}>
          Confirmation bar will be displayed after clicking the delete button
        </p>
      </div>
      <ActionConfirm
        visible={visible}
        confirmLoading={loading}
        okText="Confirm Delete"
        cancelText="Cancel"
        onOk={handleDelete}
        onCancel={() => setVisible(false)}
      />
    </div>
  );
}
Result
Loading...

API

ActionConfirm

PropertyDescriptionTypeDefault
visibleWhether to display the confirm barbooleanRequired
okTextConfirm button textReactNode<Check variant="light" />
cancelTextCancel button textReactNode<Close variant="light" />
confirmLoadingWhether the confirm button shows loading statebooleanfalse
onOkCallback when clicking the confirm button() => void-
onCancelCallback when clicking the cancel button() => void-
classNameCustom class namestring-
styleCustom stylesCSSProperties-
info

About Positioning:

  • ActionConfirm uses position: absolute positioning and needs to be placed in a position: relative container
  • The component will be fixed at the bottom of the container, achieving full-width layout through bottom: 0; left: 0; right: 0;
  • The spacing from the container edge is 12px (set through margin: 12px)
  • The container needs to set overflow: hidden to ensure animation effects work properly
  • z-index is 999, ensuring it appears above other elements

About Animation:

  • The component has smooth transition animations when showing/hiding (transition: all 0.3s)
  • Hidden state effect (ActionConfirm.tsx lines 21-25):
    visibility: hidden;
    opacity: 0;
    transform: translateY(48px); // Slides down 48px
  • Visible state effect (ActionConfirm.tsx lines 13-18):
    visibility: visible;
    opacity: 1;
    transform: translate(0); // Returns to original position

About Button Styles:

  • Buttons use dark background (theme.palette.accents_8), white text (theme.palette.background)
  • On hover, background becomes accents_7 (slightly lighter)
  • Button padding: padding: 10px 20px
  • Button right margin: margin-right: 12px
  • Button alignment: justify-content: right

About Loading State:

  • When confirmLoading is true, the confirm button displays a Loading component (size: 14px)
  • Loading state styles (ActionConfirm.tsx lines 61-66):
    background-color: accents_7;  // Background becomes lighter
    cursor: not-allowed; // Disabled cursor
  • Clicking the confirm button in loading state does not trigger the onOk callback (line 96 checks !confirmLoading)
  • Suitable for scenarios requiring asynchronous processing

About Icons:

  • Default confirm button uses <Check variant="light" /> icon (light variant)
  • Default cancel button uses <Close variant="light" /> icon (light variant)
  • Can be customized to text or other content through okText and cancelText
  • Icons are from the @kubed/icons package

About Click Handling:

  • onCancel click handling: directly calls the passed callback function (lines 89-93)
  • onOk click handling: only calls the callback when !confirmLoading (lines 95-99)
  • This ensures no repeated submissions during loading state

Usage Recommendations

Container Setup

Ensure the parent container has proper positioning and overflow properties:

// Correct: Set relative positioning and hide overflow
<div style={{ position: 'relative', overflow: 'hidden', height: '300px' }}>
<ActionConfirm visible={visible} />
</div>

// Incorrect: No positioning set
<div>
<ActionConfirm visible={visible} />
</div>

Form Scenario

Display confirmation bar when form is modified:

const [hasChanges, setHasChanges] = React.useState(false);

const handleFieldChange = () => {
setHasChanges(true);
};

const handleSave = async () => {
await saveForm();
setHasChanges(false);
};

const handleCancel = () => {
resetForm();
setHasChanges(false);
};

<ActionConfirm
visible={hasChanges}
okText="Save"
cancelText="Cancel"
onOk={handleSave}
onCancel={handleCancel}
/>

Asynchronous Operations

Handle asynchronous save operations:

const [loading, setLoading] = React.useState(false);

const handleOk = async () => {
setLoading(true);
try {
await saveData();
setVisible(false);
} catch (error) {
console.error(error);
} finally {
setLoading(false);
}
};

<ActionConfirm
visible={visible}
confirmLoading={loading}
onOk={handleOk}
onCancel={() => setVisible(false)}
/>

With Modal Component

Using confirmation bar inside a Modal:

<Modal visible={modalVisible} onCancel={() => setModalVisible(false)}>
<div style={{ position: 'relative', minHeight: '200px' }}>
<Form>{/* Form content */}</Form>
<ActionConfirm
visible={hasChanges}
okText="Save"
cancelText="Cancel"
onOk={handleSave}
onCancel={handleCancel}
/>
</div>
</Modal>

Custom Button Content

Buttons support any ReactNode:

// Using text
<ActionConfirm
okText="Confirm Submit"
cancelText="Discard Changes"
/>

// Using icons and text
<ActionConfirm
okText={
<Group spacing="xs">
<Check size={14} />
<span>Save</span>
</Group>
}
cancelText={
<Group spacing="xs">
<Close size={14} />
<span>Cancel</span>
</Group>
}
/>