Focusable

A focus ring clearly indicates which item has keyboard focus.

Installation

Package installation information
Installyarn add @atlaskit/primitives
SourceBitbucket.org, (opens new window)
npm@atlaskit/primitives, (opens new window)
Bundleunpkg.com, (opens new window)

Default

A focus ring indicates the currently focused item. The default focus ring shows a line around the outside of the focused item.

Focusable Card

This is a custom card component that's focusable and clickable.

import type { JSX } from 'react'; import { cssMap, jsx } from '@atlaskit/css'; import { Focusable } from '@atlaskit/primitives/compiled/focusable'; import { token } from '@atlaskit/tokens'; const styles = cssMap({ container: { paddingBlockStart: token('space.100'), paddingInlineEnd: token('space.100'), paddingBlockEnd: token('space.100'), paddingInlineStart: token('space.100'), }, card: { paddingBlockStart: token('space.200'), paddingInlineEnd: token('space.200'), paddingBlockEnd: token('space.200'), paddingInlineStart: token('space.200'), borderRadius: token('radius.small'), backgroundColor: token('elevation.surface'), boxShadow: token('elevation.shadow.overlay'), cursor: 'pointer', }, }); export default (): JSX.Element => { return ( <div css={styles.container}> <Focusable as="div" xcss={styles.card} tabIndex={0} role="button" aria-pressed="false" onClick={() => console.log('Card clicked!')} onKeyDown={(e: React.KeyboardEvent<HTMLDivElement>) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); console.log('Card clicked!'); } }} > <h3>Focusable Card</h3> <p>This is a custom card component that's focusable and clickable.</p> </Focusable> </div> ); };

Inset line

You can toggle the focus ring to show inside the focused item. This is for cases when an inset line is more visible than the default line or to avoid overlapping other UI.

import type { JSX } from 'react'; import { cssMap, jsx } from '@atlaskit/css'; import { Focusable } from '@atlaskit/primitives/compiled/focusable'; import { token } from '@atlaskit/tokens'; const styles = cssMap({ container: { paddingBlockStart: token('space.100'), paddingInlineEnd: token('space.100'), paddingBlockEnd: token('space.100'), paddingInlineStart: token('space.100'), }, textfield: { display: 'block', paddingBlockStart: token('space.100'), paddingInlineEnd: token('space.100'), paddingBlockEnd: token('space.100'), paddingInlineStart: token('space.100'), border: 'none', borderRadius: token('radius.small'), marginBlock: token('space.150'), marginInline: 0, cursor: 'pointer', borderWidth: token('border.width.selected'), borderStyle: 'solid', borderColor: token('color.border'), }, }); export default (): JSX.Element => { return ( <div css={styles.container}> <Focusable as="input" isInset testId="input" xcss={styles.textfield} placeholder="Native Textfield (Inset)" /> </div> ); };
Was this page helpful?
We use this feedback to improve our documentation.
© 2026 AtlassianTrademark, (opens new window)Privacy, (opens new window)License