codigo0/node_modules/react-remove-scroll/dist/es2019/handleScroll.js
planetazuzu 5d7a6500fe refactor: Fase 1 - Clean Architecture, refactorización modular y eliminación de duplicidades
-  Ticket 1.1: Estructura Clean Architecture en backend
-  Ticket 1.2: Schemas Zod compartidos
-  Ticket 1.3: Refactorización drugs.ts (1362 → 8 archivos modulares)
-  Ticket 1.4: Refactorización procedures.ts (3583 → 6 archivos modulares)
-  Ticket 1.5: Eliminación de duplicidades (~50 líneas)

Cambios principales:
- Creada estructura Clean Architecture en backend/src/
- Schemas Zod compartidos en backend/src/shared/schemas/
- Refactorización modular de drugs y procedures
- Utilidades genéricas en src/utils/ (filter, validation)
- Eliminados scripts obsoletos y documentación antigua
- Corregidos errores: QueryClient, import test-error-handling
- Build verificado y funcionando correctamente
2026-01-25 21:09:47 +01:00

97 lines
4.1 KiB
JavaScript

const alwaysContainsScroll = (node) =>
// textarea will always _contain_ scroll inside self. It only can be hidden
node.tagName === 'TEXTAREA';
const elementCanBeScrolled = (node, overflow) => {
if (!(node instanceof Element)) {
return false;
}
const styles = window.getComputedStyle(node);
return (
// not-not-scrollable
styles[overflow] !== 'hidden' &&
// contains scroll inside self
!(styles.overflowY === styles.overflowX && !alwaysContainsScroll(node) && styles[overflow] === 'visible'));
};
const elementCouldBeVScrolled = (node) => elementCanBeScrolled(node, 'overflowY');
const elementCouldBeHScrolled = (node) => elementCanBeScrolled(node, 'overflowX');
export const locationCouldBeScrolled = (axis, node) => {
const ownerDocument = node.ownerDocument;
let current = node;
do {
// Skip over shadow root
if (typeof ShadowRoot !== 'undefined' && current instanceof ShadowRoot) {
current = current.host;
}
const isScrollable = elementCouldBeScrolled(axis, current);
if (isScrollable) {
const [, scrollHeight, clientHeight] = getScrollVariables(axis, current);
if (scrollHeight > clientHeight) {
return true;
}
}
current = current.parentNode;
} while (current && current !== ownerDocument.body);
return false;
};
const getVScrollVariables = ({ scrollTop, scrollHeight, clientHeight }) => [
scrollTop,
scrollHeight,
clientHeight,
];
const getHScrollVariables = ({ scrollLeft, scrollWidth, clientWidth }) => [
scrollLeft,
scrollWidth,
clientWidth,
];
const elementCouldBeScrolled = (axis, node) => axis === 'v' ? elementCouldBeVScrolled(node) : elementCouldBeHScrolled(node);
const getScrollVariables = (axis, node) => axis === 'v' ? getVScrollVariables(node) : getHScrollVariables(node);
const getDirectionFactor = (axis, direction) =>
/**
* If the element's direction is rtl (right-to-left), then scrollLeft is 0 when the scrollbar is at its rightmost position,
* and then increasingly negative as you scroll towards the end of the content.
* @see https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeft
*/
axis === 'h' && direction === 'rtl' ? -1 : 1;
export const handleScroll = (axis, endTarget, event, sourceDelta, noOverscroll) => {
const directionFactor = getDirectionFactor(axis, window.getComputedStyle(endTarget).direction);
const delta = directionFactor * sourceDelta;
// find scrollable target
let target = event.target;
const targetInLock = endTarget.contains(target);
let shouldCancelScroll = false;
const isDeltaPositive = delta > 0;
let availableScroll = 0;
let availableScrollTop = 0;
do {
if (!target) {
break;
}
const [position, scroll, capacity] = getScrollVariables(axis, target);
const elementScroll = scroll - capacity - directionFactor * position;
if (position || elementScroll) {
if (elementCouldBeScrolled(axis, target)) {
availableScroll += elementScroll;
availableScrollTop += position;
}
}
const parent = target.parentNode;
// we will "bubble" from ShadowDom in case we are, or just to the parent in normal case
// this is the same logic used in focus-lock
target = (parent && parent.nodeType === Node.DOCUMENT_FRAGMENT_NODE ? parent.host : parent);
} while (
// portaled content
(!targetInLock && target !== document.body) ||
// self content
(targetInLock && (endTarget.contains(target) || endTarget === target)));
// handle epsilon around 0 (non standard zoom levels)
if (isDeltaPositive &&
((noOverscroll && Math.abs(availableScroll) < 1) || (!noOverscroll && delta > availableScroll))) {
shouldCancelScroll = true;
}
else if (!isDeltaPositive &&
((noOverscroll && Math.abs(availableScrollTop) < 1) || (!noOverscroll && -delta > availableScrollTop))) {
shouldCancelScroll = true;
}
return shouldCancelScroll;
};