ActionButton
Small tinted button for a secondary action, optionally rendered as another element. It is the "clear filter" of a toolbar: accent text on a quiet background, no border.
Use this when / not when
- Use for a secondary action next to content — clearing a filter, adding one more row, toggling a panel.
- Not for the primary action of a screen or a dialog;
Buttonhas the sizes, the primary look andisLoading. - Not for an icon on its own —
IconButtonis that, though it is not keyboard-operable, and this one is. - Not for navigation between pages unless you also pass
as="a", in which caseLinkmay be the better fit.
Import
import { ActionButton } from "@onlyoffice/apps-ui-kit/components/action-button";
Also exported from the root barrel @onlyoffice/apps-ui-kit.
Needs ThemeProvider from @onlyoffice/apps-ui-kit/providers/theme for the accent text colour
and the hover background.
Stories
Default
The plain text button for a secondary action; click it to see onClick in the Actions panel, and change any other prop live in the Controls panel below.
With Icon
An icon before the label makes the action easier to spot in a busy toolbar; the icon takes the text colour (icon).
As Link
The same look for an action that navigates: the button becomes a link and takes href (as).
Disabled State
An action that is not available yet stays in place but fades and ignores clicks (disabled); it works only on the default button.
Minimal example
import { ActionButton } from "@onlyoffice/apps-ui-kit/components/action-button";
export function ClearFilter({ onClear }: { onClear: () => void }) {
return <ActionButton label="Clear filter" onClick={onClear} />;
}
Props
Everything else you pass is forwarded to the rendered element, so a <button> takes
disabled, type and onClick, and as="a" takes href and target.
Recipes
With an icon
icon takes a node, not a name. It is drawn at 12×12 before the label and its paths are filled
with the button's own colour, so an SVG whose path has no hardcoded fill follows the theme.
import { ActionButton } from "@onlyoffice/apps-ui-kit/components/action-button";
export function AddRow({ onAdd }: { onAdd: () => void }) {
return (
<ActionButton
label="Add row"
onClick={onAdd}
icon={
<svg viewBox="0 0 12 12" aria-hidden="true">
<path d="M6 1v10M1 6h10" stroke="currentColor" strokeWidth="1.5" />
</svg>
}
/>
);
}
As a link
as swaps the element, and the props of that element are then accepted and type-checked.
import { ActionButton } from "@onlyoffice/apps-ui-kit/components/action-button";
export function DocsLink() {
return (
<ActionButton
as="a"
href="https://helpcenter.onlyoffice.com"
target="_blank"
rel="noreferrer"
label="Open the help centre"
/>
);
}
Disabled / read-only
There is no isDisabled prop: as a <button> it takes the DOM's own disabled, which the
stylesheet fades to half opacity.
import { ActionButton } from "@onlyoffice/apps-ui-kit/components/action-button";
export function SaveAction({ dirty }: { dirty: boolean }) {
return <ActionButton label="Save changes" disabled={!dirty} />;
}
Note that disabled only exists on a <button>. Under as="a" nothing stops the click, and
the style does not change either.
Behaviour the types don't state
- This is a real
<button>. Unlike most of this kit it is focusable, activated by Enter and Space, and takesdisabled— there is nothing to add for keyboard support. typedefaults tosubmit, as it does for any<button>. Inside a form, passtype="button"unless submitting is what you want.labelis what is rendered, notchildren. The component destructureslabeland does not renderchildrenat all, so a node passed as a child disappears.- The component brings no width and no margin. It is
inline-flexwith6px 10pxof padding and an8pxgap, so a row of them needs its own gap. - Hover and press change only the background. It darkens on hover — on devices that
have hover, so not after a tap on a touch screen — and again while pressed; the text colour
stays. Under
disabledthe button also shows a not-allowed cursor. - The dark colours come from a
.darkancestor, the classThemeProviderputs on<body>for the dark theme. Outside one the button keeps its light colours whatever the page looks like. refreaches the rendered element, whicheverasselects.- The label does not wrap or truncate. A long label stretches the button until its parent clips it.
asaccepts a component as well as a tag name, and the props of whatever you pass are checked against it —as={Link}from a router works, andtois then required.- The component emits no
data-testid. Query it by its role and name, or pass anid.
CSS variables
The colours are theme tokens defined on the component's own class rather than public knobs;
there is no --action-button-* variable to set from outside. To restyle one, pass a
className — it is applied after the component's own class.
Accessibility
- The default element is a
<button>, so the role, the focus ring, Enter/Space anddisabledall come from the platform. labelis the accessible name. A button with only aniconand nolabelhas no name at all — passaria-labelin that case, or useButton.- The icon is not hidden from assistive technology. If it carries no meaning of its own, mark
the SVG
aria-hidden. as="a"produces a link, which is announced as a link and activated by Enter only. Do not use it for something that is not navigation.
Test ids
The component sets none. Pass data-testid yourself — it is forwarded to the rendered element
like any other unknown prop.
Related
Button— the full-size button, with sizes, the primary look and a loader.IconButton— an icon on its own, without the label or the background.Link— text that navigates.