2
2
3
3
import classNames from 'classnames' ;
4
4
import React from 'react' ;
5
+ import { atom , useRecoilState } from 'recoil' ;
5
6
6
7
interface InteractiveSectionTab {
7
8
key : string ;
8
9
label : string ;
9
10
body : React . ReactNode ;
10
11
}
11
12
13
+ const syncedTabsAtom = atom < Record < string , string > > ( {
14
+ key : 'syncedTabState' ,
15
+ default : { } ,
16
+ } ) ;
17
+
12
18
/**
13
19
* To optimize rendering, most of the components are server-components,
14
20
* and the interactiveness is mainly handled by a few key components like this one.
@@ -34,6 +40,8 @@ export function InteractiveSection(props: {
34
40
children ?: React . ReactNode ;
35
41
/** Children to display within the container */
36
42
overlay ?: React . ReactNode ;
43
+ /** An optional key referencing a value in global state */
44
+ stateKey ?: string ;
37
45
} ) {
38
46
const {
39
47
id,
@@ -47,12 +55,18 @@ export function InteractiveSection(props: {
47
55
overlay,
48
56
toggleOpenIcon = '▶' ,
49
57
toggleCloseIcon = '▼' ,
58
+ stateKey,
50
59
} = props ;
60
+ const [ syncedTabs , setSyncedTabs ] = useRecoilState ( syncedTabsAtom ) ;
61
+ const tabFromState =
62
+ stateKey && stateKey in syncedTabs
63
+ ? tabs . find ( ( tab ) => tab . key === syncedTabs [ stateKey ] )
64
+ : undefined ;
51
65
52
66
const [ opened , setOpened ] = React . useState ( defaultOpened ) ;
53
- const [ selectedTabKey , setSelectedTab ] = React . useState ( defaultTab ) ;
67
+ const [ selectedTabKey , setSelectedTab ] = React . useState ( tabFromState ?. key ?? defaultTab ) ;
54
68
const selectedTab : InteractiveSectionTab | undefined =
55
- tabs . find ( ( tab ) => tab . key === selectedTabKey ) ?? tabs [ 0 ] ;
69
+ tabFromState ?? tabs . find ( ( tab ) => tab . key === selectedTabKey ) ?? tabs [ 0 ] ;
56
70
57
71
return (
58
72
< div
@@ -99,6 +113,12 @@ export function InteractiveSection(props: {
99
113
value = { selectedTab . key }
100
114
onChange = { ( event ) => {
101
115
setSelectedTab ( event . target . value ) ;
116
+ if ( stateKey ) {
117
+ setSyncedTabs ( ( state ) => ( {
118
+ ...state ,
119
+ [ stateKey ] : event . target . value ,
120
+ } ) ) ;
121
+ }
102
122
setOpened ( true ) ;
103
123
} }
104
124
>
0 commit comments