-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expand file tree
/
Copy pathTabSelectionIndicator.tsx
More file actions
37 lines (34 loc) · 1.12 KB
/
TabSelectionIndicator.tsx
File metadata and controls
37 lines (34 loc) · 1.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import {useContext, useId} from "react";
import {TabListStateContext} from "react-aria-components";
export function TabSelectionIndicator() {
let state = useContext(TabListStateContext);
if (!state) return null;
// Generate keyframes for each tab using CSS anchor positioning.
let animationId = useId();
let keyframes = [];
for (let item of state.collection) {
keyframes.push(`${Math.round(item.index / (state.collection.size - 1) * 100)}% {
top: anchor(--tab-${item.key} start);
left: anchor(--tab-${item.key} start);
bottom: anchor(--tab-${item.key} end);
right: anchor(--tab-${item.key} end);
}`);
}
return (
<>
<style>
{`@keyframes ${animationId} {
${keyframes.join('\n\n')}
`}
</style>
<div
className="absolute z-10 bg-white forced-color-adjust-none rounded-full mix-blend-difference contain-strict transition-[inset]"
style={{
animationName: animationId,
animationTimingFunction: 'linear',
animationTimeline: '--scroll',
animationFillMode: 'both'
} as any} />
</>
);
}