@i-novus/ui-core
Version:
Базовые UI компоненты
79 lines (78 loc) • 2.98 kB
JavaScript
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);
}