Scrollable Content
Usage
Wraps overflowing content with gradient indicators that appear when there is more content to scroll.
import { ScrollableContent } from '@jamie/ui/scrollable-content'
const actionItems = [
'Send follow-up email to the client',
'Review the Q3 revenue projections',
'Schedule a call with the legal team',
'Update the investor deck with new metrics',
'Prepare the board meeting agenda',
'Share the updated financial model',
'Book travel for the NYC conference',
'Draft the partnership proposal',
'Review and approve the new hire offer',
'Submit the expense report for October'
]
export function ScrollableContentDemo() {
return (
<div className="relative h-[200px] w-80 rounded-md border">
<ScrollableContent className="h-full p-4">
<h4 className="mb-3 text-sm font-medium">Action Items</h4>
<ul className="space-y-2">
{actionItems.map((item, index) => (
<li key={item} className="text-sm text-muted-foreground">
{index + 1}. {item}
</li>
))}
</ul>
</ScrollableContent>
</div>
)
}Compound API
Use the compound API for full control over the scroll viewport and indicator placement.
import { ScrollableContent } from '@jamie/ui/scrollable-content'
const transcriptSnippets = [
{ speaker: 'Sarah', text: 'Let me walk you through the quarterly results.' },
{ speaker: 'Michael', text: 'Revenue is up 12% compared to last quarter.' },
{ speaker: 'Sarah', text: 'That tracks with the forecast we shared in January.' },
{ speaker: 'David', text: 'What about the APAC region specifically?' },
{ speaker: 'Michael', text: 'APAC grew 18%, driven by the new enterprise deals.' },
{ speaker: 'Sarah', text: 'We closed three major accounts in Singapore.' },
{ speaker: 'David', text: 'Impressive. And the churn rate?' },
{ speaker: 'Michael', text: 'Down to 2.1% from 3.4% last quarter.' },
{ speaker: 'Sarah', text: 'The retention initiatives are clearly working.' },
{ speaker: 'David', text: 'Let us discuss the roadmap for next quarter.' }
]
export function ScrollableContentCompoundDemo() {
return (
<div className="relative h-[200px] w-80 rounded-md border">
<ScrollableContent.Root>
<ScrollableContent.TopIndicator />
<ScrollableContent.Viewport className="h-[200px] p-4">
<h4 className="mb-3 text-sm font-medium">Transcript</h4>
<div className="space-y-3">
{transcriptSnippets.map((snippet, index) => (
<div key={`${snippet.speaker}-${index}`}>
<span className="text-sm font-medium">{snippet.speaker}: </span>
<span className="text-sm text-muted-foreground">{snippet.text}</span>
</div>
))}
</div>
</ScrollableContent.Viewport>
<ScrollableContent.BottomIndicator />
</ScrollableContent.Root>
</div>
)
}