---
title: Clickable
description: A wrapper component that makes non-button elements keyboard accessible and clickable with proper ARIA attributes
---

```tsx
'use client';

import { Clickable } from '@/ui/Clickable';

export function ClickableDemo() {
  return (
    <Clickable
      onClick={() => alert('Clicked!')}
      className="rounded-lg border-2 border-dashed border-gray-300 p-6 text-center hover:border-gray-400 hover:bg-gray-50"
    >
      Click me or press Enter/Space
    </Clickable>
  );
}
```

## Installation

Using the CLI:

```bash
npx shadcn@latest add https://develop.trident-ui.pro.clubmed/r/clickable.json
```

Or manually, copy the following code into `/ui/clickable.tsx`:

```tsx
'use client';
import { type ComponentPropsWithoutRef, forwardRef, type KeyboardEvent } from 'react';
import { CODE, KEY } from './hooks/keyboard.constants';

export interface ClickableProps extends ComponentPropsWithoutRef<'div'> {
  onClick: () => void;
}

export const Clickable = forwardRef<HTMLDivElement, ClickableProps>(function Clickable(
  { children, onClick, ...attrs },
  ref,
) {
  const handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {
    if (
      e.key === KEY.ENTER ||
      e.key === KEY.SPACE ||
      e.code === CODE.ENTER ||
      e.code === CODE.SPACE
    ) {
      onClick();
    }
  };

  return (
    <div
      {...attrs}
      data-name="Clickable"
      onClick={onClick}
      onKeyDown={handleKeyDown}
      ref={ref}
      role="button"
      tabIndex={0}
    >
      {children}
    </div>
  );
});
```

## Usage

```tsx showLineNumbers
import { Clickable } from '@/docs/lib/ui/clickable';

export function Component() {
  const handleClick = () => {
    console.log('Clicked!');
  };

  return (
    <Clickable onClick={handleClick} className="rounded-lg p-4 hover:bg-gray-100">
      Click me or press Enter/Space
    </Clickable>
  );
}
```

## API Reference

### Clickable

| Prop        | Type         | Default     | Description                                                                                       |
| ----------- | ------------ | ----------- | ------------------------------------------------------------------------------------------------- |
| `onClick`   | `() => void` | `undefined` | **Required**. Callback function to execute when the element is clicked or activated via keyboard. |
| `children`  | `ReactNode`  | `undefined` | The content to render inside the clickable area.                                                  |
| `className` | `string`     | `undefined` | Additional CSS classes to apply to the clickable div.                                             |

The component also accepts all standard HTML `div` element attributes via `ComponentPropsWithoutRef<"div">`.

## Notes

- **Accessibility**: The component automatically sets `role="button"` and `tabIndex={0}` to make the div keyboard accessible and screen-reader friendly.
- **Keyboard Support**: Responds to both `Enter` and `Space` keys, matching native button behavior.
- **Click Handler**: The `onClick` callback is triggered by mouse clicks, touch events, and keyboard activation (Enter/Space keys).
- **Forwarded Ref**: Supports React ref forwarding, allowing parent components to access the underlying div element.
- **Use Case**: Ideal for making custom clickable areas, cards, or complex interactive elements that aren't semantic buttons but need button-like behavior.
- **Semantic HTML**: When possible, prefer using semantic `<button>` elements. Use Clickable when you need clickable behavior on a container with complex children or layout requirements that are difficult to achieve with a button element.
