UNPKG

@grafana/ui

Version:
178 lines (175 loc) • 5.71 kB
import { jsx } from 'react/jsx-runtime'; import { cx, css } from '@emotion/css'; import { useRef, useEffect, useCallback } from 'react'; import Scrollbars from 'react-custom-scrollbars-2'; import { useStyles2 } from '../../themes/ThemeContext.mjs'; import { ScrollIndicators } from './ScrollIndicators.mjs'; "use strict"; const CustomScrollbar = ({ autoHide = false, autoHideTimeout = 200, setScrollTop, className, testId, autoHeightMin = "0", autoHeightMax = "100%", hideTracksWhenNotNeeded = false, hideHorizontalTrack, hideVerticalTrack, scrollRefCallback, showScrollIndicators = false, updateAfterMountMs, scrollTop, onScroll, children, divId }) => { const ref = useRef(null); const styles = useStyles2(getStyles); useEffect(() => { if (ref.current && scrollRefCallback) { scrollRefCallback(ref.current.view); } }, [ref, scrollRefCallback]); useScrollTop(ref.current, scrollTop); useEffect(() => { if (!updateAfterMountMs) { return; } setTimeout(() => { const scrollbar = ref.current; if (scrollbar == null ? void 0 : scrollbar.update) { scrollbar.update(); } }, updateAfterMountMs); }, [updateAfterMountMs]); function renderTrack(className2, hideTrack, passedProps) { if (passedProps.style && hideTrack) { passedProps.style.display = "none"; } return /* @__PURE__ */ jsx("div", { ...passedProps, className: className2 }); } const renderTrackHorizontal = useCallback( (passedProps) => { return renderTrack("track-horizontal", hideHorizontalTrack, passedProps); }, [hideHorizontalTrack] ); const renderTrackVertical = useCallback( (passedProps) => { return renderTrack("track-vertical", hideVerticalTrack, passedProps); }, [hideVerticalTrack] ); const renderThumbHorizontal = useCallback((passedProps) => { return /* @__PURE__ */ jsx("div", { ...passedProps, className: "thumb-horizontal" }); }, []); const renderThumbVertical = useCallback((passedProps) => { return /* @__PURE__ */ jsx("div", { ...passedProps, className: "thumb-vertical" }); }, []); const renderView = useCallback( (passedProps) => { if (passedProps.style && passedProps.style["WebkitOverflowScrolling"] === "touch") { passedProps.style["WebkitOverflowScrolling"] = "auto"; } return /* @__PURE__ */ jsx("div", { ...passedProps, className: "scrollbar-view", id: divId }); }, [divId] ); const onScrollStop = useCallback(() => { ref.current && setScrollTop && setScrollTop(ref.current.getValues()); }, [setScrollTop]); return /* @__PURE__ */ jsx( Scrollbars, { "data-testid": testId, ref, className: cx(styles.customScrollbar, className, { [styles.scrollbarWithScrollIndicators]: showScrollIndicators }), onScrollStop, autoHeight: true, autoHide, autoHideTimeout, hideTracksWhenNotNeeded, autoHeightMax, autoHeightMin, renderTrackHorizontal, renderTrackVertical, renderThumbHorizontal, renderThumbVertical, renderView, onScroll, children: showScrollIndicators ? /* @__PURE__ */ jsx(ScrollIndicators, { children }) : children } ); }; const getStyles = (theme) => { return { customScrollbar: css({ // Fix for Firefox. For some reason sometimes .view container gets a height of its content, but in order to // make scroll working it should fit outer container size (scroll appears only when inner container size is // greater than outer one). display: "flex", flexGrow: 1, ".scrollbar-view": { display: "flex", flexGrow: 1, flexDirection: "column" }, ".track-vertical": { borderRadius: theme.shape.borderRadius(2), width: `${theme.spacing(1)} !important`, right: 0, bottom: theme.spacing(0.25), top: theme.spacing(0.25) }, ".track-horizontal": { borderRadius: theme.shape.borderRadius(2), height: `${theme.spacing(1)} !important`, right: theme.spacing(0.25), bottom: theme.spacing(0.25), left: theme.spacing(0.25) }, ".thumb-vertical": { background: theme.colors.action.focus, borderRadius: theme.shape.borderRadius(2), opacity: 0 }, ".thumb-horizontal": { background: theme.colors.action.focus, borderRadius: theme.shape.borderRadius(2), opacity: 0 }, "&:hover": { ".thumb-vertical, .thumb-horizontal": { opacity: 1, [theme.transitions.handleMotion("no-preference", "reduce")]: { transition: "opacity 0.3s ease-in-out" } } } }), // override the scroll container position so that the scroll indicators // are positioned at the top and bottom correctly. // react-custom-scrollbars doesn't provide any way for us to hook in nicely, // so we have to override with !important. feelsbad. scrollbarWithScrollIndicators: css({ ".scrollbar-view": { // Need type assertion here due to the use of !important // see https://github.com/frenic/csstype/issues/114#issuecomment-697201978 // eslint-disable-next-line @typescript-eslint/consistent-type-assertions position: "static !important" } }) }; }; function useScrollTop(scrollBar, scrollTop) { useEffect(() => { if (scrollBar && scrollTop != null) { scrollBar.scrollTop(scrollTop); } }, [scrollTop, scrollBar]); } export { CustomScrollbar, CustomScrollbar as default }; //# sourceMappingURL=CustomScrollbar.mjs.map