mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
98 lines
2.6 KiB
TypeScript
98 lines
2.6 KiB
TypeScript
/* eslint-disable react/prop-types */
|
|
/* eslint-disable @typescript-eslint/ban-types */
|
|
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
import { useCallback, useReducer, createContext, useContext } from 'react'
|
|
|
|
import type { Item } from '#types/Item'
|
|
import type { Marker, Popup } from 'leaflet'
|
|
|
|
interface LeafletRef {
|
|
item: Item
|
|
marker: Marker
|
|
popup: Popup
|
|
}
|
|
|
|
type ActionType =
|
|
| { type: 'ADD_MARKER'; item: Item; marker: Marker }
|
|
| { type: 'ADD_POPUP'; item: Item; popup: Popup }
|
|
|
|
type UseLeafletRefsManagerResult = ReturnType<typeof useLeafletRefsManager>
|
|
|
|
const LeafletRefsContext = createContext<UseLeafletRefsManagerResult>({
|
|
leafletRefs: {},
|
|
addMarker: () => {},
|
|
addPopup: () => {},
|
|
})
|
|
|
|
function useLeafletRefsManager(initialLeafletRefs: {}): {
|
|
leafletRefs: Record<string, LeafletRef>
|
|
addMarker: (item: Item, marker: Marker) => void
|
|
addPopup: (item: Item, popup: Popup) => void
|
|
} {
|
|
const [leafletRefs, dispatch] = useReducer(
|
|
(state: Record<string, LeafletRef>, action: ActionType) => {
|
|
switch (action.type) {
|
|
case 'ADD_MARKER':
|
|
return {
|
|
...state,
|
|
[action.item.id]: {
|
|
...state[action.item.id],
|
|
marker: action.marker,
|
|
item: action.item,
|
|
},
|
|
}
|
|
case 'ADD_POPUP':
|
|
return {
|
|
...state,
|
|
[action.item.id]: { ...state[action.item.id], popup: action.popup, item: action.item },
|
|
}
|
|
default:
|
|
throw new Error()
|
|
}
|
|
},
|
|
initialLeafletRefs,
|
|
)
|
|
|
|
const addMarker = useCallback((item: Item, marker: Marker) => {
|
|
dispatch({
|
|
type: 'ADD_MARKER',
|
|
item,
|
|
marker,
|
|
})
|
|
}, [])
|
|
|
|
const addPopup = useCallback((item: Item, popup: Popup) => {
|
|
dispatch({
|
|
type: 'ADD_POPUP',
|
|
item,
|
|
popup,
|
|
})
|
|
}, [])
|
|
|
|
return { leafletRefs, addMarker, addPopup }
|
|
}
|
|
|
|
export const LeafletRefsProvider: React.FunctionComponent<{
|
|
initialLeafletRefs: {}
|
|
children?: React.ReactNode
|
|
}> = ({ initialLeafletRefs, children }) => (
|
|
<LeafletRefsContext.Provider value={useLeafletRefsManager(initialLeafletRefs)}>
|
|
{children}
|
|
</LeafletRefsContext.Provider>
|
|
)
|
|
|
|
export const useLeafletRefs = (): Record<string, LeafletRef> => {
|
|
const { leafletRefs } = useContext(LeafletRefsContext)
|
|
return leafletRefs
|
|
}
|
|
|
|
export const useAddMarker = (): UseLeafletRefsManagerResult['addMarker'] => {
|
|
const { addMarker } = useContext(LeafletRefsContext)
|
|
return addMarker
|
|
}
|
|
|
|
export const useAddPopup = (): UseLeafletRefsManagerResult['addPopup'] => {
|
|
const { addPopup } = useContext(LeafletRefsContext)
|
|
return addPopup
|
|
}
|