Action Button
An Action Button is a submit button that shows the progress of an action: waiting, processing, success or error. You set its state from your component while the action runs.
Usage
<div class="d-flex flex-wrap gap-2">
 <ActionButton state="$saveState" (click)="save" />
 <ActionButton state="$publishState" text="Publish" textProcessing="Publishing.." textSuccess="Published"
 textFailed="Could not publish" (click)="publish" />
</div>
<?php

use Viewi\Components\BaseComponent;
use Viewi\Components\Environment\ClientTimer;
use Viewi\UI\Components\Buttons\ActionButton;

class ActionButtonDocsExample extends BaseComponent
{
 public int $saveState = 0;
 public int $publishState = 0;

 public function save()
 {
 $this->saveState = ActionButton::STATE_PROCESSING;
 // pretend to call the server
 ClientTimer::setTimeoutStatic(function () {
 $this->saveState = ActionButton::STATE_SUCCESS;
 ClientTimer::setTimeoutStatic(function () {
 $this->saveState = ActionButton::STATE_PENDING;
 }, 2000);
 }, 1000);
 }

 public function publish()
 {
 $this->publishState = ActionButton::STATE_PROCESSING;
 // pretend the server returned an error
 ClientTimer::setTimeoutStatic(function () {
 $this->publishState = ActionButton::STATE_ERROR;
 ClientTimer::setTimeoutStatic(function () {
 $this->publishState = ActionButton::STATE_PENDING;
 }, 2000);
 }, 1000);
 }
}
In a real component, set the success or error state when your HTTP request finishes, then return to STATE_PENDING after a short delay.
States
Use the constants of ActionButton for the state property:
ActionButton::STATE_PENDING (0) - blue button with text. The button is enabled.
ActionButton::STATE_PROCESSING (1) - blue button with a spinner and textProcessing.
ActionButton::STATE_SUCCESS (2) - green button with a check icon and textSuccess.
ActionButton::STATE_ERROR (3) - red button with textFailed.
The button is disabled in every state except STATE_PENDING, so the user can not start the action twice.
Inside a form
The button has type="submit". Inside an Action Form, a click submits the form, so you can handle the (submit) event of the form instead of (click):
<ActionForm #profileForm (submit)="onSubmit" rules="$validationRules">
 <TextInput label="Name" name="Name" model="$user->Name" />
 <ActionButton state="$state" />
</ActionForm>
public function onSubmit(DomEvent $event)
{
 $event->preventDefault();
 if (!$this->profileForm->validate()) {
 return;
 }
 $this->state = ActionButton::STATE_PROCESSING;
 // send the data, then set STATE_SUCCESS or STATE_ERROR
}
Properties
state - (optional), current state of the button, one of the STATE_* constants. Default: 0 (STATE_PENDING).
text - (optional), text in the pending state. Default: Save.
textProcessing - (optional), text in the processing state. Default: Saving...
textSuccess - (optional), text in the success state. Default: Saved.
textFailed - (optional), text in the error state. Default: Failed.
Events
(click) - event that happens when the user clicks the button. Receives the DOM event.