-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDualScrollSync.tsx
More file actions
107 lines (97 loc) · 2.74 KB
/
DualScrollSync.tsx
File metadata and controls
107 lines (97 loc) · 2.74 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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import clsx from 'clsx';
import type { FC } from 'react';
import { useMemo } from 'react';
import type { DualScrollSyncContextProps } from '@/contexts';
import { DualScrollSyncContext } from '@/contexts';
import { useScrollSyncObserver, useValidateChildren } from '@/hooks';
import styles from './DualScrollSync.module.scss';
import type { DualScrollSyncProps, DualScrollSyncType } from './DualScrollSync.types';
import { DualScrollSyncContent } from './DualScrollSyncContent';
import { DualScrollSyncContentSection } from './DualScrollSyncContentSection/DualScrollSyncContentSection';
import { DualScrollSyncLabel } from './DualScrollSyncLabel/DualScrollSyncLabel';
import { DualScrollSyncNav } from './DualScrollSyncNav';
import { DualScrollSyncNavItem } from './DualScrollSyncNavItem';
export const DualScrollSyncBase: FC<DualScrollSyncProps> = ({
children,
className,
id,
items,
onItemClick,
maxVisibleItems = 6,
style = {}
}) => {
const baseId = id || 'dual-scroll-sync';
const navId = `${baseId}-nav`;
const contentId = `${baseId}-content`;
const { activeKey, contentRef, sectionRefs, navItemRefs, navRef, onMenuItemSelect } =
useScrollSyncObserver();
const value = useMemo<DualScrollSyncContextProps>(
() => ({
baseId,
navId,
contentId,
activeKey,
contentRef,
sectionRefs,
navItemRefs,
navRef,
maxVisibleItems,
onMenuItemSelect,
onItemClick
}),
[
baseId,
navId,
contentId,
activeKey,
contentRef,
sectionRefs,
navItemRefs,
navRef,
maxVisibleItems,
onMenuItemSelect,
onItemClick
]
);
useValidateChildren({ children, items });
return (
<DualScrollSyncContext.Provider value={value}>
<section
className={clsx(styles.scrollSync, className)}
data-testid={baseId}
id={baseId}
style={style}
>
{items ? (
<>
<DualScrollSyncNav>
{items.map(({ sectionKey, label }) => (
<DualScrollSyncNavItem key={sectionKey} sectionKey={sectionKey}>
{label}
</DualScrollSyncNavItem>
))}
</DualScrollSyncNav>
<DualScrollSyncContent>
{items.map(({ sectionKey, label, children }) => (
<DualScrollSyncContentSection key={sectionKey} sectionKey={sectionKey}>
<DualScrollSyncLabel>{label}</DualScrollSyncLabel>
{children}
</DualScrollSyncContentSection>
))}
</DualScrollSyncContent>
</>
) : (
children
)}
</section>
</DualScrollSyncContext.Provider>
);
};
DualScrollSyncBase.displayName = 'DualScrollSync';
export const DualScrollSync: DualScrollSyncType = Object.assign(DualScrollSyncBase, {
Nav: DualScrollSyncNav,
NavItem: DualScrollSyncNavItem,
Content: DualScrollSyncContent,
ContentSection: DualScrollSyncContentSection,
Label: DualScrollSyncLabel
});