@smwb/ui-react 2.1.2 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/styles/less/components/carousel/carousel.entry.css +1 -1
- package/dist/components/dataDisplay/carousel/carousel.js +169 -150
- package/dist/components/dataDisplay/carousel/carousel.js.map +1 -1
- package/dist/components/dataDisplay/chat/useChatStickToBottom.js +8 -7
- package/dist/components/dataDisplay/chat/useChatStickToBottom.js.map +1 -1
- package/dist/headless/components/dataDisplay/carousel/carousel.js +169 -150
- package/dist/headless/components/dataDisplay/carousel/carousel.js.map +1 -1
- package/dist/headless/components/dataDisplay/chat/useChatStickToBottom.js +8 -7
- package/dist/headless/components/dataDisplay/chat/useChatStickToBottom.js.map +1 -1
- package/dist/headless/hooks/useEventCallback.js +8 -7
- package/dist/headless/hooks/useEventCallback.js.map +1 -1
- package/dist/headless/hooks/useTheme.js +16 -15
- package/dist/headless/hooks/useTheme.js.map +1 -1
- package/dist/hooks/useEventCallback.js +8 -7
- package/dist/hooks/useEventCallback.js.map +1 -1
- package/dist/hooks/useTheme.js +16 -15
- package/dist/hooks/useTheme.js.map +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"carousel.js","sources":["../../../../src/components/dataDisplay/carousel/carousel.tsx"],"sourcesContent":["import React, { forwardRef, ReactNode, useEffect, useId, useRef, useState } from \"react\";\nimport cn from \"clsx\";\nimport { Icon } from \"../../base/icon\";\nimport { Modal } from \"../../feedBack/modal\";\nimport { useForkRef } from \"../../../hooks/useForkRef\";\nimport {\n clamp,\n coordX,\n coordY,\n dragPrevent,\n getSlideIndexForMultipleParts,\n getSlidesToShow,\n getSlideStyle,\n getSlideWidth,\n getStartSlide,\n isMouseEvent,\n isTouchEvent,\n toCssLength,\n toCssNumber,\n} from \"./utils\";\nimport { useSafeLayoutEffect } from \"../../../hooks/useSafeLayoutEffect\";\nimport { useEventCallback } from \"../../../hooks/useEventCallback\";\n\nexport interface CarouselProps extends React.PropsWithChildren {\n slidesToShow?: number;\n startSlide?: number;\n className?: string;\n showNavigation?: boolean;\n showArrows?: boolean;\n arrowsSize?: number;\n navigationClassName?: string;\n onSlideChange?: (slideIndex: number) => void;\n navigationDotRenderer?: (index: number, isActive: boolean, onClick: (index: number) => void) => ReactNode;\n /** Accessible label for the carousel region. */\n \"aria-label\"?: string;\n /** Advance slides automatically. */\n autoplay?: boolean;\n /** Autoplay interval in ms. */\n autoplayInterval?: number;\n /** Pause autoplay while the pointer is over the carousel. */\n pauseOnHover?: boolean;\n /** Height of each cell/photo. Number is treated as px. Overrides the default 205px. */\n cellHeight?: number | string;\n /** Aspect ratio of each cell/photo (e.g. 0.9 or \"16 / 9\"). Overrides the default 0.9. */\n aspectRatio?: number | string;\n /** Per-side spacing around each slide. Number is treated as px (default 4). */\n gap?: number | string;\n /** Max width of the carousel. Number is treated as px (default 412). */\n maxWidth?: number | string;\n /** Open the clicked slide in a fullscreen lightbox (arrows / swipe / Esc to navigate & close). */\n enableFullscreen?: boolean;\n}\n\ninterface ShiftState {\n animation: boolean | undefined;\n}\n\ntype Axis = \"x\" | \"y\" | null;\n\ninterface Motion {\n isPressed: boolean;\n startX: number;\n startY: number;\n lastX: number;\n lastT: number;\n axis: Axis;\n dragged: boolean;\n}\n\nconst MOTION_INITIAL_STATE: Motion = {\n isPressed: false,\n startX: 0,\n startY: 0,\n lastX: 0,\n lastT: 0,\n axis: null,\n dragged: false,\n};\n\n// Movement (px) below which a pointer interaction is treated as a tap, not a drag.\nconst TAP_THRESHOLD = 8;\n// Flick velocity (px/ms) above which we advance a slide even on a short drag.\nconst FLICK_VELOCITY = 0.4;\n\nexport const Carousel = forwardRef<HTMLDivElement, CarouselProps>(function Carousel(\n {\n slidesToShow: slidesToShowProp = 3,\n startSlide: startSlideProp = 0,\n children,\n className,\n showNavigation = true,\n showArrows: showArrowsProp,\n arrowsSize = 30,\n navigationClassName,\n onSlideChange,\n navigationDotRenderer,\n \"aria-label\": ariaLabel = \"Carousel\",\n autoplay = false,\n autoplayInterval = 4000,\n pauseOnHover = true,\n cellHeight,\n aspectRatio,\n gap,\n maxWidth,\n enableFullscreen = false,\n },\n ref\n) {\n const slidesCount = React.Children.count(children);\n const slidesToShow = getSlidesToShow(slidesToShowProp, slidesCount);\n const startSlide = getStartSlide(startSlideProp, slidesCount);\n const showArrows = showArrowsProp && slidesCount > 1;\n const maxShift = Math.max(0, slidesCount - slidesToShow);\n\n const [activeSlideIndex, setActiveSlideIndex] = useState<number>(startSlide);\n const [shiftState, setShiftState] = useState<ShiftState>({\n animation: undefined,\n });\n // Live pointer-follow offset (px) applied on top of the resting %-based indent.\n const [dragPx, setDragPx] = useState<number>(0);\n const [isDragging, setIsDragging] = useState<boolean>(false);\n const [fullscreenIndex, setFullscreenIndex] = useState<number | null>(null);\n\n const rootRef = useRef<HTMLDivElement>(null);\n const outerRef = useRef<HTMLDivElement>(null);\n const forkedOuterRef = useForkRef<HTMLDivElement>(ref, outerRef);\n const trackRef = useRef<HTMLDivElement>(null);\n const [isHovered, setIsHovered] = useState<boolean>(false);\n\n const motion = useRef<Motion>({ ...MOTION_INITIAL_STATE });\n\n useSafeLayoutEffect(() => {\n setShiftState((prevState) => ({\n ...prevState,\n animation: false,\n }));\n }, [slidesToShow]);\n\n useSafeLayoutEffect(() => {\n setActiveSlideIndex(startSlide);\n onSlideChange?.(startSlide);\n\n if (shiftState.animation !== undefined) {\n setShiftState((prevState) => ({\n ...prevState,\n animation: true,\n }));\n }\n }, [startSlide]);\n\n const setMotion = (value: Partial<Motion>) => {\n Object.assign<Motion, Partial<Motion>>(motion.current, value);\n };\n\n const now = () => (typeof performance !== \"undefined\" ? performance.now() : Date.now());\n\n const goToSlide = (index: number) => {\n const target = clamp(index, 0, maxShift);\n\n setActiveSlideIndex(target);\n setShiftState((prevState) => ({ ...prevState, animation: true }));\n onSlideChange?.(target);\n };\n\n const moveFullscreen = (direction: 1 | -1) => {\n setFullscreenIndex((prev) => (prev === null ? prev : (prev + direction + slidesCount) % slidesCount));\n };\n\n const fullscreenTouchX = useRef<number | null>(null);\n\n const detachListeners = (isMouse: boolean) => {\n if (!trackRef.current) {\n return;\n }\n\n trackRef.current.removeEventListener(isMouse ? \"mousemove\" : \"touchmove\", onMove);\n trackRef.current.removeEventListener(isMouse ? \"mouseup\" : \"touchend\", onEnd);\n\n if (isMouse) {\n trackRef.current.removeEventListener(\"mouseleave\", onEnd);\n }\n };\n\n const onStart = useEventCallback((event: React.MouseEvent<HTMLDivElement> | React.TouchEvent<HTMLDivElement>) => {\n if (!trackRef.current) {\n return;\n }\n\n const isMouse = isMouseEvent(event);\n\n if (isMouse && event.button !== 0) {\n return;\n }\n\n event.stopPropagation();\n\n const clientX = coordX(event);\n const clientY = coordY(event);\n\n setMotion({\n isPressed: true,\n startX: clientX,\n startY: clientY,\n lastX: clientX,\n lastT: now(),\n axis: null,\n dragged: false,\n });\n\n trackRef.current.addEventListener(isMouse ? \"mousemove\" : \"touchmove\", onMove, { passive: false });\n trackRef.current.addEventListener(isMouse ? \"mouseup\" : \"touchend\", onEnd);\n\n if (isMouse) {\n trackRef.current.addEventListener(\"mouseleave\", onEnd);\n }\n });\n\n const onMove = useEventCallback((event: MouseEvent | TouchEvent) => {\n if (!rootRef.current || !motion.current.isPressed) {\n return;\n }\n\n if (isTouchEvent(event) && event.touches.length > 1) {\n return onEnd(event);\n }\n\n const clientX = coordX(event);\n const clientY = coordY(event);\n const shiftX = clientX - motion.current.startX;\n const shiftY = clientY - motion.current.startY;\n\n // Lock the gesture axis once the pointer has moved past the tap threshold.\n if (motion.current.axis === null) {\n if (Math.abs(shiftX) < TAP_THRESHOLD && Math.abs(shiftY) < TAP_THRESHOLD) {\n return;\n }\n\n const axis: Axis = Math.abs(shiftX) >= Math.abs(shiftY) ? \"x\" : \"y\";\n setMotion({ axis, dragged: true });\n\n // Vertical intent → release so the page can scroll.\n if (axis === \"y\") {\n return onEnd(event);\n }\n\n if (slidesCount > 1) {\n setIsDragging(true);\n }\n }\n\n if (motion.current.axis !== \"x\") {\n return;\n }\n\n // Horizontal drag: keep the gesture and follow the finger.\n event.preventDefault();\n event.stopPropagation();\n\n if (slidesCount > 1) {\n const atStart = activeSlideIndex <= 0;\n const atEnd = activeSlideIndex >= maxShift;\n // Add resistance when dragging beyond the first / last slide.\n const offset = (atStart && shiftX > 0) || (atEnd && shiftX < 0) ? shiftX * 0.35 : shiftX;\n setDragPx(offset);\n }\n\n motion.current.lastX = clientX;\n motion.current.lastT = now();\n });\n\n const onEnd = useEventCallback((event: MouseEvent | TouchEvent) => {\n if (!motion.current.isPressed) {\n return;\n }\n\n const isMouse = isMouseEvent(event);\n detachListeners(isMouse);\n\n const { axis, dragged, startX, lastX, lastT } = motion.current;\n setMotion({ isPressed: false });\n setIsDragging(false);\n\n if (axis === \"x\" && dragged && slidesCount > 1 && rootRef.current) {\n const clientX = coordX(event);\n const totalShift = clientX - startX;\n const widthPerSlide = rootRef.current.offsetWidth / slidesToShow;\n const velocity = lastT ? (clientX - lastX) / Math.max(1, now() - lastT) : 0;\n\n let movedSlides = widthPerSlide > 0 ? Math.round(-totalShift / widthPerSlide) : 0;\n\n if (movedSlides === 0 && Math.abs(velocity) > FLICK_VELOCITY) {\n movedSlides = velocity < 0 ? 1 : -1;\n }\n\n goToSlide(activeSlideIndex + movedSlides);\n }\n\n // Animate back to the resting position (snap / snap-back).\n setDragPx(0);\n });\n\n const onSlideClick = (index: number) => () => {\n // Suppress the click that fires at the end of a drag.\n if (motion.current.dragged) {\n return;\n }\n\n if (enableFullscreen) {\n setFullscreenIndex(index);\n }\n };\n\n const onNavigationItemClick = (index: number) => () => goToSlide(index);\n\n const getNextIndex = (direction: 1 | -1) => {\n const isSingleSlide = slidesToShow === 1;\n const totalGroups = isSingleSlide ? slidesCount : Math.ceil(slidesCount / slidesToShow);\n const activeIndex = activeSlideIndex + slidesToShow;\n const isNextSlideDisabled = slidesCount - slidesToShow <= activeSlideIndex;\n\n const currentIndex = getSlideIndexForMultipleParts(activeIndex, slidesToShow, slidesCount, isNextSlideDisabled);\n const nextIndex = (currentIndex + direction + totalGroups) % totalGroups;\n\n return isSingleSlide ? nextIndex : nextIndex * slidesToShow;\n };\n\n const getNavigation = () => {\n if (!showNavigation) {\n return <></>;\n }\n\n const isNextSlideDisabled = slidesCount - slidesToShow <= activeSlideIndex;\n const isSinglePartSlide = slidesToShow === 1;\n const count = isSinglePartSlide ? slidesCount : Math.ceil(slidesCount / slidesToShow);\n const indicators: React.ReactNode[] = [];\n\n for (let index = 0; index < count; index++) {\n let nextIndex = index;\n let currentIndex = activeSlideIndex;\n\n if (!isSinglePartSlide) {\n const isLast = index === count - 1;\n const activeIndex = activeSlideIndex + slidesToShow;\n\n nextIndex = isLast ? slidesCount - slidesToShow : index * slidesToShow;\n currentIndex = getSlideIndexForMultipleParts(activeIndex, slidesToShow, slidesCount, isNextSlideDisabled);\n }\n\n const isActive = currentIndex === index;\n const onClick = onNavigationItemClick(nextIndex);\n\n let indicator: ReactNode = (\n <div key={index} className={cn(\"smwb-carousel__navigation__dot\", isActive && \"current\")} onClick={onClick} />\n );\n\n if (navigationDotRenderer) {\n indicator = navigationDotRenderer(index, isActive, onClick);\n }\n\n indicators.push(indicator);\n }\n\n return <div className={cn(\"smwb-carousel__navigation\", navigationClassName)}>{indicators}</div>;\n };\n\n const getIndent = () => {\n const shiftSlides = activeSlideIndex > maxShift ? maxShift : activeSlideIndex;\n\n return getSlideWidth(slidesToShow) * shiftSlides;\n };\n\n const slideId = useId();\n const slideStyle = getSlideStyle(slidesToShow);\n\n const indent = getIndent();\n\n const layerStyle: React.CSSProperties = {\n transform: `translateX(calc(-${indent}% + ${dragPx}px))`,\n transition:\n isDragging || shiftState.animation === undefined\n ? \"none\"\n : shiftState.animation\n ? \"transform 500ms cubic-bezier(.1, 0, .25, 1)\"\n : \"none\",\n };\n\n const rootStyle: React.CSSProperties = {};\n const cellHeightValue = toCssLength(cellHeight);\n const aspectRatioValue = toCssNumber(aspectRatio);\n const gapValue = toCssLength(gap);\n const maxWidthValue = toCssLength(maxWidth);\n if (cellHeightValue) (rootStyle as Record<string, string>)[\"--smwb-carousel-cell-height\"] = cellHeightValue;\n if (aspectRatioValue) (rootStyle as Record<string, string>)[\"--smwb-carousel-aspect-ratio\"] = aspectRatioValue;\n if (gapValue) (rootStyle as Record<string, string>)[\"--smwb-carousel-gap\"] = gapValue;\n if (maxWidthValue) (rootStyle as Record<string, string>)[\"--smwb-carousel-max-width\"] = maxWidthValue;\n\n React.useEffect(() => {\n if (!Array.isArray(children)) {\n console.error(\"SMWB Material: The `children` prop was passed invalidly. It should contain an array of elements.\");\n }\n }, [children]);\n\n useEffect(() => {\n if (!autoplay || slidesCount <= 1 || (pauseOnHover && isHovered) || fullscreenIndex !== null) {\n return;\n }\n const timer = window.setInterval(() => {\n onNavigationItemClick(getNextIndex(1))();\n }, autoplayInterval);\n\n return () => window.clearInterval(timer);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n autoplay,\n autoplayInterval,\n pauseOnHover,\n isHovered,\n slidesCount,\n activeSlideIndex,\n slidesToShow,\n fullscreenIndex,\n ]);\n\n useEffect(() => {\n if (fullscreenIndex === null || slidesCount <= 1) {\n return;\n }\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"ArrowLeft\") {\n moveFullscreen(-1);\n } else if (event.key === \"ArrowRight\") {\n moveFullscreen(1);\n }\n };\n document.addEventListener(\"keydown\", onKeyDown);\n\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [fullscreenIndex, slidesCount]);\n\n if (!Array.isArray(children)) {\n return <></>;\n }\n\n const childrenArray = children as ReactNode[];\n\n const onFullscreenTouchStart = (event: React.TouchEvent) => {\n fullscreenTouchX.current = event.touches[0]?.clientX ?? null;\n };\n\n const onFullscreenTouchEnd = (event: React.TouchEvent) => {\n if (fullscreenTouchX.current === null || slidesCount <= 1) {\n return;\n }\n const delta = (event.changedTouches[0]?.clientX ?? fullscreenTouchX.current) - fullscreenTouchX.current;\n fullscreenTouchX.current = null;\n if (Math.abs(delta) > 40) {\n moveFullscreen(delta < 0 ? 1 : -1);\n }\n };\n\n return (\n <div\n className={cn(\"smwb-carousel\", className)}\n data-testid=\"carousel\"\n ref={forkedOuterRef}\n role=\"region\"\n aria-roledescription=\"carousel\"\n aria-label={ariaLabel}\n style={rootStyle}\n onMouseEnter={pauseOnHover ? () => setIsHovered(true) : undefined}\n onMouseLeave={pauseOnHover ? () => setIsHovered(false) : undefined}\n >\n <div className={cn(\"smwb-carousel__inner\")} ref={rootRef}>\n {showArrows && (\n <Icon\n name=\"chevron_left\"\n size={arrowsSize}\n className={cn(\"smwb-carousel__arrow\", \"smwb-carousel__arrow_prev\")}\n style={{\n top: `calc(50% - ${arrowsSize / 2}px)`,\n left: -arrowsSize / 2,\n }}\n onClick={() => onNavigationItemClick(getNextIndex(-1))()}\n />\n )}\n <div\n ref={trackRef}\n className=\"smwb-carousel__track\"\n onMouseDown={onStart}\n onTouchStart={onStart}\n onDragStart={dragPrevent}\n onDragEnd={dragPrevent}\n >\n <div className=\"smwb-carousel__layer\" style={layerStyle}>\n {React.Children.map(children, (child, index) => (\n <div key={index} id={`${slideId}${index}`} className=\"smwb-carousel__slide\" style={slideStyle}>\n <div\n className={cn(\n \"smwb-carousel__slide-inner\",\n enableFullscreen && \"smwb-carousel__slide-inner_clickable\"\n )}\n onClick={enableFullscreen ? onSlideClick(index) : undefined}\n >\n {child}\n </div>\n </div>\n ))}\n </div>\n </div>\n {showArrows && (\n <Icon\n name=\"chevron_right\"\n size={arrowsSize}\n className={cn(\"smwb-carousel__arrow\", \"smwb-carousel__arrow_next\")}\n style={{\n top: `calc(50% - ${arrowsSize / 2}px)`,\n right: -arrowsSize / 2,\n }}\n onClick={() => onNavigationItemClick(getNextIndex(1))()}\n />\n )}\n </div>\n {getNavigation()}\n {enableFullscreen && (\n <Modal\n open={fullscreenIndex !== null}\n size=\"fullscreen\"\n backdrop=\"darkBlured\"\n className=\"smwb-carousel__fullscreen\"\n onClose={() => setFullscreenIndex(null)}\n aria-label=\"Image viewer\"\n >\n {fullscreenIndex !== null && (\n <div className=\"smwb-carousel__fullscreen-content\">\n {slidesCount > 1 && (\n <Icon\n name=\"chevron_left\"\n size={40}\n className={cn(\"smwb-carousel__fullscreen-arrow\", \"smwb-carousel__fullscreen-arrow_prev\")}\n onClick={() => moveFullscreen(-1)}\n />\n )}\n <div\n className=\"smwb-carousel__fullscreen-stage\"\n onTouchStart={onFullscreenTouchStart}\n onTouchEnd={onFullscreenTouchEnd}\n >\n {childrenArray[fullscreenIndex]}\n </div>\n {slidesCount > 1 && (\n <Icon\n name=\"chevron_right\"\n size={40}\n className={cn(\"smwb-carousel__fullscreen-arrow\", \"smwb-carousel__fullscreen-arrow_next\")}\n onClick={() => moveFullscreen(1)}\n />\n )}\n <Icon\n name=\"close\"\n size={32}\n className=\"smwb-carousel__fullscreen-close\"\n onClick={() => setFullscreenIndex(null)}\n />\n </div>\n )}\n </Modal>\n )}\n </div>\n );\n});\n\nexport default Carousel;\n"],"names":["MOTION_INITIAL_STATE","TAP_THRESHOLD","FLICK_VELOCITY","Carousel","forwardRef","slidesToShowProp","startSlideProp","children","className","showNavigation","showArrowsProp","arrowsSize","navigationClassName","onSlideChange","navigationDotRenderer","ariaLabel","autoplay","autoplayInterval","pauseOnHover","cellHeight","aspectRatio","gap","maxWidth","enableFullscreen","ref","slidesCount","React","slidesToShow","getSlidesToShow","startSlide","getStartSlide","showArrows","maxShift","activeSlideIndex","setActiveSlideIndex","useState","shiftState","setShiftState","dragPx","setDragPx","isDragging","setIsDragging","fullscreenIndex","setFullscreenIndex","rootRef","useRef","outerRef","forkedOuterRef","useForkRef","trackRef","isHovered","setIsHovered","motion","useSafeLayoutEffect","prevState","setMotion","value","now","goToSlide","index","target","clamp","moveFullscreen","direction","prev","fullscreenTouchX","detachListeners","isMouse","onMove","onEnd","onStart","useEventCallback","event","isMouseEvent","clientX","coordX","clientY","coordY","isTouchEvent","shiftX","shiftY","axis","atStart","atEnd","offset","dragged","startX","lastX","lastT","totalShift","widthPerSlide","velocity","movedSlides","onSlideClick","onNavigationItemClick","getNextIndex","isSingleSlide","totalGroups","activeIndex","isNextSlideDisabled","nextIndex","getSlideIndexForMultipleParts","getNavigation","jsx","Fragment","isSinglePartSlide","count","indicators","currentIndex","isLast","isActive","onClick","indicator","cn","getIndent","shiftSlides","getSlideWidth","slideId","useId","slideStyle","getSlideStyle","layerStyle","rootStyle","cellHeightValue","toCssLength","aspectRatioValue","toCssNumber","gapValue","maxWidthValue","useEffect","timer","onKeyDown","childrenArray","onFullscreenTouchStart","_b","_a","onFullscreenTouchEnd","delta","jsxs","Icon","dragPrevent","child","Modal"],"mappings":";;;;;;;;;;AAsEA,MAAMA,KAA+B;AAAA,EACnC,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AACX,GAGMC,KAAgB,GAEhBC,KAAiB,KAEVC,KAAWC,GAA0C,SAChE;AAAA,EACE,cAAcC,KAAmB;AAAA,EACjC,YAAYC,KAAiB;AAAA,EAC7B,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,gBAAAC,KAAiB;AAAA,EACjB,YAAYC;AAAA,EACZ,YAAAC,IAAa;AAAA,EACb,qBAAAC;AAAA,EACA,eAAAC;AAAA,EACA,uBAAAC;AAAA,EACA,cAAcC,KAAY;AAAA,EAC1B,UAAAC,IAAW;AAAA,EACX,kBAAAC,IAAmB;AAAA,EACnB,cAAAC,IAAe;AAAA,EACf,YAAAC;AAAA,EACA,aAAAC;AAAA,EACA,KAAAC;AAAA,EACA,UAAAC;AAAA,EACA,kBAAAC,IAAmB;AACrB,GACAC,IACA;AACA,QAAMC,IAAcC,EAAM,SAAS,MAAMnB,CAAQ,GAC3CoB,IAAeC,GAAgBvB,IAAkBoB,CAAW,GAC5DI,IAAaC,GAAcxB,IAAgBmB,CAAW,GACtDM,IAAarB,MAAkBe,IAAc,GAC7CO,IAAW,KAAK,IAAI,GAAGP,IAAcE,CAAY,GAEjD,CAACM,GAAkBC,CAAmB,IAAIC,EAAiBN,CAAU,GACrE,CAACO,GAAYC,CAAa,IAAIF,EAAqB;AAAA,IACvD,WAAW;AAAA,EAAA,CACZ,GAEK,CAACG,IAAQC,CAAS,IAAIJ,EAAiB,CAAC,GACxC,CAACK,IAAYC,CAAa,IAAIN,EAAkB,EAAK,GACrD,CAACO,GAAiBC,CAAkB,IAAIR,EAAwB,IAAI,GAEpES,IAAUC,EAAuB,IAAI,GACrCC,KAAWD,EAAuB,IAAI,GACtCE,KAAiBC,GAA2BxB,IAAKsB,EAAQ,GACzDG,IAAWJ,EAAuB,IAAI,GACtC,CAACK,IAAWC,EAAY,IAAIhB,EAAkB,EAAK,GAEnDiB,IAASP,EAAe,EAAE,GAAG7C,IAAsB;AAEzD,EAAAqD,GAAoB,MAAM;AACxB,IAAAhB,EAAc,CAACiB,OAAe;AAAA,MAC5B,GAAGA;AAAA,MACH,WAAW;AAAA,IAAA,EACX;AAAA,EACJ,GAAG,CAAC3B,CAAY,CAAC,GAEjB0B,GAAoB,MAAM;AACxB,IAAAnB,EAAoBL,CAAU,GAC9BhB,KAAA,QAAAA,EAAgBgB,IAEZO,EAAW,cAAc,UAC3BC,EAAc,CAACiB,OAAe;AAAA,MAC5B,GAAGA;AAAA,MACH,WAAW;AAAA,IAAA,EACX;AAAA,EAEN,GAAG,CAACzB,CAAU,CAAC;AAEf,QAAM0B,IAAY,CAACC,MAA2B;AAC5C,WAAO,OAAgCJ,EAAO,SAASI,CAAK;AAAA,EAC9D,GAEMC,IAAM,MAAO,OAAO,eAAgB,cAAc,YAAY,IAAA,IAAQ,KAAK,IAAA,GAE3EC,KAAY,CAACC,MAAkB;AACnC,UAAMC,IAASC,GAAMF,GAAO,GAAG3B,CAAQ;AAEvC,IAAAE,EAAoB0B,CAAM,GAC1BvB,EAAc,CAACiB,OAAe,EAAE,GAAGA,GAAW,WAAW,KAAO,GAChEzC,KAAA,QAAAA,EAAgB+C;AAAA,EAClB,GAEME,IAAiB,CAACC,MAAsB;AAC5C,IAAApB,EAAmB,CAACqB,MAAUA,MAAS,OAAOA,KAAQA,IAAOD,IAAYtC,KAAeA,CAAY;AAAA,EACtG,GAEMwC,IAAmBpB,EAAsB,IAAI,GAE7CqB,KAAkB,CAACC,MAAqB;AAC5C,IAAKlB,EAAS,YAIdA,EAAS,QAAQ,oBAAoBkB,IAAU,cAAc,aAAaC,EAAM,GAChFnB,EAAS,QAAQ,oBAAoBkB,IAAU,YAAY,YAAYE,CAAK,GAExEF,KACFlB,EAAS,QAAQ,oBAAoB,cAAcoB,CAAK;AAAA,EAE5D,GAEMC,KAAUC,EAAiB,CAACC,MAA+E;AAC/G,QAAI,CAACvB,EAAS;AACZ;AAGF,UAAMkB,IAAUM,GAAaD,CAAK;AAElC,QAAIL,KAAWK,EAAM,WAAW;AAC9B;AAGF,IAAAA,EAAM,gBAAA;AAEN,UAAME,IAAUC,EAAOH,CAAK,GACtBI,IAAUC,GAAOL,CAAK;AAE5B,IAAAjB,EAAU;AAAA,MACR,WAAW;AAAA,MACX,QAAQmB;AAAA,MACR,QAAQE;AAAA,MACR,OAAOF;AAAA,MACP,OAAOjB,EAAA;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,IAAA,CACV,GAEDR,EAAS,QAAQ,iBAAiBkB,IAAU,cAAc,aAAaC,IAAQ,EAAE,SAAS,IAAO,GACjGnB,EAAS,QAAQ,iBAAiBkB,IAAU,YAAY,YAAYE,CAAK,GAErEF,KACFlB,EAAS,QAAQ,iBAAiB,cAAcoB,CAAK;AAAA,EAEzD,CAAC,GAEKD,KAASG,EAAiB,CAACC,MAAmC;AAClE,QAAI,CAAC5B,EAAQ,WAAW,CAACQ,EAAO,QAAQ;AACtC;AAGF,QAAI0B,GAAaN,CAAK,KAAKA,EAAM,QAAQ,SAAS;AAChD,aAAOH,EAAMG,CAAK;AAGpB,UAAME,IAAUC,EAAOH,CAAK,GACtBI,IAAUC,GAAOL,CAAK,GACtBO,IAASL,IAAUtB,EAAO,QAAQ,QAClC4B,IAASJ,IAAUxB,EAAO,QAAQ;AAGxC,QAAIA,EAAO,QAAQ,SAAS,MAAM;AAChC,UAAI,KAAK,IAAI2B,CAAM,IAAI9E,MAAiB,KAAK,IAAI+E,CAAM,IAAI/E;AACzD;AAGF,YAAMgF,IAAa,KAAK,IAAIF,CAAM,KAAK,KAAK,IAAIC,CAAM,IAAI,MAAM;AAIhE,UAHAzB,EAAU,EAAE,MAAA0B,GAAM,SAAS,GAAA,CAAM,GAG7BA,MAAS;AACX,eAAOZ,EAAMG,CAAK;AAGpB,MAAI/C,IAAc,KAChBgB,EAAc,EAAI;AAAA,IAEtB;AAEA,QAAIW,EAAO,QAAQ,SAAS,KAQ5B;AAAA,UAHAoB,EAAM,eAAA,GACNA,EAAM,gBAAA,GAEF/C,IAAc,GAAG;AACnB,cAAMyD,IAAUjD,KAAoB,GAC9BkD,IAAQlD,KAAoBD,GAE5BoD,IAAUF,KAAWH,IAAS,KAAOI,KAASJ,IAAS,IAAKA,IAAS,OAAOA;AAClF,QAAAxC,EAAU6C,CAAM;AAAA,MAClB;AAEA,MAAAhC,EAAO,QAAQ,QAAQsB,GACvBtB,EAAO,QAAQ,QAAQK,EAAA;AAAA;AAAA,EACzB,CAAC,GAEKY,IAAQE,EAAiB,CAACC,MAAmC;AACjE,QAAI,CAACpB,EAAO,QAAQ;AAClB;AAGF,UAAMe,IAAUM,GAAaD,CAAK;AAClC,IAAAN,GAAgBC,CAAO;AAEvB,UAAM,EAAE,MAAAc,GAAM,SAAAI,GAAS,QAAAC,GAAQ,OAAAC,GAAO,OAAAC,EAAA,IAAUpC,EAAO;AAIvD,QAHAG,EAAU,EAAE,WAAW,IAAO,GAC9Bd,EAAc,EAAK,GAEfwC,MAAS,OAAOI,KAAW5D,IAAc,KAAKmB,EAAQ,SAAS;AACjE,YAAM8B,IAAUC,EAAOH,CAAK,GACtBiB,IAAaf,IAAUY,GACvBI,IAAgB9C,EAAQ,QAAQ,cAAcjB,GAC9CgE,IAAWH,KAASd,IAAUa,KAAS,KAAK,IAAI,GAAG9B,MAAQ+B,CAAK,IAAI;AAE1E,UAAII,IAAcF,IAAgB,IAAI,KAAK,MAAM,CAACD,IAAaC,CAAa,IAAI;AAEhF,MAAIE,MAAgB,KAAK,KAAK,IAAID,CAAQ,IAAIzF,OAC5C0F,IAAcD,IAAW,IAAI,IAAI,KAGnCjC,GAAUzB,IAAmB2D,CAAW;AAAA,IAC1C;AAGA,IAAArD,EAAU,CAAC;AAAA,EACb,CAAC,GAEKsD,KAAe,CAAClC,MAAkB,MAAM;AAE5C,IAAIP,EAAO,QAAQ,WAIf7B,KACFoB,EAAmBgB,CAAK;AAAA,EAE5B,GAEMmC,IAAwB,CAACnC,MAAkB,MAAMD,GAAUC,CAAK,GAEhEoC,IAAe,CAAChC,MAAsB;AAC1C,UAAMiC,IAAgBrE,MAAiB,GACjCsE,IAAcD,IAAgBvE,IAAc,KAAK,KAAKA,IAAcE,CAAY,GAChFuE,IAAcjE,IAAmBN,GACjCwE,IAAsB1E,IAAcE,KAAgBM,GAGpDmE,KADeC,GAA8BH,GAAavE,GAAcF,GAAa0E,CAAmB,IAC5EpC,IAAYkC,KAAeA;AAE7D,WAAOD,IAAgBI,IAAYA,IAAYzE;AAAA,EACjD,GAEM2E,KAAgB,MAAM;AAC1B,QAAI,CAAC7F;AACH,aAAO,gBAAA8F,EAAAC,IAAA,EAAE;AAGX,UAAML,IAAsB1E,IAAcE,KAAgBM,GACpDwE,IAAoB9E,MAAiB,GACrC+E,IAAQD,IAAoBhF,IAAc,KAAK,KAAKA,IAAcE,CAAY,GAC9EgF,IAAgC,CAAA;AAEtC,aAAShD,IAAQ,GAAGA,IAAQ+C,GAAO/C,KAAS;AAC1C,UAAIyC,IAAYzC,GACZiD,IAAe3E;AAEnB,UAAI,CAACwE,GAAmB;AACtB,cAAMI,IAASlD,MAAU+C,IAAQ,GAC3BR,IAAcjE,IAAmBN;AAEvC,QAAAyE,IAAYS,IAASpF,IAAcE,IAAegC,IAAQhC,GAC1DiF,IAAeP,GAA8BH,GAAavE,GAAcF,GAAa0E,CAAmB;AAAA,MAC1G;AAEA,YAAMW,IAAWF,MAAiBjD,GAC5BoD,IAAUjB,EAAsBM,CAAS;AAE/C,UAAIY,IACF,gBAAAT,EAAC,OAAA,EAAgB,WAAWU,EAAG,kCAAkCH,KAAY,SAAS,GAAG,SAAAC,EAAA,GAA/EpD,CAAiG;AAG7G,MAAI7C,MACFkG,IAAYlG,EAAsB6C,GAAOmD,GAAUC,CAAO,IAG5DJ,EAAW,KAAKK,CAAS;AAAA,IAC3B;AAEA,6BAAQ,OAAA,EAAI,WAAWC,EAAG,6BAA6BrG,EAAmB,GAAI,UAAA+F,GAAW;AAAA,EAC3F,GAEMO,KAAY,MAAM;AACtB,UAAMC,IAAclF,IAAmBD,IAAWA,IAAWC;AAE7D,WAAOmF,GAAczF,CAAY,IAAIwF;AAAA,EACvC,GAEME,KAAUC,GAAA,GACVC,KAAaC,GAAc7F,CAAY,GAIvC8F,KAAkC;AAAA,IACtC,WAAW,oBAHEP,GAAA,CAGwB,OAAO5E,EAAM;AAAA,IAClD,YACEE,MAAcJ,EAAW,cAAc,SACnC,SACAA,EAAW,YACT,gDACA;AAAA,EAAA,GAGJsF,IAAiC,CAAA,GACjCC,KAAkBC,EAAYzG,EAAU,GACxC0G,KAAmBC,GAAY1G,EAAW,GAC1C2G,KAAWH,EAAYvG,EAAG,GAC1B2G,KAAgBJ,EAAYtG,EAAQ;AAkD1C,MAjDIqG,OAAkBD,EAAqC,6BAA6B,IAAIC,KACxFE,OAAmBH,EAAqC,8BAA8B,IAAIG,KAC1FE,OAAWL,EAAqC,qBAAqB,IAAIK,KACzEC,OAAgBN,EAAqC,2BAA2B,IAAIM,KAExFtG,EAAM,UAAU,MAAM;AACpB,IAAK,MAAM,QAAQnB,CAAQ,KACzB,QAAQ,MAAM,kGAAkG;AAAA,EAEpH,GAAG,CAACA,CAAQ,CAAC,GAEb0H,GAAU,MAAM;AACd,QAAI,CAACjH,KAAYS,KAAe,KAAMP,KAAgBgC,MAAcR,MAAoB;AACtF;AAEF,UAAMwF,IAAQ,OAAO,YAAY,MAAM;AACrC,MAAApC,EAAsBC,EAAa,CAAC,CAAC,EAAA;AAAA,IACvC,GAAG9E,CAAgB;AAEnB,WAAO,MAAM,OAAO,cAAciH,CAAK;AAAA,EAEzC,GAAG;AAAA,IACDlH;AAAA,IACAC;AAAA,IACAC;AAAA,IACAgC;AAAA,IACAzB;AAAA,IACAQ;AAAA,IACAN;AAAA,IACAe;AAAA,EAAA,CACD,GAEDuF,GAAU,MAAM;AACd,QAAIvF,MAAoB,QAAQjB,KAAe;AAC7C;AAEF,UAAM0G,IAAY,CAAC3D,MAAyB;AAC1C,MAAIA,EAAM,QAAQ,cAChBV,EAAe,EAAE,IACRU,EAAM,QAAQ,gBACvBV,EAAe,CAAC;AAAA,IAEpB;AACA,oBAAS,iBAAiB,WAAWqE,CAAS,GAEvC,MAAM,SAAS,oBAAoB,WAAWA,CAAS;AAAA,EAEhE,GAAG,CAACzF,GAAiBjB,CAAW,CAAC,GAE7B,CAAC,MAAM,QAAQlB,CAAQ;AACzB,WAAO,gBAAAgG,EAAAC,IAAA,EAAE;AAGX,QAAM4B,KAAgB7H,GAEhB8H,KAAyB,CAAC7D,MAA4B;;AAC1D,IAAAP,EAAiB,WAAUqE,KAAAC,IAAA/D,EAAM,QAAQ,CAAC,MAAf,gBAAA+D,EAAkB,YAAlB,OAAAD,IAA6B;AAAA,EAC1D,GAEME,KAAuB,CAAChE,MAA4B;;AACxD,QAAIP,EAAiB,YAAY,QAAQxC,KAAe;AACtD;AAEF,UAAMgH,MAASH,KAAAC,IAAA/D,EAAM,eAAe,CAAC,MAAtB,gBAAA+D,EAAyB,YAAzB,OAAAD,IAAoCrE,EAAiB,WAAWA,EAAiB;AAChG,IAAAA,EAAiB,UAAU,MACvB,KAAK,IAAIwE,CAAK,IAAI,MACpB3E,EAAe2E,IAAQ,IAAI,IAAI,EAAE;AAAA,EAErC;AAEA,SACE,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWzB,EAAG,iBAAiBzG,EAAS;AAAA,MACxC,eAAY;AAAA,MACZ,KAAKuC;AAAA,MACL,MAAK;AAAA,MACL,wBAAqB;AAAA,MACrB,cAAYhC;AAAA,MACZ,OAAO2G;AAAA,MACP,cAAcxG,IAAe,MAAMiC,GAAa,EAAI,IAAI;AAAA,MACxD,cAAcjC,IAAe,MAAMiC,GAAa,EAAK,IAAI;AAAA,MAEzD,UAAA;AAAA,QAAA,gBAAAuF,EAAC,SAAI,WAAWzB,EAAG,sBAAsB,GAAG,KAAKrE,GAC9C,UAAA;AAAA,UAAAb,KACC,gBAAAwE;AAAA,YAACoC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,MAAMhI;AAAA,cACN,WAAWsG,EAAG,wBAAwB,2BAA2B;AAAA,cACjE,OAAO;AAAA,gBACL,KAAK,cAActG,IAAa,CAAC;AAAA,gBACjC,MAAM,CAACA,IAAa;AAAA,cAAA;AAAA,cAEtB,SAAS,MAAMmF,EAAsBC,EAAa,EAAE,CAAC,EAAA;AAAA,YAAE;AAAA,UAAA;AAAA,UAG3D,gBAAAQ;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,KAAKtD;AAAA,cACL,WAAU;AAAA,cACV,aAAaqB;AAAA,cACb,cAAcA;AAAA,cACd,aAAasE;AAAA,cACb,WAAWA;AAAA,cAEX,UAAA,gBAAArC,EAAC,OAAA,EAAI,WAAU,wBAAuB,OAAOkB,IAC1C,UAAA/F,EAAM,SAAS,IAAInB,GAAU,CAACsI,GAAOlF,MACpC,gBAAA4C,EAAC,OAAA,EAAgB,IAAI,GAAGc,EAAO,GAAG1D,CAAK,IAAI,WAAU,wBAAuB,OAAO4D,IACjF,UAAA,gBAAAhB;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAWU;AAAA,oBACT;AAAA,oBACA1F,KAAoB;AAAA,kBAAA;AAAA,kBAEtB,SAASA,IAAmBsE,GAAalC,CAAK,IAAI;AAAA,kBAEjD,UAAAkF;AAAA,gBAAA;AAAA,cAAA,EACH,GATQlF,CAUV,CACD,EAAA,CACH;AAAA,YAAA;AAAA,UAAA;AAAA,UAED5B,KACC,gBAAAwE;AAAA,YAACoC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,MAAMhI;AAAA,cACN,WAAWsG,EAAG,wBAAwB,2BAA2B;AAAA,cACjE,OAAO;AAAA,gBACL,KAAK,cAActG,IAAa,CAAC;AAAA,gBACjC,OAAO,CAACA,IAAa;AAAA,cAAA;AAAA,cAEvB,SAAS,MAAMmF,EAAsBC,EAAa,CAAC,CAAC,EAAA;AAAA,YAAE;AAAA,UAAA;AAAA,QACxD,GAEJ;AAAA,QACCO,GAAA;AAAA,QACA/E,KACC,gBAAAgF;AAAA,UAACuC;AAAA,UAAA;AAAA,YACC,MAAMpG,MAAoB;AAAA,YAC1B,MAAK;AAAA,YACL,UAAS;AAAA,YACT,WAAU;AAAA,YACV,SAAS,MAAMC,EAAmB,IAAI;AAAA,YACtC,cAAW;AAAA,YAEV,UAAAD,MAAoB,QACnB,gBAAAgG,EAAC,OAAA,EAAI,WAAU,qCACZ,UAAA;AAAA,cAAAjH,IAAc,KACb,gBAAA8E;AAAA,gBAACoC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,MAAM;AAAA,kBACN,WAAW1B,EAAG,mCAAmC,sCAAsC;AAAA,kBACvF,SAAS,MAAMnD,EAAe,EAAE;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGpC,gBAAAyC;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAU;AAAA,kBACV,cAAc8B;AAAA,kBACd,YAAYG;AAAA,kBAEX,aAAc9F,CAAe;AAAA,gBAAA;AAAA,cAAA;AAAA,cAE/BjB,IAAc,KACb,gBAAA8E;AAAA,gBAACoC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,MAAM;AAAA,kBACN,WAAW1B,EAAG,mCAAmC,sCAAsC;AAAA,kBACvF,SAAS,MAAMnD,EAAe,CAAC;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGnC,gBAAAyC;AAAA,gBAACoC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,MAAM;AAAA,kBACN,WAAU;AAAA,kBACV,SAAS,MAAMhG,EAAmB,IAAI;AAAA,gBAAA;AAAA,cAAA;AAAA,YACxC,EAAA,CACF;AAAA,UAAA;AAAA,QAAA;AAAA,MAEJ;AAAA,IAAA;AAAA,EAAA;AAIR,CAAC;"}
|
|
1
|
+
{"version":3,"file":"carousel.js","sources":["../../../../src/components/dataDisplay/carousel/carousel.tsx"],"sourcesContent":["import React, { forwardRef, ReactNode, useEffect, useId, useRef, useState } from \"react\";\nimport cn from \"clsx\";\nimport { Icon } from \"../../base/icon\";\nimport { Modal } from \"../../feedBack/modal\";\nimport { useForkRef } from \"../../../hooks/useForkRef\";\nimport {\n clamp,\n coordX,\n coordY,\n dragPrevent,\n getSlideIndexForMultipleParts,\n getSlidesToShow,\n getSlideStyle,\n getSlideWidth,\n getStartSlide,\n isMouseEvent,\n isTouchEvent,\n toCssLength,\n toCssNumber,\n} from \"./utils\";\nimport { useSafeLayoutEffect } from \"../../../hooks/useSafeLayoutEffect\";\nimport { useEventCallback } from \"../../../hooks/useEventCallback\";\n\nexport interface CarouselProps extends React.PropsWithChildren {\n slidesToShow?: number;\n startSlide?: number;\n className?: string;\n showNavigation?: boolean;\n showArrows?: boolean;\n arrowsSize?: number;\n navigationClassName?: string;\n onSlideChange?: (slideIndex: number) => void;\n navigationDotRenderer?: (index: number, isActive: boolean, onClick: (index: number) => void) => ReactNode;\n /** Accessible label for the carousel region. */\n \"aria-label\"?: string;\n /** Advance slides automatically. */\n autoplay?: boolean;\n /** Autoplay interval in ms. */\n autoplayInterval?: number;\n /** Pause autoplay while the pointer is over the carousel. */\n pauseOnHover?: boolean;\n /** Height of each cell/photo. Number is treated as px. Overrides the default 205px. */\n cellHeight?: number | string;\n /** Aspect ratio of each cell/photo (e.g. 0.9 or \"16 / 9\"). Overrides the default 0.9. */\n aspectRatio?: number | string;\n /** Per-side spacing around each slide. Number is treated as px (default 4). */\n gap?: number | string;\n /** Max width of the carousel. Number is treated as px (default 412). */\n maxWidth?: number | string;\n /** Open the clicked slide in a fullscreen lightbox (arrows / swipe / Esc to navigate & close). */\n enableFullscreen?: boolean;\n}\n\ninterface ShiftState {\n animation: boolean | undefined;\n}\n\ntype Axis = \"x\" | \"y\" | null;\n\ninterface Motion {\n isPressed: boolean;\n startX: number;\n startY: number;\n lastX: number;\n lastT: number;\n axis: Axis;\n dragged: boolean;\n}\n\nconst MOTION_INITIAL_STATE: Motion = {\n isPressed: false,\n startX: 0,\n startY: 0,\n lastX: 0,\n lastT: 0,\n axis: null,\n dragged: false,\n};\n\n// Movement (px) below which a pointer interaction is treated as a tap, not a drag.\nconst TAP_THRESHOLD = 8;\n// Flick velocity (px/ms) above which we advance a slide even on a short drag.\nconst FLICK_VELOCITY = 0.4;\n\nexport const Carousel = forwardRef<HTMLDivElement, CarouselProps>(function Carousel(\n {\n slidesToShow: slidesToShowProp = 3,\n startSlide: startSlideProp = 0,\n children,\n className,\n showNavigation = true,\n showArrows: showArrowsProp,\n arrowsSize = 30,\n navigationClassName,\n onSlideChange,\n navigationDotRenderer,\n \"aria-label\": ariaLabel = \"Carousel\",\n autoplay = false,\n autoplayInterval = 4000,\n pauseOnHover = true,\n cellHeight,\n aspectRatio,\n gap,\n maxWidth,\n enableFullscreen = false,\n },\n ref\n) {\n const slidesCount = React.Children.count(children);\n const slidesToShow = getSlidesToShow(slidesToShowProp, slidesCount);\n const startSlide = getStartSlide(startSlideProp, slidesCount);\n const showArrows = showArrowsProp && slidesCount > 1;\n const maxShift = Math.max(0, slidesCount - slidesToShow);\n\n const [activeSlideIndex, setActiveSlideIndex] = useState<number>(startSlide);\n const [shiftState, setShiftState] = useState<ShiftState>({\n animation: undefined,\n });\n // Live pointer-follow offset (px) applied on top of the resting %-based indent.\n const [dragPx, setDragPx] = useState<number>(0);\n const [isDragging, setIsDragging] = useState<boolean>(false);\n const [fullscreenIndex, setFullscreenIndex] = useState<number | null>(null);\n // Live finger-follow offset (px) for the fullscreen track.\n const [fullscreenDragPx, setFullscreenDragPx] = useState<number>(0);\n const [isFullscreenDragging, setIsFullscreenDragging] = useState<boolean>(false);\n\n const rootRef = useRef<HTMLDivElement>(null);\n const outerRef = useRef<HTMLDivElement>(null);\n const forkedOuterRef = useForkRef<HTMLDivElement>(ref, outerRef);\n const trackRef = useRef<HTMLDivElement>(null);\n const [isHovered, setIsHovered] = useState<boolean>(false);\n\n const motion = useRef<Motion>({ ...MOTION_INITIAL_STATE });\n\n useSafeLayoutEffect(() => {\n setShiftState((prevState) => ({\n ...prevState,\n animation: false,\n }));\n }, [slidesToShow]);\n\n useSafeLayoutEffect(() => {\n setActiveSlideIndex(startSlide);\n onSlideChange?.(startSlide);\n\n if (shiftState.animation !== undefined) {\n setShiftState((prevState) => ({\n ...prevState,\n animation: true,\n }));\n }\n }, [startSlide]);\n\n const setMotion = (value: Partial<Motion>) => {\n Object.assign<Motion, Partial<Motion>>(motion.current, value);\n };\n\n const now = () => (typeof performance !== \"undefined\" ? performance.now() : Date.now());\n\n const goToSlide = (index: number) => {\n const target = clamp(index, 0, maxShift);\n\n setActiveSlideIndex(target);\n setShiftState((prevState) => ({ ...prevState, animation: true }));\n onSlideChange?.(target);\n };\n\n const moveFullscreen = (direction: 1 | -1) => {\n setFullscreenIndex((prev) => (prev === null ? prev : (prev + direction + slidesCount) % slidesCount));\n };\n\n const fullscreenTouchX = useRef<number | null>(null);\n\n const detachListeners = (isMouse: boolean) => {\n if (!trackRef.current) {\n return;\n }\n\n trackRef.current.removeEventListener(isMouse ? \"mousemove\" : \"touchmove\", onMove);\n trackRef.current.removeEventListener(isMouse ? \"mouseup\" : \"touchend\", onEnd);\n\n if (isMouse) {\n trackRef.current.removeEventListener(\"mouseleave\", onEnd);\n }\n };\n\n const onStart = useEventCallback((event: React.MouseEvent<HTMLDivElement> | React.TouchEvent<HTMLDivElement>) => {\n if (!trackRef.current) {\n return;\n }\n\n const isMouse = isMouseEvent(event);\n\n if (isMouse && event.button !== 0) {\n return;\n }\n\n event.stopPropagation();\n\n const clientX = coordX(event);\n const clientY = coordY(event);\n\n setMotion({\n isPressed: true,\n startX: clientX,\n startY: clientY,\n lastX: clientX,\n lastT: now(),\n axis: null,\n dragged: false,\n });\n\n trackRef.current.addEventListener(isMouse ? \"mousemove\" : \"touchmove\", onMove, { passive: false });\n trackRef.current.addEventListener(isMouse ? \"mouseup\" : \"touchend\", onEnd);\n\n if (isMouse) {\n trackRef.current.addEventListener(\"mouseleave\", onEnd);\n }\n });\n\n const onMove = useEventCallback((event: MouseEvent | TouchEvent) => {\n if (!rootRef.current || !motion.current.isPressed) {\n return;\n }\n\n if (isTouchEvent(event) && event.touches.length > 1) {\n return onEnd(event);\n }\n\n const clientX = coordX(event);\n const clientY = coordY(event);\n const shiftX = clientX - motion.current.startX;\n const shiftY = clientY - motion.current.startY;\n\n // Lock the gesture axis once the pointer has moved past the tap threshold.\n if (motion.current.axis === null) {\n if (Math.abs(shiftX) < TAP_THRESHOLD && Math.abs(shiftY) < TAP_THRESHOLD) {\n return;\n }\n\n const axis: Axis = Math.abs(shiftX) >= Math.abs(shiftY) ? \"x\" : \"y\";\n setMotion({ axis, dragged: true });\n\n // Vertical intent → release so the page can scroll.\n if (axis === \"y\") {\n return onEnd(event);\n }\n\n if (slidesCount > 1) {\n setIsDragging(true);\n }\n }\n\n if (motion.current.axis !== \"x\") {\n return;\n }\n\n // Horizontal drag: keep the gesture and follow the finger.\n event.preventDefault();\n event.stopPropagation();\n\n if (slidesCount > 1) {\n const atStart = activeSlideIndex <= 0;\n const atEnd = activeSlideIndex >= maxShift;\n // Add resistance when dragging beyond the first / last slide.\n const offset = (atStart && shiftX > 0) || (atEnd && shiftX < 0) ? shiftX * 0.35 : shiftX;\n setDragPx(offset);\n }\n\n motion.current.lastX = clientX;\n motion.current.lastT = now();\n });\n\n const onEnd = useEventCallback((event: MouseEvent | TouchEvent) => {\n if (!motion.current.isPressed) {\n return;\n }\n\n const isMouse = isMouseEvent(event);\n detachListeners(isMouse);\n\n const { axis, dragged, startX, lastX, lastT } = motion.current;\n setMotion({ isPressed: false });\n setIsDragging(false);\n\n if (axis === \"x\" && dragged && slidesCount > 1 && rootRef.current) {\n const clientX = coordX(event);\n const totalShift = clientX - startX;\n const widthPerSlide = rootRef.current.offsetWidth / slidesToShow;\n const velocity = lastT ? (clientX - lastX) / Math.max(1, now() - lastT) : 0;\n\n let movedSlides = widthPerSlide > 0 ? Math.round(-totalShift / widthPerSlide) : 0;\n\n if (movedSlides === 0 && Math.abs(velocity) > FLICK_VELOCITY) {\n movedSlides = velocity < 0 ? 1 : -1;\n }\n\n goToSlide(activeSlideIndex + movedSlides);\n }\n\n // Animate back to the resting position (snap / snap-back).\n setDragPx(0);\n });\n\n const onSlideClick = (index: number) => () => {\n // Suppress the click that fires at the end of a drag.\n if (motion.current.dragged) {\n return;\n }\n\n if (enableFullscreen) {\n setFullscreenIndex(index);\n }\n };\n\n const onNavigationItemClick = (index: number) => () => goToSlide(index);\n\n const getNextIndex = (direction: 1 | -1) => {\n const isSingleSlide = slidesToShow === 1;\n const totalGroups = isSingleSlide ? slidesCount : Math.ceil(slidesCount / slidesToShow);\n const activeIndex = activeSlideIndex + slidesToShow;\n const isNextSlideDisabled = slidesCount - slidesToShow <= activeSlideIndex;\n\n const currentIndex = getSlideIndexForMultipleParts(activeIndex, slidesToShow, slidesCount, isNextSlideDisabled);\n const nextIndex = (currentIndex + direction + totalGroups) % totalGroups;\n\n return isSingleSlide ? nextIndex : nextIndex * slidesToShow;\n };\n\n const getNavigation = () => {\n if (!showNavigation) {\n return <></>;\n }\n\n const isNextSlideDisabled = slidesCount - slidesToShow <= activeSlideIndex;\n const isSinglePartSlide = slidesToShow === 1;\n const count = isSinglePartSlide ? slidesCount : Math.ceil(slidesCount / slidesToShow);\n const indicators: React.ReactNode[] = [];\n\n for (let index = 0; index < count; index++) {\n let nextIndex = index;\n let currentIndex = activeSlideIndex;\n\n if (!isSinglePartSlide) {\n const isLast = index === count - 1;\n const activeIndex = activeSlideIndex + slidesToShow;\n\n nextIndex = isLast ? slidesCount - slidesToShow : index * slidesToShow;\n currentIndex = getSlideIndexForMultipleParts(activeIndex, slidesToShow, slidesCount, isNextSlideDisabled);\n }\n\n const isActive = currentIndex === index;\n const onClick = onNavigationItemClick(nextIndex);\n\n let indicator: ReactNode = (\n <div key={index} className={cn(\"smwb-carousel__navigation__dot\", isActive && \"current\")} onClick={onClick} />\n );\n\n if (navigationDotRenderer) {\n indicator = navigationDotRenderer(index, isActive, onClick);\n }\n\n indicators.push(indicator);\n }\n\n return <div className={cn(\"smwb-carousel__navigation\", navigationClassName)}>{indicators}</div>;\n };\n\n const getIndent = () => {\n const shiftSlides = activeSlideIndex > maxShift ? maxShift : activeSlideIndex;\n\n return getSlideWidth(slidesToShow) * shiftSlides;\n };\n\n const slideId = useId();\n const slideStyle = getSlideStyle(slidesToShow);\n\n const indent = getIndent();\n\n const layerStyle: React.CSSProperties = {\n transform: `translateX(calc(-${indent}% + ${dragPx}px))`,\n transition:\n isDragging || shiftState.animation === undefined\n ? \"none\"\n : shiftState.animation\n ? \"transform 500ms cubic-bezier(.1, 0, .25, 1)\"\n : \"none\",\n };\n\n const rootStyle: React.CSSProperties = {};\n const cellHeightValue = toCssLength(cellHeight);\n const aspectRatioValue = toCssNumber(aspectRatio);\n const gapValue = toCssLength(gap);\n const maxWidthValue = toCssLength(maxWidth);\n if (cellHeightValue) (rootStyle as Record<string, string>)[\"--smwb-carousel-cell-height\"] = cellHeightValue;\n if (aspectRatioValue) (rootStyle as Record<string, string>)[\"--smwb-carousel-aspect-ratio\"] = aspectRatioValue;\n if (gapValue) (rootStyle as Record<string, string>)[\"--smwb-carousel-gap\"] = gapValue;\n if (maxWidthValue) (rootStyle as Record<string, string>)[\"--smwb-carousel-max-width\"] = maxWidthValue;\n\n React.useEffect(() => {\n if (!Array.isArray(children)) {\n console.error(\"SMWB Material: The `children` prop was passed invalidly. It should contain an array of elements.\");\n }\n }, [children]);\n\n useEffect(() => {\n if (!autoplay || slidesCount <= 1 || (pauseOnHover && isHovered) || fullscreenIndex !== null) {\n return;\n }\n const timer = window.setInterval(() => {\n onNavigationItemClick(getNextIndex(1))();\n }, autoplayInterval);\n\n return () => window.clearInterval(timer);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n autoplay,\n autoplayInterval,\n pauseOnHover,\n isHovered,\n slidesCount,\n activeSlideIndex,\n slidesToShow,\n fullscreenIndex,\n ]);\n\n useEffect(() => {\n if (fullscreenIndex === null || slidesCount <= 1) {\n return;\n }\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"ArrowLeft\") {\n moveFullscreen(-1);\n } else if (event.key === \"ArrowRight\") {\n moveFullscreen(1);\n }\n };\n document.addEventListener(\"keydown\", onKeyDown);\n\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [fullscreenIndex, slidesCount]);\n\n if (!Array.isArray(children)) {\n return <></>;\n }\n\n const childrenArray = children as ReactNode[];\n\n const onFullscreenTouchStart = (event: React.TouchEvent) => {\n fullscreenTouchX.current = event.touches[0]?.clientX ?? null;\n };\n\n const onFullscreenTouchMove = (event: React.TouchEvent) => {\n if (fullscreenTouchX.current === null || slidesCount <= 1) {\n return;\n }\n const delta = (event.touches[0]?.clientX ?? fullscreenTouchX.current) - fullscreenTouchX.current;\n setIsFullscreenDragging(true);\n setFullscreenDragPx(delta);\n };\n\n const onFullscreenTouchEnd = (event: React.TouchEvent) => {\n const startX = fullscreenTouchX.current;\n fullscreenTouchX.current = null;\n setIsFullscreenDragging(false);\n setFullscreenDragPx(0);\n\n if (startX === null || slidesCount <= 1) {\n return;\n }\n const delta = (event.changedTouches[0]?.clientX ?? startX) - startX;\n if (Math.abs(delta) > 40) {\n moveFullscreen(delta < 0 ? 1 : -1);\n }\n };\n\n const fullscreenTrackStyle: React.CSSProperties = {\n transform: `translateX(calc(-${(fullscreenIndex ?? 0) * 100}% + ${fullscreenDragPx}px))`,\n transition: isFullscreenDragging ? \"none\" : \"transform 350ms cubic-bezier(.22, .61, .36, 1)\",\n };\n\n return (\n <div\n className={cn(\"smwb-carousel\", className)}\n data-testid=\"carousel\"\n ref={forkedOuterRef}\n role=\"region\"\n aria-roledescription=\"carousel\"\n aria-label={ariaLabel}\n style={rootStyle}\n onMouseEnter={pauseOnHover ? () => setIsHovered(true) : undefined}\n onMouseLeave={pauseOnHover ? () => setIsHovered(false) : undefined}\n >\n <div className={cn(\"smwb-carousel__inner\")} ref={rootRef}>\n {showArrows && (\n <Icon\n name=\"chevron_left\"\n size={arrowsSize}\n className={cn(\"smwb-carousel__arrow\", \"smwb-carousel__arrow_prev\")}\n style={{\n top: `calc(50% - ${arrowsSize / 2}px)`,\n left: -arrowsSize / 2,\n }}\n onClick={() => onNavigationItemClick(getNextIndex(-1))()}\n />\n )}\n <div\n ref={trackRef}\n className=\"smwb-carousel__track\"\n onMouseDown={onStart}\n onTouchStart={onStart}\n onDragStart={dragPrevent}\n onDragEnd={dragPrevent}\n >\n <div className=\"smwb-carousel__layer\" style={layerStyle}>\n {React.Children.map(children, (child, index) => (\n <div key={index} id={`${slideId}${index}`} className=\"smwb-carousel__slide\" style={slideStyle}>\n <div\n className={cn(\n \"smwb-carousel__slide-inner\",\n enableFullscreen && \"smwb-carousel__slide-inner_clickable\"\n )}\n onClick={enableFullscreen ? onSlideClick(index) : undefined}\n >\n {child}\n </div>\n </div>\n ))}\n </div>\n </div>\n {showArrows && (\n <Icon\n name=\"chevron_right\"\n size={arrowsSize}\n className={cn(\"smwb-carousel__arrow\", \"smwb-carousel__arrow_next\")}\n style={{\n top: `calc(50% - ${arrowsSize / 2}px)`,\n right: -arrowsSize / 2,\n }}\n onClick={() => onNavigationItemClick(getNextIndex(1))()}\n />\n )}\n </div>\n {getNavigation()}\n {enableFullscreen && (\n <Modal\n open={fullscreenIndex !== null}\n size=\"fullscreen\"\n backdrop=\"darkBlured\"\n className=\"smwb-carousel__fullscreen\"\n onClose={() => setFullscreenIndex(null)}\n aria-label=\"Image viewer\"\n >\n {fullscreenIndex !== null && (\n <div className=\"smwb-carousel__fullscreen-content\">\n {slidesCount > 1 && (\n <Icon\n name=\"chevron_left\"\n size={40}\n className={cn(\"smwb-carousel__fullscreen-arrow\", \"smwb-carousel__fullscreen-arrow_prev\")}\n onClick={() => moveFullscreen(-1)}\n />\n )}\n <div\n className=\"smwb-carousel__fullscreen-stage\"\n onTouchStart={onFullscreenTouchStart}\n onTouchMove={onFullscreenTouchMove}\n onTouchEnd={onFullscreenTouchEnd}\n >\n <div className=\"smwb-carousel__fullscreen-track\" style={fullscreenTrackStyle}>\n {childrenArray.map((child, index) => (\n <div\n key={index}\n className=\"smwb-carousel__fullscreen-slide\"\n aria-hidden={index !== fullscreenIndex}\n >\n {child}\n </div>\n ))}\n </div>\n </div>\n {slidesCount > 1 && (\n <Icon\n name=\"chevron_right\"\n size={40}\n className={cn(\"smwb-carousel__fullscreen-arrow\", \"smwb-carousel__fullscreen-arrow_next\")}\n onClick={() => moveFullscreen(1)}\n />\n )}\n <Icon\n name=\"close\"\n size={32}\n className=\"smwb-carousel__fullscreen-close\"\n onClick={() => setFullscreenIndex(null)}\n />\n </div>\n )}\n </Modal>\n )}\n </div>\n );\n});\n\nexport default Carousel;\n"],"names":["MOTION_INITIAL_STATE","TAP_THRESHOLD","FLICK_VELOCITY","Carousel","forwardRef","slidesToShowProp","startSlideProp","children","className","showNavigation","showArrowsProp","arrowsSize","navigationClassName","onSlideChange","navigationDotRenderer","ariaLabel","autoplay","autoplayInterval","pauseOnHover","cellHeight","aspectRatio","gap","maxWidth","enableFullscreen","ref","slidesCount","React","slidesToShow","getSlidesToShow","startSlide","getStartSlide","showArrows","maxShift","activeSlideIndex","setActiveSlideIndex","useState","shiftState","setShiftState","dragPx","setDragPx","isDragging","setIsDragging","fullscreenIndex","setFullscreenIndex","fullscreenDragPx","setFullscreenDragPx","isFullscreenDragging","setIsFullscreenDragging","rootRef","useRef","outerRef","forkedOuterRef","useForkRef","trackRef","isHovered","setIsHovered","motion","useSafeLayoutEffect","prevState","setMotion","value","now","goToSlide","index","target","clamp","moveFullscreen","direction","prev","fullscreenTouchX","detachListeners","isMouse","onMove","onEnd","onStart","useEventCallback","event","isMouseEvent","clientX","coordX","clientY","coordY","isTouchEvent","shiftX","shiftY","axis","atStart","atEnd","offset","dragged","startX","lastX","lastT","totalShift","widthPerSlide","velocity","movedSlides","onSlideClick","onNavigationItemClick","getNextIndex","isSingleSlide","totalGroups","activeIndex","isNextSlideDisabled","nextIndex","getSlideIndexForMultipleParts","getNavigation","jsx","Fragment","isSinglePartSlide","count","indicators","currentIndex","isLast","isActive","onClick","indicator","cn","getIndent","shiftSlides","getSlideWidth","slideId","useId","slideStyle","getSlideStyle","layerStyle","rootStyle","cellHeightValue","toCssLength","aspectRatioValue","toCssNumber","gapValue","maxWidthValue","useEffect","timer","onKeyDown","childrenArray","onFullscreenTouchStart","_b","_a","onFullscreenTouchMove","delta","onFullscreenTouchEnd","fullscreenTrackStyle","jsxs","Icon","dragPrevent","child","Modal"],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { useRef as c, useEffect as M
|
|
2
|
-
|
|
1
|
+
import { useRef as c, useEffect as M } from "react";
|
|
2
|
+
import { useSafeLayoutEffect as S } from "../../../hooks/useSafeLayoutEffect.js";
|
|
3
|
+
function T(t, r = 24) {
|
|
3
4
|
return t.scrollHeight - t.scrollTop - t.clientHeight <= r;
|
|
4
5
|
}
|
|
5
6
|
function h(t) {
|
|
@@ -12,15 +13,15 @@ function B({ containerRef: t, messages: r, threshold: l = 24 }) {
|
|
|
12
13
|
if (!e)
|
|
13
14
|
return;
|
|
14
15
|
const o = () => {
|
|
15
|
-
n.current =
|
|
16
|
+
n.current = T(e, l);
|
|
16
17
|
};
|
|
17
18
|
return o(), e.addEventListener("scroll", o, { passive: !0 }), () => e.removeEventListener("scroll", o);
|
|
18
|
-
}, [t, l]),
|
|
19
|
-
var
|
|
19
|
+
}, [t, l]), S(() => {
|
|
20
|
+
var a, g;
|
|
20
21
|
const e = t.current;
|
|
21
22
|
if (!e)
|
|
22
23
|
return;
|
|
23
|
-
const o = u.current, p = d.current, v = f.current, i = (
|
|
24
|
+
const o = u.current, p = d.current, v = f.current, i = (a = r[0]) == null ? void 0 : a.id, s = (g = r[r.length - 1]) == null ? void 0 : g.id;
|
|
24
25
|
if (p === void 0)
|
|
25
26
|
h(e), n.current = !0;
|
|
26
27
|
else {
|
|
@@ -31,7 +32,7 @@ function B({ containerRef: t, messages: r, threshold: l = 24 }) {
|
|
|
31
32
|
}, [t, r]);
|
|
32
33
|
}
|
|
33
34
|
export {
|
|
34
|
-
|
|
35
|
+
T as isScrolledToBottom,
|
|
35
36
|
h as scrollChatToBottom,
|
|
36
37
|
B as useChatStickToBottom
|
|
37
38
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useChatStickToBottom.js","sources":["../../../../src/components/dataDisplay/chat/useChatStickToBottom.ts"],"sourcesContent":["import { RefObject, useEffect,
|
|
1
|
+
{"version":3,"file":"useChatStickToBottom.js","sources":["../../../../src/components/dataDisplay/chat/useChatStickToBottom.ts"],"sourcesContent":["import { RefObject, useEffect, useRef } from \"react\";\nimport { useSafeLayoutEffect } from \"../../../hooks/useSafeLayoutEffect\";\n\nexport interface UseChatStickToBottomParams {\n containerRef: RefObject<HTMLElement | null>;\n messages: readonly { id: string }[];\n threshold?: number;\n}\n\nexport function isScrolledToBottom(element: HTMLElement, threshold = 24): boolean {\n return element.scrollHeight - element.scrollTop - element.clientHeight <= threshold;\n}\n\nexport function scrollChatToBottom(element: HTMLElement): void {\n element.scrollTop = element.scrollHeight;\n}\n\nexport function useChatStickToBottom({ containerRef, messages, threshold = 24 }: UseChatStickToBottomParams) {\n const isAtBottomRef = useRef(true);\n const previousScrollHeightRef = useRef(0);\n const previousFirstMessageIdRef = useRef<string | undefined>();\n const previousLastMessageIdRef = useRef<string | undefined>();\n\n useEffect(() => {\n const element = containerRef.current;\n\n if (!element) {\n return;\n }\n\n const handleScroll = () => {\n isAtBottomRef.current = isScrolledToBottom(element, threshold);\n };\n\n handleScroll();\n element.addEventListener(\"scroll\", handleScroll, { passive: true });\n\n return () => element.removeEventListener(\"scroll\", handleScroll);\n }, [containerRef, threshold]);\n\n useSafeLayoutEffect(() => {\n const element = containerRef.current;\n\n if (!element) {\n return;\n }\n\n const previousScrollHeight = previousScrollHeightRef.current;\n const previousFirstMessageId = previousFirstMessageIdRef.current;\n const previousLastMessageId = previousLastMessageIdRef.current;\n const firstMessageId = messages[0]?.id;\n const lastMessageId = messages[messages.length - 1]?.id;\n\n if (previousFirstMessageId === undefined) {\n scrollChatToBottom(element);\n isAtBottomRef.current = true;\n } else {\n const prepended =\n firstMessageId !== undefined &&\n firstMessageId !== previousFirstMessageId &&\n lastMessageId === previousLastMessageId;\n const appended = lastMessageId !== undefined && lastMessageId !== previousLastMessageId;\n\n if (prepended && previousScrollHeight > 0) {\n element.scrollTop += element.scrollHeight - previousScrollHeight;\n } else if (appended && isAtBottomRef.current) {\n scrollChatToBottom(element);\n }\n }\n\n previousScrollHeightRef.current = element.scrollHeight;\n previousFirstMessageIdRef.current = firstMessageId;\n previousLastMessageIdRef.current = lastMessageId;\n }, [containerRef, messages]);\n}\n"],"names":["isScrolledToBottom","element","threshold","scrollChatToBottom","useChatStickToBottom","containerRef","messages","isAtBottomRef","useRef","previousScrollHeightRef","previousFirstMessageIdRef","previousLastMessageIdRef","useEffect","handleScroll","useSafeLayoutEffect","previousScrollHeight","previousFirstMessageId","previousLastMessageId","firstMessageId","_a","lastMessageId","_b","prepended","appended"],"mappings":";;AASO,SAASA,EAAmBC,GAAsBC,IAAY,IAAa;AAChF,SAAOD,EAAQ,eAAeA,EAAQ,YAAYA,EAAQ,gBAAgBC;AAC5E;AAEO,SAASC,EAAmBF,GAA4B;AAC7D,EAAAA,EAAQ,YAAYA,EAAQ;AAC9B;AAEO,SAASG,EAAqB,EAAE,cAAAC,GAAc,UAAAC,GAAU,WAAAJ,IAAY,MAAkC;AAC3G,QAAMK,IAAgBC,EAAO,EAAI,GAC3BC,IAA0BD,EAAO,CAAC,GAClCE,IAA4BF,EAAA,GAC5BG,IAA2BH,EAAA;AAEjC,EAAAI,EAAU,MAAM;AACd,UAAMX,IAAUI,EAAa;AAE7B,QAAI,CAACJ;AACH;AAGF,UAAMY,IAAe,MAAM;AACzB,MAAAN,EAAc,UAAUP,EAAmBC,GAASC,CAAS;AAAA,IAC/D;AAEA,WAAAW,EAAA,GACAZ,EAAQ,iBAAiB,UAAUY,GAAc,EAAE,SAAS,IAAM,GAE3D,MAAMZ,EAAQ,oBAAoB,UAAUY,CAAY;AAAA,EACjE,GAAG,CAACR,GAAcH,CAAS,CAAC,GAE5BY,EAAoB,MAAM;;AACxB,UAAMb,IAAUI,EAAa;AAE7B,QAAI,CAACJ;AACH;AAGF,UAAMc,IAAuBN,EAAwB,SAC/CO,IAAyBN,EAA0B,SACnDO,IAAwBN,EAAyB,SACjDO,KAAiBC,IAAAb,EAAS,CAAC,MAAV,gBAAAa,EAAa,IAC9BC,KAAgBC,IAAAf,EAASA,EAAS,SAAS,CAAC,MAA5B,gBAAAe,EAA+B;AAErD,QAAIL,MAA2B;AAC7B,MAAAb,EAAmBF,CAAO,GAC1BM,EAAc,UAAU;AAAA,SACnB;AACL,YAAMe,IACJJ,MAAmB,UACnBA,MAAmBF,KACnBI,MAAkBH,GACdM,IAAWH,MAAkB,UAAaA,MAAkBH;AAElE,MAAIK,KAAaP,IAAuB,IACtCd,EAAQ,aAAaA,EAAQ,eAAec,IACnCQ,KAAYhB,EAAc,WACnCJ,EAAmBF,CAAO;AAAA,IAE9B;AAEA,IAAAQ,EAAwB,UAAUR,EAAQ,cAC1CS,EAA0B,UAAUQ,GACpCP,EAAyB,UAAUS;AAAA,EACrC,GAAG,CAACf,GAAcC,CAAQ,CAAC;AAC7B;"}
|