Focusable
A focus ring clearly indicates which item has keyboard focus.Installation
| Install | yarn add @atlaskit/primitives |
|---|---|
| Source | Bitbucket.org, (opens new window) |
| npm | @atlaskit/primitives, (opens new window) |
| Bundle | unpkg.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>
);
};