UNPKG

@i-novus/ui-core

Version:

Базовые UI компоненты

79 lines (78 loc) 2.98 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { createContext, useCallback, useContext, useMemo, useState } from 'react'; const DEFAULT_TOOLTIP_ID = 'DEFAULT_TOOLTIP_ID'; const DEFAULT_CONTEXT_DATA = { anchorRefs: new Set(), activeAnchor: { current: null }, attach: () => { /* attach anchor element */ }, detach: () => { /* detach anchor element */ }, setActiveAnchor: () => { /* set active anchor */ }, }; const DEFAULT_CONTEXT_DATA_WRAPPER = { getTooltipData: () => DEFAULT_CONTEXT_DATA, }; const TooltipContext = createContext(DEFAULT_CONTEXT_DATA_WRAPPER); /** * @deprecated Use the `data-tooltip-id` attribute, or the `anchorSelect` prop instead. * See https://react-tooltip.com/docs/getting-started */ export const TooltipProvider = ({ children }) => { const [anchorRefMap, setAnchorRefMap] = useState({ [DEFAULT_TOOLTIP_ID]: new Set(), }); const [activeAnchorMap, setActiveAnchorMap] = useState({ [DEFAULT_TOOLTIP_ID]: { current: null }, }); const attach = useCallback((tooltipId, ...refs) => { setAnchorRefMap((oldMap) => { const tooltipRefs = oldMap[tooltipId] ?? new Set(); refs.forEach(ref => tooltipRefs.add(ref)); // create new object to trigger re-render return { ...oldMap, [tooltipId]: new Set(tooltipRefs) }; }); }, []); const detach = useCallback((tooltipId, ...refs) => { setAnchorRefMap((oldMap) => { const tooltipRefs = oldMap[tooltipId]; if (!tooltipRefs) { // tooltip not found // maybe thow error? return oldMap; } refs.forEach(ref => tooltipRefs.delete(ref)); // create new object to trigger re-render return { ...oldMap }; }); }, []); const setActiveAnchor = (tooltipId, ref) => { setActiveAnchorMap((oldMap) => { if (oldMap[tooltipId]?.current === ref.current) { return oldMap; } // create new object to trigger re-render return { ...oldMap, [tooltipId]: ref }; }); }; const getTooltipData = useCallback((tooltipId = DEFAULT_TOOLTIP_ID) => ({ anchorRefs: anchorRefMap[tooltipId] ?? new Set(), activeAnchor: activeAnchorMap[tooltipId] ?? { current: null }, attach: (...refs) => attach(tooltipId, ...refs), detach: (...refs) => detach(tooltipId, ...refs), setActiveAnchor: (ref) => setActiveAnchor(tooltipId, ref), }), [anchorRefMap, activeAnchorMap, attach, detach]); const context = useMemo(() => { return { getTooltipData, }; }, [getTooltipData]); return _jsx(TooltipContext.Provider, { value: context, children: children }); }; export function useTooltip(tooltipId = DEFAULT_TOOLTIP_ID) { return useContext(TooltipContext).getTooltipData(tooltipId); }