Skip to main content
The Actionable component is a low-level utility that provides a consistent foundation for interactive elements. It handles the complexity of rendering buttons, links, or custom elements with proper accessibility attributes and focus management.

Basic Usage

import { Actionable } from 'reshaped';

// Renders as button
<Actionable onClick={() => console.log('clicked')}>
  Click me
</Actionable>

// Renders as link
<Actionable href="/about">
  About
</Actionable>

// Renders as span
<Actionable>
  Static content
</Actionable>

With Custom Element

import { Actionable } from 'reshaped';

function Example() {
  return (
    <Actionable 
      as="div"
      onClick={() => {}}
    >
      Custom element
    </Actionable>
  );
}

With Focus Ring

import { Actionable, View } from 'reshaped';

function FocusableCard() {
  return (
    <Actionable 
      insetFocus
      borderRadius="inherit"
      onClick={() => {}}
    >
      <View 
        padding={4}
        borderRadius="large"
        backgroundColor="neutral-faded"
      >
        Focusable card content
      </View>
    </Actionable>
  );
}

Props

onClick
(event: MouseEvent) => void
Click handler - causes component to render as a button
href
string
Link URL - causes component to render as an anchor element
disabled
boolean
Disable the interactive element
touchHitbox
boolean
Enable a minimum required touch hitbox for better mobile accessibility
fullWidth
boolean
Take up the full width of its parent
insetFocus
boolean
Enable a focus ring inside the element bounds
disableFocusRing
boolean
Don’t show a focus ring on focus, can be used when it is within a container with a focus ring
borderRadius
'inherit'
Apply the focus ring to the child and rely on its border radius
as
string
HTML element to render as
render
(props) => ReactElement
Custom render function for complete control over the rendered element
type
'button' | 'submit' | 'reset'
Button type attribute (only applies when rendering as button)
stopPropagation
boolean
Stop event propagation on click
children
React.ReactNode
Content to render inside the actionable element
className
string
Additional classname for the root element
attributes
HTMLAttributes
Additional attributes for the element

When to Use

  • Custom Interactive Components: Building custom buttons, cards, or interactive elements
  • Polymorphic Elements: Need element to render as button, link, or other based on props
  • Focus Management: Require custom focus ring behavior
  • Accessibility: Ensure proper keyboard navigation and screen reader support
  • Touch Targets: Mobile-first designs requiring minimum touch target sizes

Composition Patterns

Interactive Card

import { Actionable, View, Text, Stack } from 'reshaped';

function InteractiveCard({ title, description, onClick }) {
  return (
    <Actionable 
      onClick={onClick}
      insetFocus
      borderRadius="inherit"
    >
      <View 
        padding={4}
        borderRadius="medium"
        backgroundColor="elevated"
        borderColor="neutral-faded"
        borderWidth={1}
      >
        <Stack gap={2}>
          <Text variant="title-5" weight="medium">{title}</Text>
          <Text color="neutral">{description}</Text>
        </Stack>
      </View>
    </Actionable>
  );
}
import { Actionable, Text } from 'reshaped';

function CustomLink({ href, children }) {
  return (
    <Actionable 
      href={href}
      disableFocusRing
    >
      <Text color="primary" weight="medium">
        {children}
      </Text>
    </Actionable>
  );
}

Mobile Touch Target

import { Actionable, Icon } from 'reshaped';

function IconButton({ icon, onClick, label }) {
  return (
    <Actionable 
      onClick={onClick}
      touchHitbox
      attributes={{ 'aria-label': label }}
    >
      <Icon svg={icon} size={5} />
    </Actionable>
  );
}

Disabled State

import { Actionable, View, Text } from 'reshaped';

function DisabledButton({ disabled, onClick, children }) {
  return (
    <Actionable 
      disabled={disabled}
      onClick={onClick}
    >
      <View 
        padding={3}
        backgroundColor={disabled ? 'neutral-faded' : 'primary'}
        borderRadius="medium"
      >
        <Text color={disabled ? 'disabled' : 'white'}>
          {children}
        </Text>
      </View>
    </Actionable>
  );
}

Full Width Action

import { Actionable, View, Text } from 'reshaped';

function FullWidthButton({ children, onClick }) {
  return (
    <Actionable 
      fullWidth
      onClick={onClick}
    >
      <View 
        padding={4}
        backgroundColor="primary"
        borderRadius="medium"
        align="center"
      >
        <Text color="white" weight="medium">{children}</Text>
      </View>
    </Actionable>
  );
}

Custom Render Function

import { Actionable } from 'reshaped';

function CustomActionable() {
  return (
    <Actionable
      onClick={() => {}}
      render={(props) => (
        <article {...props} data-custom="true">
          Custom rendered element
        </article>
      )}
    />
  );
}

Preventing Event Propagation

import { Actionable, View } from 'reshaped';

function NestedAction({ onParentClick, onChildClick }) {
  return (
    <Actionable onClick={onParentClick}>
      <View padding={4}>
        Parent clickable area
        <Actionable 
          stopPropagation
          onClick={onChildClick}
        >
          <View padding={2} backgroundColor="primary">
            Child action (stops propagation)
          </View>
        </Actionable>
      </View>
    </Actionable>
  );
}

Build docs developers (and LLMs) love