{
  "version": 3,
  "sources": ["../src/scrollable-list.tsx"],
  "sourcesContent": ["import React from 'react';\nimport { Primitive } from '@ryvora/react-primitive';\nimport { createContextScope, type Scope } from '@ryvora/react-context';\nimport { useComposedRefs } from '@ryvora/react-compose-refs';\nimport { composeEventHandlers } from '@ryvora/primitive';\n\n/** ----------------------------------------- ScrollableList ----------------------------------------- */\n\nconst SCROLLABLE_LIST_NAME = 'ScrollableList';\n\ntype ScopedProps<P> = P & { __scopeScrollableList?: Scope };\n\nconst [createScrollableListContext, createScrollableListScope] =\n  createContextScope(SCROLLABLE_LIST_NAME);\n\ninterface ScrollContextType {\n  firstRef: React.RefObject<React.ComponentRef<typeof Primitive.div> | null>;\n  lastRef: React.RefObject<React.ComponentRef<typeof Primitive.div> | null>;\n  scrollRef: React.RefObject<React.ComponentRef<typeof Primitive.div> | null>;\n  items: React.ReactNode[];\n  disabledLeft: boolean;\n  setDisabledLeft: React.Dispatch<React.SetStateAction<boolean>>;\n  disabledRight: boolean;\n  setDisabledRight: React.Dispatch<React.SetStateAction<boolean>>;\n  isScrollReady?: boolean;\n}\n\nconst [ScrollableListProvider, useScrollableListContextInternal] =\n  createScrollableListContext<ScrollContextType>(SCROLLABLE_LIST_NAME);\n\nexport function useScrollContext(callerName: string, scope?: Scope): ScrollContextType {\n  const context = useScrollableListContextInternal(callerName, scope);\n  if (!context) {\n    throw new Error(`\\`${callerName}\\` must be used within \\`${SCROLLABLE_LIST_NAME}\\``);\n  }\n  return context;\n}\n\ntype ScrollableListElement = React.ComponentRef<typeof Primitive.div>;\ntype PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;\ninterface ScrollableListProps extends PrimitiveDivProps {}\n\nconst ScrollableList = React.forwardRef<ScrollableListElement, ScopedProps<ScrollableListProps>>(\n  ({ __scopeScrollableList, children, ...props }, forwardedRef) => {\n    const firstRef = React.useRef<React.ComponentRef<typeof Primitive.div>>(null);\n    const lastRef = React.useRef<React.ComponentRef<typeof Primitive.div>>(null);\n    const scrollRef = React.useRef<React.ComponentRef<typeof Primitive.div>>(null);\n\n    const [isScrollReady, setIsScrollReady] = React.useState(false);\n    const [disabledLeft, setDisabledLeft] = React.useState(true);\n    const [disabledRight, setDisabledRight] = React.useState(false);\n\n    React.useEffect(() => {\n      if (scrollRef.current) {\n        setIsScrollReady(true);\n      }\n    }, []);\n\n    let identifiedViewport: React.ReactElement | null = null;\n    const otherChildren: React.ReactNode[] = [];\n\n    React.Children.forEach(children, (child) => {\n      if (\n        React.isValidElement(child) &&\n        typeof child.type !== 'string' &&\n        (child.type as { displayName?: string }).displayName === VIEWPORT_NAME\n      ) {\n        identifiedViewport = child;\n      } else {\n        otherChildren.push(child);\n      }\n    });\n\n    let viewportWithRefs: React.ReactElement | null = identifiedViewport;\n\n    if (identifiedViewport) {\n      const viewportProps = (identifiedViewport as { props: { children?: React.ReactNode } }).props;\n      const itemsFromViewport = React.Children.toArray(viewportProps.children);\n\n      const itemsWithRefs = itemsFromViewport.map((item, idx) => {\n        if (!React.isValidElement(item)) return item;\n        if (idx === 0)\n          return React.cloneElement(item as React.ReactElement<React.RefAttributes<HTMLElement>>, {\n            ref: firstRef,\n          });\n        if (idx === itemsFromViewport.length - 1)\n          return React.cloneElement(item as React.ReactElement<React.RefAttributes<HTMLElement>>, {\n            ref: lastRef,\n          });\n        return item;\n      });\n\n      viewportWithRefs = React.cloneElement(identifiedViewport, {}, itemsWithRefs);\n    }\n\n    return (\n      <ScrollableListProvider\n        scope={__scopeScrollableList}\n        firstRef={firstRef}\n        lastRef={lastRef}\n        scrollRef={scrollRef}\n        items={React.Children.toArray(children)}\n        disabledLeft={disabledLeft}\n        setDisabledLeft={setDisabledLeft}\n        disabledRight={disabledRight}\n        setDisabledRight={setDisabledRight}\n        isScrollReady={isScrollReady}\n      >\n        <Primitive.div data-state-scrollable-list-root {...props} ref={forwardedRef}>\n          {viewportWithRefs}\n          {otherChildren}\n        </Primitive.div>\n      </ScrollableListProvider>\n    );\n  }\n);\n\nScrollableList.displayName = SCROLLABLE_LIST_NAME;\n\n/** ----------------------------------------- ScrollableListViewport ----------------------------------------- */\n\nconst VIEWPORT_NAME = 'ScrollableListViewport';\ntype ScrollableListViewportElement = React.ComponentRef<typeof Primitive.div>;\ninterface ScrollableListViewportProps extends PrimitiveDivProps {}\n\nconst ScrollableListViewport = React.forwardRef<\n  ScrollableListViewportElement,\n  ScopedProps<ScrollableListViewportProps>\n>(({ __scopeScrollableList, children, style, onScroll, ...props }, forwardedRef) => {\n  const context = useScrollContext(VIEWPORT_NAME, __scopeScrollableList);\n  const { setDisabledLeft, setDisabledRight } = context;\n  const composedRefs = useComposedRefs(forwardedRef, context.scrollRef);\n\n  const handleScroll = (event: React.UIEvent<HTMLDivElement>) => {\n    const target = event.currentTarget;\n    const scrollLeft = target.scrollLeft;\n    const scrollWidth = target.scrollWidth;\n    const clientWidth = target.clientWidth;\n\n    console.log({\n      scrollLeft,\n      scrollWidth,\n      clientWidth,\n      isAtStart: scrollLeft === 0,\n      isAtEnd: clientWidth + scrollLeft >= scrollWidth - 1,\n    });\n\n    setDisabledLeft(scrollLeft === 0);\n    setDisabledRight(clientWidth + scrollLeft >= scrollWidth - 1);\n  };\n\n  return (\n    <Primitive.div\n      data-state-scrollable-list-viewport\n      ref={composedRefs}\n      onScroll={composeEventHandlers(onScroll, handleScroll)}\n      {...props}\n    >\n      {children}\n    </Primitive.div>\n  );\n});\n\nScrollableListViewport.displayName = VIEWPORT_NAME;\n\n/** ----------------------------------------- ScrollableListItem ----------------------------------------- */\n\nconst ITEM_NAME = 'ScrollableListItem';\ntype ScrollableListItemElement = React.ComponentRef<typeof Primitive.div>;\ninterface ScrollableListItemProps extends PrimitiveDivProps {}\n\nconst ScrollableListItem = React.forwardRef<\n  ScrollableListItemElement,\n  ScopedProps<ScrollableListItemProps>\n>(({ __scopeScrollableList, ...props }, forwardedRef) => {\n  return <Primitive.div data-state-scrollable-list-item {...props} ref={forwardedRef} />;\n});\n\nScrollableListItem.displayName = ITEM_NAME;\n\n/** ----------------------------------------- ScrollableListPreviousButton ----------------------------------------- */\n\nconst PREVIOUS_BUTTON_NAME = 'ScrollableListPreviousButton';\ntype ScrollableListPreviousButtonElement = React.ComponentRef<typeof Primitive.button>;\ntype PrimitiveButtonProps = React.ComponentPropsWithoutRef<typeof Primitive.button>;\ninterface ScrollableListPreviousButtonProps extends PrimitiveButtonProps {}\n\nconst ScrollableListPreviousButton = React.forwardRef<\n  ScrollableListPreviousButtonElement,\n  ScopedProps<ScrollableListPreviousButtonProps>\n>(({ __scopeScrollableList, onClick, ...props }, forwardedRef) => {\n  const { disabledLeft, scrollRef, isScrollReady } = useScrollContext(\n    PREVIOUS_BUTTON_NAME,\n    __scopeScrollableList\n  );\n\n  const handleClick = () => {\n    if (scrollRef.current) {\n      scrollRef.current.scrollBy({\n        left: -200,\n        behavior: 'smooth',\n      });\n    }\n  };\n\n  if (!isScrollReady) return null;\n\n  return (\n    <Primitive.button\n      data-state-scrollable-list-prev-button\n      data-disabled={disabledLeft ? '' : undefined}\n      disabled={disabledLeft}\n      onClick={composeEventHandlers(onClick, handleClick)}\n      {...props}\n      ref={forwardedRef}\n    />\n  );\n});\n\nScrollableListPreviousButton.displayName = PREVIOUS_BUTTON_NAME;\n\n/** ----------------------------------------- ScrollableListNextButton ----------------------------------------- */\n\nconst NEXT_BUTTON_NAME = 'ScrollableListNextButton';\ntype ScrollableListNextButtonElement = React.ComponentRef<typeof Primitive.button>;\ninterface ScrollableListNextButtonProps extends PrimitiveButtonProps {}\n\nconst ScrollableListNextButton = React.forwardRef<\n  ScrollableListNextButtonElement,\n  ScopedProps<ScrollableListNextButtonProps>\n>(({ __scopeScrollableList, onClick, ...props }, forwardedRef) => {\n  const { disabledRight, scrollRef, isScrollReady } = useScrollContext(\n    NEXT_BUTTON_NAME,\n    __scopeScrollableList\n  );\n\n  const handleClick = () => {\n    if (scrollRef.current) {\n      scrollRef.current.scrollBy({\n        left: 200,\n        behavior: 'smooth',\n      });\n    }\n  };\n\n  if (!isScrollReady) return null;\n\n  return (\n    <Primitive.button\n      data-state-scrollable-list-next-button\n      aria-disabled={disabledRight || undefined}\n      data-disabled={disabledRight ? '' : undefined}\n      disabled={disabledRight}\n      onClick={composeEventHandlers(onClick, handleClick)}\n      {...props}\n      ref={forwardedRef}\n    />\n  );\n});\n\nScrollableListNextButton.displayName = NEXT_BUTTON_NAME;\n\nexport { createScrollableListScope };\n\nconst Root = ScrollableList;\nconst Viewport = ScrollableListViewport;\nconst Item = ScrollableListItem;\nconst PreviousButton = ScrollableListPreviousButton;\nconst NextButton = ScrollableListNextButton;\n\nexport {\n  ScrollableList,\n  ScrollableListViewport,\n  ScrollableListItem,\n  ScrollableListPreviousButton,\n  ScrollableListNextButton,\n  //\n  Root,\n  Viewport,\n  Item,\n  PreviousButton,\n  NextButton,\n};\n\nexport type {\n  ScrollableListProps,\n  ScrollableListViewportProps,\n  ScrollableListItemProps,\n  ScrollableListPreviousButtonProps,\n  ScrollableListNextButtonProps,\n};\n"],
  "mappings": "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",
  "names": []
}
