Washed Huila opens with red apple and panela, then settles into a finish that stays long and sweet well after the cup cools. Select any words to ask about them.
'use client';
import { useState } from 'react';
import { SelectionActions, StreamingText } from '@brand-studio/ui';
const replies: Record<string, (text: string) => string> = {
explain: text => `“${text}” means the flavour the coffee leaves after you swallow, and how long it lasts.`,
shorten: () => 'A long, sweet finish.',
translate: () => 'Un final largo y dulce.',
};
export default function SelectionActionsDemo() {
const [reply, setReply] = useState<string>();
return (
<div style={{ width: '100%', maxWidth: 560, display: 'grid', gap: 20 }}>
<SelectionActions
actions={[{ id: 'explain', label: 'Explain' }, { id: 'shorten', label: 'Shorten' }, { id: 'translate', label: 'Translate' }]}
onAction={(id, text) => setReply(replies[id](text))}
>
<p style={{ margin: 0, fontSize: 18, lineHeight: 1.6 }}>
Washed Huila opens with red apple and panela, then settles into a finish that stays long and sweet well after the cup cools. Select any words to ask about them.
</p>
</SelectionActions>
<div style={{ minHeight: 48, color: 'var(--bs-muted)' }}>{reply ? <StreamingText key={reply} text={reply} /> : null}</div>
</div>
);
}Installation
pnpm add @brand-studio/uinpm install @brand-studio/uiyarn add @brand-studio/uibun add @brand-studio/uiInstall the peer dependencies
npm install react react-domImport the stylesheet once
import '@brand-studio/ui/styles.css';Wrap your app in a brand theme
import { BrandTheme, SelectionActions } from '@brand-studio/ui'; import brand from './brand.json'; <BrandTheme palette={brand.tokens} mode="system"> {/* your app */} </BrandTheme>
Usage
import { SelectionActions } from '@brand-studio/ui';<SelectionActions actions={[{ id: 'explain', label: 'Explain' }, { id: 'shorten', label: 'Shorten' }]} onAction={(id, text) => ask(id, text)}>
<p>Washed Huila opens with red apple and panela…</p>
</SelectionActions>Select part of the wrapped text with the mouse, touch or Shift and the arrow keys, and a bar appears under the selection. Choosing an action calls onAction with its id and the selected text, then clears the selection. What happens next is up to you: answer beside it, or replace the text.
Accessibility
- The bar is a toolbar that comes after the text in reading order, so Tab reaches it after a keyboard selection. Arrow keys move along it.
- Escape dismisses the bar and clears the selection.
API Reference
| Prop | Type | Default |
|---|---|---|
actions | SelectionAction[] | – |
onAction? | ((id: string, text: string) => void) | – |
children | React.ReactNode | – |
label? | string | 'Selection actions' |
className? | string | '' |