@pmndrs/uikit
Version:
Build performant 3D user interfaces with Three.js and yoga.
61 lines (60 loc) • 2.34 kB
JavaScript
import { createConditionalPropertyTranslator } from './utils.js';
import { addHandler } from './components/index.js';
import { traverseProperties } from './properties/index.js';
export function setupCursorCleanup(hoveredSignal, abortSignal) {
//cleanup cursor effect
abortSignal.addEventListener('abort', () => unsetCursorType(hoveredSignal));
}
export function addHoverHandlers(target, style, properties, defaultProperties, hoveredSignal, defaultCursor) {
let hoverPropertiesExist = false;
traverseProperties(style, properties, defaultProperties, (p) => {
if ('hover' in p) {
hoverPropertiesExist = true;
}
});
const cursor = style?.cursor ?? properties?.cursor ?? defaultCursor;
if (!hoverPropertiesExist && style?.onHoverChange == null && properties?.onHoverChange == null && cursor == null) {
//no need to listen to hover
hoveredSignal.value.length = 0;
return;
}
addHandler('onPointerOver', target, ({ pointerId }) => {
hoveredSignal.value = [pointerId, ...hoveredSignal.value];
if (hoveredSignal.value.length === 1) {
properties?.onHoverChange?.(true);
style?.onHoverChange?.(true);
}
if (cursor != null) {
setCursorType(hoveredSignal, cursor);
}
});
addHandler('onPointerOut', target, ({ pointerId }) => {
hoveredSignal.value = hoveredSignal.value.filter((id) => id != pointerId);
if (hoveredSignal.value.length === 0) {
properties?.onHoverChange?.(false);
style?.onHoverChange?.(false);
}
unsetCursorType(hoveredSignal);
});
}
export function createHoverPropertyTransformers(hoveredSignal) {
return {
hover: createConditionalPropertyTranslator(() => hoveredSignal.value.length > 0),
};
}
const cursorRefStack = [];
const cursorTypeStack = [];
export function setCursorType(ref, type) {
cursorRefStack.push(ref);
cursorTypeStack.push(type);
document.body.style.cursor = type;
}
export function unsetCursorType(ref) {
const index = cursorRefStack.indexOf(ref);
if (index == -1) {
return;
}
cursorRefStack.splice(index, 1);
cursorTypeStack.splice(index, 1);
document.body.style.cursor = cursorTypeStack[cursorTypeStack.length - 1] ?? 'default';
}