UNPKG

indicate

Version:

Scroll indicator for elements with scrollable overflow.

1,111 lines (1,099 loc) 34.3 kB
// theme/default.ts var defaultTheme = { indicator: (_, options, direction) => ({ background: `linear-gradient(to ${direction}, rgba(255, 255, 255, 0), ${options.color})`, // Initially not visible. opacity: "0", display: "flex" }), hide: (indicator) => { indicator.style.opacity = "0"; indicator.style.pointerEvents = "none"; if (!indicator.style.transition) { indicator.style.transition = "opacity 300ms linear"; } }, show: (indicator) => { indicator.style.opacity = "1"; indicator.style.pointerEvents = "auto"; } }; // helper.ts var log = (messageKey, objects = null) => { if (process.env.NODE_ENV !== "production") { const Messages = { IntersectionObserver: "Browser doesn't support IntersectionObserver", ExistingInstance: "An instance for this element already exists", RemoveNoInstance: "remove() no instance found for element", InvalidElement: "Initialized failed due to invalid element", InvalidTheme: "Invalid value provided to theme option", ReactMultipleChildren: "When using React with childAsElement option there can only be a single child node at the top, falling back to adding a wrapper element", ReactMissingRef: "When using React with childAsElement option a ref to the child node is required, falling back to adding a wrapper element", ReactFragmentRef: "Cannot use a Fragment in conjunction with childAsElement" }; const prefixedMessage = `indicate: ${Messages[messageKey]}.`; if (objects) { console.warn(prefixedMessage, objects); } else { console.warn(prefixedMessage); } } }; var isInline = (element) => { const computedStyleDisplay = window.getComputedStyle(element).getPropertyValue("display"); if (computedStyleDisplay.startsWith("inline")) { return computedStyleDisplay; } return false; }; var isTable = (element) => element.tagName.toLowerCase() === "table"; var hideScrollbarClass = "hide-indicate-scrollbar"; var hideScrollbarStyleSheet; var hideScrollbarWithWebkitPseudoClass = (element) => { element.classList.add(hideScrollbarClass); if (hideScrollbarStyleSheet) { return; } hideScrollbarStyleSheet = document.createElement("style"); const { sheet } = document.head.appendChild(hideScrollbarStyleSheet); sheet.insertRule(`.${hideScrollbarClass}::-webkit-scrollbar { display: none; }`); }; var removeHideScrollbarStyle = (element, innerWrapper) => { element.classList.remove(hideScrollbarClass); innerWrapper.classList.remove(hideScrollbarClass); if (!hideScrollbarStyleSheet || document.querySelector(`.${hideScrollbarClass}`)) { return; } hideScrollbarStyleSheet.remove(); hideScrollbarStyleSheet = void 0; }; var wrapElementIn = (element, wrapper) => { element.parentNode.insertBefore(wrapper, element); wrapper.append(element); }; var createSvgLine = (x1, y1, x2, y2, rounded) => { const line = document.createElementNS("http://www.w3.org/2000/svg", "line"); if (rounded) { line.setAttribute("stroke-linecap", "round"); } line.setAttribute("stroke-width", "20"); line.setAttribute("x1", x1); line.setAttribute("y1", y1); line.setAttribute("x2", x2); line.setAttribute("y2", y2); return line; }; var arrowIcon = (icon, color) => { const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.setAttribute("viewBox", "0 0 120 120"); svg.setAttribute("stroke", color); if (icon === "arrow-rounded") { svg.appendChild(createSvgLine("10", "60", "110", "60", true)); svg.appendChild(createSvgLine("108.213", "57.3553", "61.5442", "10.6863", true)); svg.appendChild(createSvgLine("61.5442", "109.213", "108.213", "62.5442", true)); } else if (icon === "pointer-rounded") { svg.appendChild(createSvgLine("43.1421", "11", "91.2254", "59.0833", true)); svg.appendChild(createSvgLine("91.2254", "60.1421", "43.1421", "108.225", true)); } else if (icon === "arrow") { svg.appendChild(createSvgLine("0", "60", "120", "60")); svg.appendChild(createSvgLine("62.9289", "112.929", "113.284", "62.5736")); svg.appendChild(createSvgLine("113.284", "57.4264", "62.929", "7.07109")); } else { svg.appendChild(createSvgLine("37.0711", "6.92893", "96.8923", "66.7502")); svg.appendChild(createSvgLine("96.468", "53.0711", "37.0711", "112.468")); } return svg; }; // options.ts var defaultOptions = { arrow: { position: "center", icon: "arrow-rounded", color: "#000000" }, color: "#FFFFFF", width: "20px", click: { denominator: 2 }, hideScrollbar: true, moveStylesToWrapper: false }; var getOptions = (options = {}) => { const shallowMerge = { ...defaultOptions, ...options }; if (typeof shallowMerge.arrow === "object") { shallowMerge.arrow = { ...defaultOptions.arrow, ...shallowMerge.arrow }; } if (typeof shallowMerge.click === "object") { shallowMerge.click = { ...defaultOptions.click, ...shallowMerge.click }; } if (shallowMerge.arrow === true) { shallowMerge.arrow = defaultOptions.arrow; } if (shallowMerge.click === true) { shallowMerge.click = defaultOptions.click; } if (shallowMerge.theme && typeof shallowMerge.theme !== "object") { log("InvalidTheme", { theme: shallowMerge.theme }); delete shallowMerge.theme; } else if (!shallowMerge.theme) { shallowMerge.theme = defaultTheme; } return shallowMerge; }; // types.ts var Direction = /* @__PURE__ */ ((Direction3) => { Direction3["left"] = "left"; Direction3["right"] = "right"; Direction3["top"] = "top"; Direction3["bottom"] = "bottom"; return Direction3; })(Direction || {}); var directions = [ "left" /* left */, "right" /* right */, "top" /* top */, "bottom" /* bottom */ ]; var isHorizontal = (direction) => direction === "left" /* left */ || direction === "right" /* right */; var isVertical = (direction) => direction === "top" /* top */ || direction === "bottom" /* bottom */; // style.ts var directionToRotation = { ["left" /* left */]: 180, ["right" /* right */]: 0, ["top" /* top */]: 270, ["bottom" /* bottom */]: 90 }; var add = (element, properties) => { Object.keys(properties).forEach((property) => { element.style[property] = properties[property]; }); }; var alignment = (direction, options, observer = false) => { const style = {}; const horizontal = isHorizontal(direction); const vertical = isVertical(direction); if (horizontal) { style.top = "0"; } if (vertical) { style.left = "0"; } const size = observer ? "1px" : options.width; style.width = horizontal ? size : "100%"; style.height = vertical ? size : "100%"; return style; }; var base = { indicator: (_, options, direction) => { const style = { position: "absolute", // Initially hidden. display: "none", cursor: options.click ? "pointer" : "inherit", [direction]: "0" }; if (isHorizontal(direction)) { style.alignItems = options.arrow && options.arrow.position !== "center" ? `flex-${options.arrow.position}` : "center"; style.justifyContent = "center"; } else { style.justifyContent = options.arrow && options.arrow.position !== "center" ? `flex-${options.arrow.position}` : "center"; style.alignItems = "center"; } return { ...style, ...alignment(direction, options) }; }, hide: (indicator) => { indicator.style.display = "none"; }, show: (indicator) => { indicator.style.display = "flex"; }, arrow: (_, __, direction) => ({ width: "12px", height: "12px", display: "block", transform: `rotate(${directionToRotation[direction]}deg)` }), outerWrapper: (_, __, ___, inline) => { const styles = { position: "relative" }; if (inline) { styles.display = inline === "inline" ? "inline-block" : inline; } return styles; }, element: (element, _, table, inline) => { const styles = {}; if (inline) { styles.display = inline === "inline" ? "inline-block" : inline; styles.verticalAlign = "top"; } if (!table && element.style.overflow !== "scroll") { styles.overflow = "auto"; } if (table) { styles.position = "relative"; styles.display = "inline-block"; styles.verticalAlign = "top"; } return styles; }, innerWrapper: (element, _, table) => { const styles = { position: "relative", display: "inline-flex", // Avoid small bottom space otherwise added by inline-. verticalAlign: "top" }; if (table && element && element.style.overflow !== "scroll") { styles.overflow = "auto"; } return styles; }, observer: (_, options, direction) => ({ position: "absolute", pointerEvents: "none", [direction]: "0", ...alignment(direction, options, true) }) }; var apply = (method, ...args) => { if (typeof method === "object") { return method; } const result = method(...args); if (typeof result === "object") { return result; } return void 0; }; var applyBaseTheme = (key, element, options, args) => { if (["show", "hide"].includes(key) && options.theme[key]) { return {}; } return apply(base[key], element, options, ...args); }; var theme = (element, key, options, ...args) => { let userProperties; if (options.theme && options.theme[key]) { userProperties = apply(options.theme[key], element, options, ...args); } let baseProperties = applyBaseTheme(key, element, options, args); if (typeof options.inlineStyles === "object" && typeof options.inlineStyles[key] === "object") { baseProperties = { ...baseProperties, ...options.inlineStyles[key] }; } const styles = userProperties ? { ...baseProperties, ...userProperties } : baseProperties; if (styles && Object.keys(styles).length) { add(element, styles); } }; var hideScrollbar = (element) => { add(element, { // Hide scrollbar in IE and Edge. // @ts-ignore "-ms-overflow-style": "none", // Hide scrollbar in Firefox. "scrollbar-width": "none" }); }; // feature/click.ts var scrollHorizontal = (direction, element, denominator) => { const position = element.scrollLeft; let scrollOffset = element.offsetWidth / denominator; if (direction === "left" /* left */) { scrollOffset = -scrollOffset; } element.scrollTo({ left: position + scrollOffset, behavior: "smooth" }); }; var scrollVertical = (direction, element, denominator) => { const position = element.scrollTop; let scrollOffset = element.offsetHeight / denominator; if (direction === "top" /* top */) { scrollOffset = -scrollOffset; } element.scrollTo({ top: position + scrollOffset, behavior: "smooth" }); }; var handleIndicatorClick = (direction, element, denominator) => { if (isHorizontal(direction)) { scrollHorizontal(direction, element, denominator); } else { scrollVertical(direction, element, denominator); } }; var registerClickListener = (direction, element, instance) => { if (!instance.options.click) { return; } const { denominator } = instance.options.click; const scrollableElement = instance.table ? instance.innerWrapper : instance.element; if (instance.options.click) { element.addEventListener( "click", handleIndicatorClick.bind(null, direction, scrollableElement, denominator) ); } }; // feature/table.ts var wrapTable = ({ element, options }) => { const outerWrapper = options.outerWrapper ?? document.createElement("div"); theme(outerWrapper, "outerWrapper", options, true, false); if (!options.outerWrapper) { wrapElementIn(element, outerWrapper); } const innerWrapper = options.innerWrapper ?? document.createElement("div"); theme(innerWrapper, "innerWrapper", options, true, false); innerWrapper.style.overflow = "auto"; innerWrapper.style.display = ""; if (!options.innerWrapper) { wrapElementIn(element, innerWrapper); } return { outerWrapper, innerWrapper }; }; // feature/move-styles.ts var move = (element, wrapper, options) => { if (!options.moveStylesToWrapper) { return; } wrapper.className += ` ${element.className}`; element.className = ""; wrapper.style.cssText += element.style.cssText; element.style.cssText = null; }; var undoMove = (element, wrapper, instance) => { if (!instance.options.moveStylesToWrapper) { return; } if (instance.table && wrapper.style.position === "relative") { wrapper.style.position = ""; } element.className += ` ${wrapper.className}`; element.style.cssText += wrapper.style.cssText; }; // element.ts var wrapContentsWith = (element, wrapper) => { wrapper.innerHTML = element.innerHTML; element.innerHTML = ""; element.appendChild(wrapper); }; var wrap = ({ element, options, table, inline }) => { if (table) { return wrapTable({ element, options }); } const outerWrapper = options.outerWrapper ?? document.createElement("div"); theme(outerWrapper, "outerWrapper", options, table, inline); if (!options.outerWrapper) { wrapElementIn(element, outerWrapper); } const innerWrapper = options.innerWrapper ?? document.createElement("div"); theme(innerWrapper, "innerWrapper", options, table, inline); if (!options.innerWrapper) { wrapContentsWith(element, innerWrapper); } return { outerWrapper, innerWrapper }; }; var createInstance = (element, options) => { const table = isTable(element); const inline = isInline(element); const getSpansByDirection = () => { const result = {}; directions.forEach((direction) => { result[direction] = document.createElement("span"); }); return result; }; const { outerWrapper, innerWrapper } = wrap({ element, options, table, inline }); move(element, outerWrapper, options); theme(element, "element", options, table, inline); if (options.hideScrollbar) { const scrollableElement = table ? innerWrapper : element; hideScrollbar(scrollableElement); hideScrollbarWithWebkitPseudoClass(scrollableElement); } return { outerWrapper, innerWrapper, element, indicator: getSpansByDirection(), observer: getSpansByDirection(), options, table, inline }; }; var addArrow = (instance, indicator, direction) => { const options = instance.options.arrow; if (!options) { return; } let arrow = null; if (options.image) { arrow = document.createElement("img"); arrow.src = options.image; arrow.alt = `indicate arrow ${direction}`; } else if (options.markup && options.markup !== "") { if (typeof options.markup === "string") { arrow = document.createElement("span"); arrow.innerHTML = options.markup; } else { arrow = options.markup; } } else { arrow = arrowIcon(options.icon, options.color); } theme(arrow, "arrow", instance.options, direction); indicator.append(arrow); }; var addIndicators = (instance) => { directions.forEach((direction) => { const indicator = instance.indicator[direction]; theme(indicator, "indicator", instance.options, direction); instance.outerWrapper.append(indicator); registerClickListener(direction, indicator, instance); addArrow(instance, indicator, direction); }); }; var addObservers = (instance) => { directions.forEach((direction) => { const observer = instance.observer[direction]; theme(observer, "observer", instance.options, direction); if (instance.table) { instance.element.append(observer); } else { instance.innerWrapper.append(observer); } }); }; // observer.ts var handleObservation = (instance, entries) => { const visibilities = []; entries.forEach( (entry) => directions.forEach((direction) => { const isMatch = entry.target === instance.observer[direction]; if (isMatch) { visibilities.push({ direction, visible: entry.isIntersecting }); } }) ); visibilities.forEach((visibility) => { if (visibility.visible) { theme(instance.indicator[visibility.direction], "hide", instance.options); } else { theme(instance.indicator[visibility.direction], "show", instance.options); } }); }; var observe = (instance) => { const observer = new IntersectionObserver(handleObservation.bind(null, instance), { root: instance.table ? instance.innerWrapper : instance.element, // Only parts of element inside the root element are counted. rootMargin: "0px", // Even if only 10% of the observer is visible, trigger handler. threshold: 0.1 }); instance.intersectionObserver = observer; directions.forEach((direction) => observer.observe(instance.observer[direction])); }; // instance.ts var instances = /* @__PURE__ */ new Map(); var wrappers = /* @__PURE__ */ new Map(); var getDOMNodes = (element) => { if (typeof element === "string") { const elements = document.querySelectorAll(element); if (elements.length) { return elements; } } if (element instanceof NodeList && element.length) { return element; } if (element instanceof HTMLElement && element.isConnected) { return [element]; } log("InvalidElement", { element }); return false; }; var hasExistingInstance = (options, element) => { let found = false; if (instances.get(element)) { found = true; } if (options.moveStylesToWrapper && !found && element.childNodes.length > 0 && instances.get(element.childNodes[0])) { found = true; } if (found) { log("ExistingInstance", { element }); } return found; }; var initialize = (options, element) => { if (hasExistingInstance(options, element)) { return; } const instance = createInstance(element, options); addIndicators(instance); addObservers(instance); instances.set(element, instance); wrappers.set(instance.outerWrapper, instance); observe(instance); }; var indicate = (element, options) => { const elements = getDOMNodes(element); const instanceOptions = getOptions(options); if (!elements) { return; } if (!IntersectionObserver) { log("IntersectionObserver"); return; } elements.forEach(initialize.bind(null, instanceOptions)); }; var remove = (element) => { const elements = getDOMNodes(element); if (!elements) { return; } elements.forEach((currentElement) => { const instance = instances.get(currentElement) || wrappers.get(currentElement); if (!instance) { log("RemoveNoInstance", { element: currentElement }); return; } directions.forEach((direction) => { instance.indicator[direction].remove(); instance.observer[direction].remove(); }); instance.intersectionObserver.disconnect(); removeHideScrollbarStyle(instance.element, instance.innerWrapper); undoMove(instance.element, instance.outerWrapper, instance); if (!instance.options.outerWrapper) { instance.outerWrapper.replaceWith(...Array.from(instance.outerWrapper.childNodes)); } if (!instance.options.innerWrapper) { if (instance.table) { instance.innerWrapper.replaceWith(...Array.from(instance.innerWrapper.childNodes)); } else { const contents = instance.innerWrapper.innerHTML; instance.innerWrapper.remove(); currentElement.innerHTML = contents; } } instances.delete(currentElement); wrappers.delete(currentElement); }); }; // react.tsx import { useEffect, useRef, createElement, cloneElement, Children, forwardRef, useCallback, useState } from "react"; import { Fragment, jsx, jsxs } from "react/jsx-runtime"; var initialVisibility = (horizontal, vertical) => ({ ["top" /* top */]: false, ["right" /* right */]: !vertical, ["bottom" /* bottom */]: !horizontal, ["left" /* left */]: false }); var childrenValid = (children, childRef) => { let valid = true; if (Children.count(children) !== 1) { log("ReactMultipleChildren", { children }); valid = false; } if (valid && Children.toArray(children)[0].type.toString() === Symbol("react.fragment").toString()) { log("ReactFragmentRef", { children }); valid = false; } if (!childRef) { log("ReactMissingRef"); valid = false; } return valid; }; var hideScrollbarClass2 = "hide-indicate-scrollbar"; var getClassName = (className, hideScrollbar2) => { if (className === "undefined") { className = void 0; } if (!className && !hideScrollbar2) { return void 0; } return [className, hideScrollbar2 && hideScrollbarClass2].filter(Boolean).join(" "); }; var defaultArrowProps = { position: "center", icon: "arrow-rounded", color: "#000000" }; var directionToRotation2 = { ["left" /* left */]: 180, ["right" /* right */]: 0, ["top" /* top */]: 270, ["bottom" /* bottom */]: 90 }; function Arrow({ icon, color, markup, image, direction, theme: theme2 }) { const style = { width: 12, height: 12, display: "block", transform: `rotate(${directionToRotation2[direction]}deg)`, ...theme2.arrow }; if (image) { return /* @__PURE__ */ jsx("img", { style, src: image, alt: `indicate arrow ${direction}` }); } if (markup) { return /* @__PURE__ */ jsx("span", { style, children: markup }); } if (icon === "arrow-rounded") { return /* @__PURE__ */ jsxs("svg", { style, viewBox: "0 0 120 120", stroke: color, children: [ /* @__PURE__ */ jsx("line", { strokeWidth: 20, strokeLinecap: "round", x1: "10", y1: "60", x2: "110", y2: "60" }), /* @__PURE__ */ jsx( "line", { strokeWidth: 20, strokeLinecap: "round", x1: "108.213", y1: "57.3553", x2: "61.5442", y2: "10.6863" } ), /* @__PURE__ */ jsx( "line", { strokeWidth: 20, strokeLinecap: "round", x1: "61.5442", y1: "109.213", x2: "108.213", y2: "62.5442" } ) ] }); } if (icon === "pointer-rounded") { return /* @__PURE__ */ jsxs("svg", { style, viewBox: "0 0 120 120", stroke: color, children: [ /* @__PURE__ */ jsx( "line", { strokeWidth: 20, strokeLinecap: "round", x1: "43.1421", y1: "11", x2: "91.2254", y2: "59.0833" } ), /* @__PURE__ */ jsx( "line", { strokeWidth: 20, strokeLinecap: "round", x1: "91.2254", y1: "60.1421", x2: "43.1421", y2: "108.225" } ) ] }); } if (icon === "arrow") { return /* @__PURE__ */ jsxs("svg", { style, viewBox: "0 0 120 120", stroke: color, children: [ /* @__PURE__ */ jsx("line", { strokeWidth: 20, x1: "0", y1: "60", x2: "120", y2: "60" }), /* @__PURE__ */ jsx("line", { strokeWidth: 20, x1: "62.9289", y1: "112.929", x2: "113.284", y2: "62.5736" }), /* @__PURE__ */ jsx("line", { strokeWidth: 20, x1: "113.284", y1: "57.4264", x2: "62.929", y2: "7.07109" }) ] }); } return /* @__PURE__ */ jsxs("svg", { style, viewBox: "0 0 120 120", stroke: color, children: [ /* @__PURE__ */ jsx("line", { strokeWidth: 20, x1: "37.0711", y1: "6.92893", x2: "96.8923", y2: "66.7502" }), /* @__PURE__ */ jsx("line", { strokeWidth: 20, x1: "96.468", y1: "53.0711", x2: "37.0711", y2: "112.468" }) ] }); } var getArrowPosition = (arrow) => { const position = arrow.position ?? "center"; if (position === "center") { return position; } return `flex-${position}`; }; var getInline = (tag, display) => { if (display && display.startsWith("inline")) { return true; } return ["a", "code", "cite", "span", "strong", "b", "textarea"].includes(String(tag)); }; function Observers({ observersRef, as: ObserverElementType = "span", theme: theme2 }) { return /* @__PURE__ */ jsx(Fragment, { children: directions.map((direction) => /* @__PURE__ */ jsx( ObserverElementType, { ref: observersRef[direction], style: { position: "absolute", top: isHorizontal(direction) ? "0" : "auto", left: isVertical(direction) ? "0" : "auto", [direction]: "0", width: isVertical(direction) ? "100%" : 1, height: isHorizontal(direction) ? "100%" : 1, ...theme2.observer } }, direction )) }); } function Indicators({ visibility, click, arrow, indicatorsRef, handleIndicatorClick: handleIndicatorClick2, width, color, theme: theme2 }) { return /* @__PURE__ */ jsx(Fragment, { children: directions.map((direction, index) => /* @__PURE__ */ jsx( "span", { style: { display: "flex", opacity: visibility[direction] ? 1 : 0, pointerEvents: visibility[direction] ? "auto" : "none", background: `linear-gradient(to ${direction}, rgba(255, 255, 255, 0), ${color})`, transition: "opacity 300ms linear", position: "absolute", cursor: click ? "pointer" : "inherit", top: isHorizontal(direction) ? "0" : "auto", left: isVertical(direction) ? "0" : "auto", [direction]: "0", alignItems: getArrowPosition(arrow), justifyContent: getArrowPosition(arrow), width: isHorizontal(direction) ? width : "100%", height: isVertical(direction) ? width : "100%", ...theme2.indicator, ...visibility[direction] ? theme2.show && theme2.show(indicatorsRef[index]) : theme2.show && theme2.hide(indicatorsRef[index]) }, role: "button", "aria-label": `Scroll ${direction}.`, tabIndex: 0, onKeyDown: () => { }, ref: indicatorsRef[index], onClick: click ? () => handleIndicatorClick2(direction) : null, children: arrow && /* @__PURE__ */ jsx(Arrow, { ...defaultArrowProps, ...arrow, direction, theme: theme2 }) }, direction )) }); } var createDirectionRefsObject = () => directions.reduce((item, direction) => { item[direction] = useRef(); return item; }, {}); var Indicate = forwardRef( ({ as = "div", children, childAsElement, horizontal = false, vertical = false, click = { scrollDenominator: 4 }, color = "#FFFFFF", width = "20px", style, innerStyle, outerStyle, outerWrapperProps, innerWrapperProps, arrow = defaultArrowProps, hideScrollbar: hideScrollbar2 = true, className, moveStylesToWrapper = false, theme: theme2 = {}, ...props }, childRef) => { const outerWrapperRef = useRef(); const elementRef = useRef(); const innerWrapperRef = useRef(); const indicatorsRef = useRef([]); const isInline2 = getInline(as, style && style.display); const observersRef = createDirectionRefsObject(); const [visibility, setVisibility] = useState(initialVisibility(horizontal, vertical)); const sharedVisibility = useRef(visibility); let content = null; const handleIndicatorClick2 = useCallback((direction) => { const horizontalCurrent = isHorizontal(direction); const position = horizontalCurrent ? elementRef.current.scrollLeft : elementRef.current.scrollTop; const denominator = click.scrollDenominator; let scrollOffset = (horizontalCurrent ? elementRef.current.offsetWidth : elementRef.current.offsetHeight) / denominator; if (direction === "left" /* left */ || direction === "top" /* top */) { scrollOffset = -scrollOffset; } elementRef.current.scrollTo({ [horizontalCurrent ? "left" /* left */ : "top" /* top */]: position + scrollOffset, behavior: "smooth" }); }, []); if (arrow === true) { arrow = defaultArrowProps; } const handleObservation2 = useCallback( (entries) => { const visibilities = []; const newState = { ...sharedVisibility.current }; entries.forEach( (entry) => directions.forEach((direction) => { const isMatch = entry.target === observersRef[direction].current; if (isMatch) { visibilities.push({ direction, visible: entry.isIntersecting }); } }) ); visibilities.forEach((currentVisibility) => { if (currentVisibility.visible) { newState[currentVisibility.direction] = false; } else { newState[currentVisibility.direction] = true; } }); if (newState.top !== sharedVisibility.current.top || newState.right !== sharedVisibility.current.right || newState.bottom !== sharedVisibility.current.bottom || newState.left !== sharedVisibility.current.left) { sharedVisibility.current = newState; setVisibility(newState); } }, [visibility, observersRef, sharedVisibility] ); const observe2 = useCallback((element) => { const observer = new IntersectionObserver(handleObservation2, { root: element, // Only parts of element inside the root element are counted. rootMargin: "0px", // Even if only 10% of the observer is visible, trigger handler. threshold: 0.1 }); directions.forEach((direction) => { observer.observe(observersRef[direction].current); }); return () => observer.disconnect(); }, []); useEffect(() => { const element = elementRef?.current ?? childRef?.current; const disconnectObserver = observe2(element); return disconnectObserver; }, []); if (childAsElement && childrenValid(children, childRef)) { const innerChildrenModifiable = Children.toArray(children.props.children); innerChildrenModifiable.push( /* @__PURE__ */ jsx(Observers, { observersRef, theme: theme2 }, "observers") ); content = cloneElement(children, { ...props, className, children: createElement( "div", { style: { // Transferring styles from child to inner wrapper. ...!moveStylesToWrapper && children.props.style, display: "inline-flex", position: "relative", verticalAlign: "top", ...innerStyle, ...theme2.innerWrapper }, ref: innerWrapperRef, ...innerWrapperProps }, innerChildrenModifiable ), style: { position: "relative", overflow: "auto", verticalAlign: "top", ...hideScrollbar2 && { msOverflowStyle: "none", scrollbarWidth: "none" }, ...style, ...theme2.element } }); } else if (as === "table") { content = /* @__PURE__ */ jsx( "div", { ref: elementRef, style: { position: "relative", overflow: "auto", verticalAlign: "top", ...style, ...theme2.element }, children: /* @__PURE__ */ jsxs( "table", { ref: innerWrapperRef, style: { display: "inline-block", position: "relative", verticalAlign: "top", ...innerStyle, ...theme2.innerWrapper }, children: [ children, /* @__PURE__ */ jsx(Observers, { as: "tbody", observersRef, theme: theme2 }) ] } ) } ); } else if (isInline2) { content = /* @__PURE__ */ jsx( "div", { ref: elementRef, style: { ...style, display: "inline-block", overflow: "auto", verticalAlign: "top", ...theme2.element }, children: createElement( as, { ref: innerWrapperRef, style: { position: "relative", verticalAlign: "top", display: "inline-flex", ...innerStyle, ...theme2.innerWrapper } }, /* @__PURE__ */ jsxs(Fragment, { children: [ children, /* @__PURE__ */ jsx(Observers, { observersRef, theme: theme2 }) ] }) ) } ); } else { content = createElement( as, { ref: elementRef, className: getClassName(className, hideScrollbar2), style: { overflow: "auto", ...hideScrollbar2 && { msOverflowStyle: "none", scrollbarWidth: "none" }, ...style, ...theme2.element }, ...props }, /* @__PURE__ */ jsxs( "div", { style: { position: "relative", display: "inline-flex", verticalAlign: "top", ...innerStyle, ...theme2.innerWrapper }, ref: innerWrapperRef, ...innerWrapperProps, children: [ children, /* @__PURE__ */ jsx(Observers, { observersRef, theme: theme2 }) ] } ) ); } return /* @__PURE__ */ jsxs( "div", { style: { ...outerStyle, position: "relative", ...isInline2 && { display: "inline-block" }, ...theme2.outerWrapper, ...childAsElement && moveStylesToWrapper && children.props.style }, ref: outerWrapperRef, ...outerWrapperProps, children: [ hideScrollbar2 && /* @__PURE__ */ jsx("style", { children: `.${hideScrollbarClass2}::-webkit-scrollbar { display: none; }` }), content, /* @__PURE__ */ jsx( Indicators, { visibility, click, arrow, indicatorsRef, handleIndicatorClick: handleIndicatorClick2, width, color, theme: theme2 } ) ] } ); } ); export { Direction, Indicate, defaultOptions, indicate, remove }; //# sourceMappingURL=index.js.map