Skip to content

Commit 60bba69

Browse files
committed
refactor: ScrollArea component
1 parent 81ddd18 commit 60bba69

43 files changed

Lines changed: 1428 additions & 602 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/showcase/demo/styled/scrollarea/basic-demo.tsx

Lines changed: 68 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,78 @@ import { ScrollArea } from '@primereact/ui/scrollarea';
22

33
export default function BasicDemo() {
44
return (
5-
<div className="flex justify-center">
6-
<ScrollArea.Root className="max-w-sm h-48">
5+
<div className="max-w-56 w-full mx-auto">
6+
<div className="text-surface-500 dark:text-surface-400 font-medium text-sm uppercase font-mono tracking-tight mb-2">Automobiles</div>
7+
<ScrollArea.Root className="h-72">
78
<ScrollArea.Viewport>
8-
<ScrollArea.Content>
9-
<div className="space-y-6 text-sm">
10-
<p>
11-
This panel provides an overview of recent activity associated with your account, including system updates,
12-
configuration changes, and important user actions that may require your attention. It is designed to surface relevant
13-
information in a compact space without overwhelming the main layout or distracting you from your current task.
14-
</p>
15-
16-
<p>
17-
As activity accumulates over time, new entries are continuously added to this section while older records remain
18-
available for review. Scrolling allows you to explore past events at your own pace, making it easier to understand
19-
changes and patterns without navigating away from the current context.
20-
</p>
21-
22-
<p>
23-
Activity data may include security-related events, billing notifications, feature updates, and changes made by team
24-
members across your workspace. Keeping this information in a dedicated scrollable area helps maintain clarity and
25-
focus within the interface while still providing access to detailed historical information.
26-
</p>
27-
28-
<p>
29-
Use this area to monitor recent changes, verify completed actions, and stay informed about updates that may affect
30-
your workflow or account status. For a more comprehensive view, additional filters, search options, or detailed logs
31-
may be available elsewhere in the application.
32-
</p>
33-
</div>
9+
<ScrollArea.Content className="space-y-2">
10+
{automobiles.map((car) => (
11+
<span key={car.label} className="flex items-end gap-0.5">
12+
<a className="text-primary text-sm hover:underline!" href="">
13+
{car.label}
14+
</a>
15+
<span className="text-surface-500 text-[11px] font-mono mb-px tracking-tighter">({car.value})</span>
16+
</span>
17+
))}
3418
</ScrollArea.Content>
3519
</ScrollArea.Viewport>
36-
<ScrollArea.ThumbY />
20+
<ScrollArea.Scrollbar orientation="vertical">
21+
<ScrollArea.Thumb />
22+
</ScrollArea.Scrollbar>
3723
</ScrollArea.Root>
3824
</div>
3925
);
4026
}
27+
28+
const automobiles = [
29+
{ label: 'Audi', value: '200' },
30+
{ label: 'BMW', value: '350' },
31+
{ label: 'Mercedes-Benz', value: '420' },
32+
{ label: 'Volkswagen', value: '510' },
33+
{ label: 'Toyota', value: '610' },
34+
{ label: 'Honda', value: '280' },
35+
{ label: 'Hyundai', value: '390' },
36+
{ label: 'Kia', value: '260' },
37+
{ label: 'Ford', value: '470' },
38+
{ label: 'Renault', value: '530' },
39+
{ label: 'Peugeot', value: '410' },
40+
{ label: 'Citroen', value: '190' },
41+
{ label: 'Skoda', value: '360' },
42+
{ label: 'Seat', value: '210' },
43+
{ label: 'Opel', value: '440' },
44+
{ label: 'Fiat', value: '620' },
45+
{ label: 'Dacia', value: '380' },
46+
{ label: 'Volvo', value: '140' },
47+
{ label: 'Mazda', value: '120' },
48+
{ label: 'Mitsubishi', value: '110' },
49+
{ label: 'Nissan', value: '330' },
50+
{ label: 'Subaru', value: '60' },
51+
{ label: 'Suzuki', value: '170' },
52+
{ label: 'Jeep', value: '95' },
53+
{ label: 'Land Rover', value: '80' },
54+
{ label: 'Porsche', value: '75' },
55+
{ label: 'Ferrari', value: '12' },
56+
{ label: 'Lamborghini', value: '9' },
57+
{ label: 'Bentley', value: '15' },
58+
{ label: 'Rolls-Royce', value: '6' },
59+
{ label: 'Mini', value: '130' },
60+
{ label: 'Tesla', value: '220' },
61+
{ label: 'BYD', value: '55' },
62+
{ label: 'Chery', value: '160' },
63+
{ label: 'MG', value: '145' },
64+
{ label: 'DS Automobiles', value: '40' },
65+
{ label: 'Alfa Romeo', value: '50' },
66+
{ label: 'Lancia', value: '8' },
67+
{ label: 'Cadillac', value: '22' },
68+
{ label: 'Chevrolet', value: '105' },
69+
{ label: 'Dodge', value: '18' },
70+
{ label: 'GMC', value: '14' },
71+
{ label: 'Infiniti', value: '11' },
72+
{ label: 'Acura', value: '7' },
73+
{ label: 'Genesis', value: '35' },
74+
{ label: 'Geely', value: '27' },
75+
{ label: 'Proton', value: '19' },
76+
{ label: 'Togg', value: '65' },
77+
{ label: 'Rivian', value: '4' },
78+
{ label: 'Lucid', value: '3' }
79+
];
Lines changed: 77 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,84 @@
11
import { ScrollArea } from '@primereact/ui/scrollarea';
22

3+
const columns = [
4+
{ key: 'city', label: 'City' },
5+
{ key: 'state', label: 'State' },
6+
{ key: 'population', label: 'Population' },
7+
{ key: 'area_km2', label: 'Area (km²)' }
8+
] as const;
9+
310
export default function BothScrollbarsDemo() {
411
return (
5-
<div className="flex justify-center">
6-
<ScrollArea.Root className="h-80 w-80 border border-surface rounded-lg">
7-
<ScrollArea.Viewport className="p-4">
8-
<ScrollArea.Content>
9-
<div className="grid grid-cols-[repeat(10,6rem)] grid-rows-[repeat(10,6rem)] gap-4">
10-
{Array(100)
11-
.fill(null)
12-
.map((_, i) => (
13-
<div key={i} className="size-full bg-surface-100 dark:bg-surface-800 rounded-lg flex items-center justify-center">
14-
<span className="text-sm opacity-75">{i}</span>
15-
</div>
12+
<ScrollArea.Root className="h-80 max-w-sm mx-auto w-full rounded-md overflow-hidden">
13+
<ScrollArea.Viewport className="p-0">
14+
<ScrollArea.Content>
15+
<table className="min-w-xl w-full text-sm border-collapse border-0">
16+
<thead className="sticky top-0 z-10 ">
17+
<tr className="bg-surface-100 dark:bg-surface-800 border-b border-surface">
18+
{columns.map((col) => (
19+
<th
20+
key={col.key}
21+
className="border-b border-surface px-4 py-2 text-left text-sm whitespace-nowrap uppercase font-mono font-light"
22+
>
23+
{col.label}
24+
</th>
1625
))}
17-
</div>
18-
</ScrollArea.Content>
19-
</ScrollArea.Viewport>
20-
<ScrollArea.ThumbY />
21-
<ScrollArea.ThumbX />
22-
</ScrollArea.Root>
23-
</div>
26+
</tr>
27+
</thead>
28+
<tbody>
29+
{usCities.map((city, i) => (
30+
<tr
31+
key={i}
32+
className="last:border-0 border-b border-surface odd:bg-surface-50 dark:odd:bg-surface-900/40 hover:bg-primary/5"
33+
>
34+
<td className=" px-4 py-2 font-medium whitespace-nowrap">{city.city}</td>
35+
<td className=" px-4 py-2 text-surface-500">{city.state}</td>
36+
<td className=" px-4 py-2 tabular-nums">{city.population.toLocaleString()}</td>
37+
<td className=" px-4 py-2 tabular-nums">{city.area_km2.toLocaleString()}</td>
38+
</tr>
39+
))}
40+
</tbody>
41+
</table>
42+
</ScrollArea.Content>
43+
</ScrollArea.Viewport>
44+
45+
<ScrollArea.Scrollbar orientation="vertical" className="m-0 bg-transparent">
46+
<ScrollArea.Thumb />
47+
</ScrollArea.Scrollbar>
48+
49+
<ScrollArea.Scrollbar orientation="horizontal" className="m-0 bg-transparent">
50+
<ScrollArea.Thumb />
51+
</ScrollArea.Scrollbar>
52+
53+
<ScrollArea.Corner />
54+
</ScrollArea.Root>
2455
);
2556
}
57+
58+
const usCities = [
59+
{ city: 'New York', state: 'NY', population: 8419600, area_km2: 783.8 },
60+
{ city: 'Los Angeles', state: 'CA', population: 3980400, area_km2: 1214.9 },
61+
{ city: 'Chicago', state: 'IL', population: 2716000, area_km2: 589.6 },
62+
{ city: 'Houston', state: 'TX', population: 2328000, area_km2: 1651.1 },
63+
{ city: 'Phoenix', state: 'AZ', population: 1690000, area_km2: 1340.6 },
64+
{ city: 'Philadelphia', state: 'PA', population: 1584200, area_km2: 369.6 },
65+
{ city: 'San Antonio', state: 'TX', population: 1547200, area_km2: 1194.0 },
66+
{ city: 'San Diego', state: 'CA', population: 1423800, area_km2: 964.5 },
67+
{ city: 'Dallas', state: 'TX', population: 1341100, area_km2: 882.9 },
68+
{ city: 'San Jose', state: 'CA', population: 1035300, area_km2: 469.7 },
69+
{ city: 'Austin', state: 'TX', population: 1010000, area_km2: 704.0 },
70+
{ city: 'Jacksonville', state: 'FL', population: 949600, area_km2: 2265.3 },
71+
{ city: 'Fort Worth', state: 'TX', population: 918900, area_km2: 920.9 },
72+
{ city: 'Columbus', state: 'OH', population: 905700, area_km2: 577.9 },
73+
{ city: 'Charlotte', state: 'NC', population: 885700, area_km2: 771.0 },
74+
{ city: 'San Francisco', state: 'CA', population: 873900, area_km2: 121.4 },
75+
{ city: 'Indianapolis', state: 'IN', population: 876400, area_km2: 953.0 },
76+
{ city: 'Seattle', state: 'WA', population: 737000, area_km2: 217.0 },
77+
{ city: 'Denver', state: 'CO', population: 715500, area_km2: 401.3 },
78+
{ city: 'Washington', state: 'DC', population: 689500, area_km2: 177.0 },
79+
{ city: 'Boston', state: 'MA', population: 675600, area_km2: 232.1 },
80+
{ city: 'El Paso', state: 'TX', population: 678800, area_km2: 663.7 },
81+
{ city: 'Nashville', state: 'TN', population: 689400, area_km2: 1362.2 },
82+
{ city: 'Detroit', state: 'MI', population: 639100, area_km2: 370.0 },
83+
{ city: 'Oklahoma City', state: 'OK', population: 681100, area_km2: 1608.8 }
84+
];
Lines changed: 69 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,79 @@
11
import { ScrollArea } from '@primereact/ui/scrollarea';
22

3-
export default function BasicDemo() {
3+
export default function CustomDemo() {
44
return (
5-
<div className="flex justify-center">
6-
<ScrollArea.Root className="max-w-sm h-48">
5+
<div className="max-w-56 w-full mx-auto">
6+
<div className="text-surface-500 dark:text-surface-400 font-medium text-sm uppercase font-mono tracking-tight mb-2">Automobiles</div>
7+
<ScrollArea.Root className="h-72">
78
<ScrollArea.Viewport>
8-
<ScrollArea.Content>
9-
<div className="space-y-6 text-sm">
10-
<p>
11-
This panel provides an overview of recent activity associated with your account, including system updates,
12-
configuration changes, and important user actions that may require your attention. It is designed to surface relevant
13-
information in a compact space without overwhelming the main layout or distracting you from your current task.
14-
</p>
15-
16-
<p>
17-
As activity accumulates over time, new entries are continuously added to this section while older records remain
18-
available for review. Scrolling allows you to explore past events at your own pace, making it easier to understand
19-
changes and patterns without navigating away from the current context.
20-
</p>
21-
22-
<p>
23-
Activity data may include security-related events, billing notifications, feature updates, and changes made by team
24-
members across your workspace. Keeping this information in a dedicated scrollable area helps maintain clarity and
25-
focus within the interface while still providing access to detailed historical information.
26-
</p>
27-
28-
<p>
29-
Use this area to monitor recent changes, verify completed actions, and stay informed about updates that may affect
30-
your workflow or account status. For a more comprehensive view, additional filters, search options, or detailed logs
31-
may be available elsewhere in the application.
32-
</p>
33-
</div>
9+
<ScrollArea.Content className="space-y-2">
10+
{automobiles.map((car) => (
11+
<span key={car.label} className="flex items-end gap-0.5">
12+
<a className="text-primary text-sm hover:underline!" href="">
13+
{car.label}
14+
</a>
15+
<span className="text-surface-500 text-[11px] font-mono mb-px tracking-tighter">({car.value})</span>
16+
</span>
17+
))}
3418
</ScrollArea.Content>
3519
</ScrollArea.Viewport>
36-
<ScrollArea.ThumbY className="w-1.5 bg-primary" />
20+
<ScrollArea.Scrollbar className="rounded-full bg-indigo-500/10 w-2">
21+
<ScrollArea.Thumb className="relative bg-transparent after:content-[''] after:rounded-full after:bg-indigo-500 after:absolute after:inset-0 active:after:scale-y-90 active:after:scale-x-75 after:transition-transform" />
22+
</ScrollArea.Scrollbar>
3723
</ScrollArea.Root>
3824
</div>
3925
);
4026
}
27+
28+
const automobiles = [
29+
{ label: 'Audi', value: '200' },
30+
{ label: 'BMW', value: '350' },
31+
{ label: 'Mercedes-Benz', value: '420' },
32+
{ label: 'Volkswagen', value: '510' },
33+
{ label: 'Toyota', value: '610' },
34+
{ label: 'Honda', value: '280' },
35+
{ label: 'Hyundai', value: '390' },
36+
{ label: 'Kia', value: '260' },
37+
{ label: 'Ford', value: '470' },
38+
{ label: 'Renault', value: '530' },
39+
{ label: 'Peugeot', value: '410' },
40+
{ label: 'Citroen', value: '190' },
41+
{ label: 'Skoda', value: '360' },
42+
{ label: 'Seat', value: '210' },
43+
{ label: 'Opel', value: '440' },
44+
{ label: 'Fiat', value: '620' },
45+
{ label: 'Dacia', value: '380' },
46+
{ label: 'Volvo', value: '140' },
47+
{ label: 'Mazda', value: '120' },
48+
{ label: 'Mitsubishi', value: '110' },
49+
{ label: 'Nissan', value: '330' },
50+
{ label: 'Subaru', value: '60' },
51+
{ label: 'Suzuki', value: '170' },
52+
{ label: 'Jeep', value: '95' },
53+
{ label: 'Land Rover', value: '80' },
54+
{ label: 'Porsche', value: '75' },
55+
{ label: 'Ferrari', value: '12' },
56+
{ label: 'Lamborghini', value: '9' },
57+
{ label: 'Bentley', value: '15' },
58+
{ label: 'Rolls-Royce', value: '6' },
59+
{ label: 'Mini', value: '130' },
60+
{ label: 'Tesla', value: '220' },
61+
{ label: 'BYD', value: '55' },
62+
{ label: 'Chery', value: '160' },
63+
{ label: 'MG', value: '145' },
64+
{ label: 'DS Automobiles', value: '40' },
65+
{ label: 'Alfa Romeo', value: '50' },
66+
{ label: 'Lancia', value: '8' },
67+
{ label: 'Cadillac', value: '22' },
68+
{ label: 'Chevrolet', value: '105' },
69+
{ label: 'Dodge', value: '18' },
70+
{ label: 'GMC', value: '14' },
71+
{ label: 'Infiniti', value: '11' },
72+
{ label: 'Acura', value: '7' },
73+
{ label: 'Genesis', value: '35' },
74+
{ label: 'Geely', value: '27' },
75+
{ label: 'Proton', value: '19' },
76+
{ label: 'Togg', value: '65' },
77+
{ label: 'Rivian', value: '4' },
78+
{ label: 'Lucid', value: '3' }
79+
];

0 commit comments

Comments
 (0)