@neo4j-ndl/react
Version:
React implementation of Neo4j Design System
95 lines • 4.04 kB
JavaScript
/**
*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { autoUpdate, flip, offset, safePolygon, shift, useClick, useClientPoint, useDismiss, useFloating, useFocus, useHover, useInteractions, useRole, } from '@floating-ui/react';
import { createContext, useContext, useId, useMemo, useState } from 'react';
export function useTooltip({ isInitialOpen = false, placement = 'top', isOpen: controlledOpen, onOpenChange: setControlledOpen, type = 'simple', isPortaled = true, strategy = 'absolute', hoverDelay = undefined, shouldCloseOnReferenceClick = false, autoUpdateOptions, isDisabled = false, followCursor = false, } = {}) {
const id = useId();
const [headerId, setHeaderId] = useState(id);
const [isUncontrolledOpen, setIsUncontrolledOpen] = useState(isInitialOpen);
const isOpen = controlledOpen !== null && controlledOpen !== void 0 ? controlledOpen : isUncontrolledOpen;
const setOpen = setControlledOpen !== null && setControlledOpen !== void 0 ? setControlledOpen : setIsUncontrolledOpen;
const data = useFloating({
middleware: [
offset(5),
flip({
crossAxis: placement.includes('-'),
fallbackAxisSideDirection: 'start',
padding: 5,
}),
shift({ padding: 5 }),
],
onOpenChange: setOpen,
open: isOpen,
placement,
strategy,
whileElementsMounted(referenceEl, floatingEl, update) {
const cleanup = autoUpdate(referenceEl, floatingEl, update, Object.assign({}, autoUpdateOptions));
return cleanup;
},
});
const context = data.context;
const hover = useHover(context, {
delay: hoverDelay,
enabled: type === 'simple' && !isDisabled,
handleClose: safePolygon(),
move: false,
});
const click = useClick(context, {
enabled: type === 'rich' && !isDisabled,
});
const focus = useFocus(context, {
enabled: type === 'simple' && !isDisabled,
visibleOnly: true,
});
const dismiss = useDismiss(context, {
escapeKey: true,
outsidePress: true,
referencePress: shouldCloseOnReferenceClick,
});
const role = useRole(context, {
role: type === 'simple' ? 'tooltip' : 'dialog',
});
const followAxis = placement.startsWith('left') || placement.startsWith('right') ? 'y' : 'x';
const clientPoint = useClientPoint(context, {
axis: followAxis,
enabled: followCursor && type === 'simple' && !isDisabled,
});
const interactions = useInteractions([
hover,
focus,
dismiss,
role,
click,
clientPoint,
]);
return useMemo(() => (Object.assign(Object.assign({ headerId: type === 'rich' ? headerId : undefined, isOpen,
isPortaled, setHeaderId: type === 'rich' ? setHeaderId : undefined, setOpen,
type }, interactions), data)), [headerId, isOpen, isPortaled, setOpen, type, interactions, data]);
}
export const TooltipContext = createContext(null);
export const useTooltipContext = () => {
const context = useContext(TooltipContext);
if (context === null) {
throw new Error('Tooltip components must be wrapped in <Tooltip />');
}
return context;
};
//# sourceMappingURL=use-tooltip.js.map