Button

A focusable button component optimized for TV remote control navigation with spatial focus support.

Import

import { Button } from '@smart-tv/ui';

Basic Usage

The Button component requires a unique focusKey for navigation.

<Button
focusKey="my-button"
onEnterPress={() => console.log('Button pressed')}
>
Click Me
</Button>

With Custom Styling

Apply custom styles when focused using the active prop.

<Button
focusKey="styled-button"
className="px-6 py-3 bg-blue-500 text-white rounded-lg"
active="scale-110 bg-blue-600 shadow-xl"
onEnterPress={() => alert('Clicked!')}
>
Styled Button
</Button>

Disabled State

<Button
focusKey="disabled-button"
disabled={true}
className="opacity-50 cursor-not-allowed"
>
Disabled Button
</Button>

Force Focus

Programmatically focus a button using the forceFocus prop.

import { useState } from 'react';
function App() {
const [focus, setFocus] = useState(false);
return (
<>
<Button
focusKey="force-button"
forceFocus={focus}
onEnterPress={() => console.log('Focused button clicked')}
>
Force Focus Me
</Button>
<Button
focusKey="trigger"
onEnterPress={() => setFocus(true)}
>
Focus Above Button
</Button>
</>
);
}

Render Props Pattern

Use render props to dynamically render button content based on focus state.

<Button
focusKey="render-button"
onEnterPress={() => console.log('Clicked')}
>
{({ focused, focusSelf }) => (
<div className={`flex items-center gap-2 ${focused ? 'text-blue-500' : ''}`}>
{focused && <span>ā–¶</span>}
<span>Play</span>
</div>
)}
</Button>

Event Handlers

<Button
focusKey="event-button"
onEnterPress={(props, details) => {
console.log('Button pressed', props, details);
}}
onEnterRelease={(props, details) => {
console.log('Button released');
}}
onFocus={(layout, props, details) => {
console.log('Button focused');
}}
onBlur={(layout, props, details) => {
console.log('Button blurred');
}}
onArrowPress={(direction, props, details) => {
console.log('Arrow pressed:', direction);
return false; // Prevent navigation
}}
>
Event Button
</Button>

With Payload Data

Pass additional data to event handlers using the payload prop.

const videoData = { id: 123, title: 'Movie Title' };
<Button
focusKey="play-button"
payload={videoData}
onEnterPress={(props) => {
console.log('Play video:', props.payload);
// Access: props.payload.id, props.payload.title
}}
>
Play Video
</Button>

Mouse Hover Support

Enable mouse hover for hybrid TV/web applications.

<Button
focusKey="hover-button"
hover={true}
className="px-4 py-2 bg-gray-200"
active="bg-blue-500 text-white"
onEnterPress={() => console.log('Clicked')}
>
Hover-enabled Button
</Button>

Button Group

import { Row, Button } from '@smart-tv/ui';
<Row focusKey="button-group" className="flex gap-4">
<Button focusKey="btn-1" onEnterPress={() => console.log('Button 1')}>
Option 1
</Button>
<Button focusKey="btn-2" onEnterPress={() => console.log('Button 2')}>
Option 2
</Button>
<Button focusKey="btn-3" onEnterPress={() => console.log('Button 3')}>
Option 3
</Button>
</Row>

Props

PropTypeDefaultDescription
focusKeystringrequiredUnique identifier for spatial navigation
childrenReactNode | RenderFunction-Button content or render function
onEnterPress(props, details) => void-Called when Enter/OK is pressed
onEnterRelease(props, details) => void-Called when Enter/OK is released
onFocus(layout, props, details) => void-Called when button receives focus
onBlur(layout, props, details) => void-Called when button loses focus
onArrowPress(direction, props, details) => boolean-Called on arrow key press
classNamestring-CSS classes for the button
activestring-CSS classes when focused
disabledbooleanfalseDisable button interactions
forceFocusbooleanfalseProgrammatically focus button
hoverbooleanfalseEnable mouse hover support
payloadany-Data passed to event handlers
styleCSSProperties-Inline styles

Best Practices

  • Always provide a unique focusKey for each button
  • Use clear, action-oriented button labels
  • Provide strong visual feedback with the active prop when focused
  • Make buttons large enough for easy selection (min 48px height recommended)
  • Use payload to pass additional context to event handlers
  • Consider using render props for dynamic content based on focus state