@@ -18,6 +18,8 @@ import parse from "autosuggest-highlight/parse";
1818import clsx from "clsx" ;
1919import { AnimatePresence , Transition } from "framer-motion" ;
2020import React , { useState } from "react" ;
21+ import create from "zustand" ;
22+ import shallow from "zustand/shallow" ;
2123
2224import { BackButton , DataSource } from "@/configurator" ;
2325import { DataSetMetadata } from "@/configurator/components/dataset-metadata" ;
@@ -31,57 +33,35 @@ import useEvent from "@/utils/use-event";
3133
3234import Flex from "./flex" ;
3335
34- type Section = "general" | "data" ;
36+ type MetadataPanelSection = "general" | "data" ;
3537
36- type State = {
38+ type MetadataPanelState = {
3739 open : boolean ;
3840 toggle : ( ) => void ;
39- activeSection : Section ;
40- setActiveSection : ( d : Section ) => void ;
41+ activeSection : MetadataPanelSection ;
42+ setActiveSection : ( d : MetadataPanelSection ) => void ;
4143 selectedDimension : DimensionMetadataFragment | undefined ;
42- setSelectedDimension : ( d : DimensionMetadataFragment | undefined ) => void ;
44+ setSelectedDimension : ( d : DimensionMetadataFragment ) => void ;
4345 clearSelectedDimension : ( ) => void ;
4446} ;
4547
46- const Context = React . createContext < State | undefined > ( undefined ) ;
47-
48- export const ContextProvider = ( {
49- children,
50- } : {
51- children : React . ReactNode ;
52- } ) => {
53- const [ open , setOpen ] = React . useState ( false ) ;
54- const [ activeSection , setActiveSection ] = React . useState < Section > ( "general" ) ;
55- const [ selectedDimension , setSelectedDimension ] = React . useState <
56- DimensionMetadataFragment | undefined
57- > ( undefined ) ;
58-
59- const ctx : State = React . useMemo ( ( ) => {
60- return {
61- open,
62- toggle : ( ) => setOpen ( ! open ) ,
63- activeSection,
64- setActiveSection,
65- selectedDimension,
66- setSelectedDimension,
67- clearSelectedDimension : ( ) => setSelectedDimension ( undefined ) ,
68- } ;
69- } , [ open , activeSection , selectedDimension ] ) ;
70-
71- return < Context . Provider value = { ctx } > { children } </ Context . Provider > ;
72- } ;
73-
74- export const useContext = ( ) => {
75- const ctx = React . useContext ( Context ) ;
76-
77- if ( ctx === undefined ) {
78- throw Error (
79- "You need to wrap your component in <ContextProvider /> to useContext()"
80- ) ;
81- }
82-
83- return ctx ;
84- } ;
48+ export const useMetadataPanelStore = create < MetadataPanelState > ( ( set , get ) => ( {
49+ open : false ,
50+ toggle : ( ) => {
51+ set ( { open : ! get ( ) . open } ) ;
52+ } ,
53+ activeSection : "general" ,
54+ setActiveSection : ( d : MetadataPanelSection ) => {
55+ set ( { activeSection : d } ) ;
56+ } ,
57+ selectedDimension : undefined ,
58+ setSelectedDimension : ( d : DimensionMetadataFragment ) => {
59+ set ( { selectedDimension : d } ) ;
60+ } ,
61+ clearSelectedDimension : ( ) => {
62+ set ( { selectedDimension : undefined } ) ;
63+ } ,
64+ } ) ) ;
8565
8666const useDrawerStyles = makeStyles < Theme , { top : number } > ( ( theme ) => {
8767 return {
@@ -163,32 +143,6 @@ const useOtherStyles = makeStyles<Theme>((theme) => {
163143 } ;
164144} ) ;
165145
166- export const MetadataPanel = ( {
167- datasetIri,
168- dataSource,
169- dimensions,
170- container,
171- top,
172- } : {
173- datasetIri : string ;
174- dataSource : DataSource ;
175- dimensions : DimensionMetadataFragment [ ] ;
176- container ?: HTMLDivElement | null ;
177- top ?: number ;
178- } ) => {
179- return (
180- < ContextProvider >
181- < PanelInner
182- datasetIri = { datasetIri }
183- dataSource = { dataSource }
184- dimensions = { dimensions }
185- container = { container }
186- top = { top }
187- />
188- </ ContextProvider >
189- ) ;
190- } ;
191-
192146const animationProps : Transition = {
193147 transition : {
194148 duration : 0.2 ,
@@ -204,7 +158,7 @@ const animationProps: Transition = {
204158 } ,
205159} ;
206160
207- const PanelInner = ( {
161+ export const MetadataPanel = ( {
208162 datasetIri,
209163 dataSource,
210164 dimensions,
@@ -214,12 +168,21 @@ const PanelInner = ({
214168 datasetIri : string ;
215169 dataSource : DataSource ;
216170 dimensions : DimensionMetadataFragment [ ] ;
217- container : HTMLDivElement | null | undefined ;
171+ container ? : HTMLDivElement | null ;
218172 top ?: number ;
219173} ) => {
220174 const drawerClasses = useDrawerStyles ( { top } ) ;
221175 const otherClasses = useOtherStyles ( ) ;
222- const { open, toggle, activeSection, setActiveSection } = useContext ( ) ;
176+ const { open, toggle, activeSection, setActiveSection } =
177+ useMetadataPanelStore (
178+ ( state ) => ( {
179+ open : state . open ,
180+ toggle : state . toggle ,
181+ activeSection : state . activeSection ,
182+ setActiveSection : state . setActiveSection ,
183+ } ) ,
184+ shallow
185+ ) ;
223186 const handleToggle = useEvent ( ( ) => {
224187 toggle ( ) ;
225188 } ) ;
@@ -342,7 +305,14 @@ const TabPanelData = ({
342305} ) => {
343306 const classes = useOtherStyles ( ) ;
344307 const { selectedDimension, setSelectedDimension, clearSelectedDimension } =
345- useContext ( ) ;
308+ useMetadataPanelStore (
309+ ( state ) => ( {
310+ selectedDimension : state . selectedDimension ,
311+ setSelectedDimension : state . setSelectedDimension ,
312+ clearSelectedDimension : state . clearSelectedDimension ,
313+ } ) ,
314+ shallow
315+ ) ;
346316 const [ inputValue , setInputValue ] = useState ( "" ) ;
347317
348318 const options = React . useMemo ( ( ) => {
@@ -373,7 +343,7 @@ const TabPanelData = ({
373343 < Autocomplete
374344 className = { classes . search }
375345 disablePortal
376- onChange = { ( _ , v ) => setSelectedDimension ( v ? .value ) }
346+ onChange = { ( _ , v ) => v && setSelectedDimension ( v . value ) }
377347 inputValue = { inputValue }
378348 onInputChange = { ( _ , v ) => setInputValue ( v . toLowerCase ( ) ) }
379349 options = { options }
@@ -443,7 +413,12 @@ const TabPanelDataDimension = ({
443413 expandable : boolean ;
444414} ) => {
445415 const classes = useOtherStyles ( ) ;
446- const { setSelectedDimension } = useContext ( ) ;
416+ const { setSelectedDimension } = useMetadataPanelStore (
417+ ( state ) => ( {
418+ setSelectedDimension : state . setSelectedDimension ,
419+ } ) ,
420+ shallow
421+ ) ;
447422 const { description, showExpandButton } = React . useMemo ( ( ) => {
448423 if ( expandable && dim . description && dim . description . length > 180 ) {
449424 return {
0 commit comments