import { createContext, useContext, useRef } from 'react' import { create } from 'zustand' import { useShallow } from 'zustand/shallow' import type { PersistStoreProviderProps } from '../types.js' import type { HeaderState, HeaderStore } from './types.js' const HeaderStoreContext = createContext(null) export function HeaderStoreProvider({ children }: PersistStoreProviderProps) { const storeRef = useRef(null) if (!storeRef.current) { storeRef.current = createHeaderStore() } return ( {children} ) } function useHeaderStoreContext() { const useStore = useContext(HeaderStoreContext) if (!useStore) { throw new Error( `You forgot to wrap your component in <${HeaderStoreProvider.name}>.` ) } return useStore } export function useHeaderStore(selector: (state: HeaderState) => T): T { const useStore = useHeaderStoreContext() return useStore(useShallow(selector)) } // We use fixed position on the header when Widget is in Full Height layout. // We do this to get it to work like the sticky header does in the other layout modes. // As the header is position fixed its not in the document flow anymore. // To prevent the remaining page content from appearing behind the header we need to // pass the headers height so that the position of the page content can be adjusted export function useHeaderHeight() { const headerHeight = useHeaderStore((state) => state.headerHeight) return { headerHeight, } } export function useSetHeaderHeight() { const setHeaderHeight = useHeaderStore((state) => state.setHeaderHeight) return { setHeaderHeight, } } const createHeaderStore = () => create((set, get) => ({ headerHeight: 108, // a basic default height setAction: (element) => { set(() => ({ element, })) return get().removeAction }, setTitle: (title) => { set(() => ({ title, })) return get().removeTitle }, removeAction: () => { set(() => ({ element: null, })) }, removeTitle: () => { set(() => ({ title: undefined, })) }, setHeaderHeight: (headerHeight) => { set(() => ({ headerHeight, })) }, }))