{"version":3,"file":"index.mjs","names":[],"sources":["../../src/Legend/index.tsx"],"sourcesContent":["import { Flexbox, FlexboxProps } from '@lobehub/ui';\nimport { createStaticStyles, cx } from 'antd-style';\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport { forwardRef, useCallback, useEffect, useRef, useState } from 'react';\n\nimport { useThemeColorRange } from '@/hooks/useThemeColorRange';\n\nimport LegendItem from './LegendItem';\nimport ScrollButton from './ScrollButton';\n\nconst styles = createStaticStyles(({ css }) => ({\n  container: css`\n    position: relative;\n    overflow: hidden;\n  `,\n  enableLegendSlider: css`\n    scrollbar-width: none;\n\n    overflow: auto;\n    align-items: center;\n\n    padding-right: 48px;\n    padding-left: 16px;\n  `,\n  scrollButtons: css`\n    top: 0;\n    right: 0;\n    bottom: 0;\n  `,\n}));\n\nexport interface LegendProps extends FlexboxProps {\n  activeLegend?: string;\n  categories: string[];\n  colors?: string[];\n  customCategories?: {\n    [key: string]: string;\n  };\n  enableLegendSlider?: boolean;\n  onClickLegendItem?: (category: string, color: string) => void;\n}\n\ntype HasScrollProps = {\n  left: boolean;\n  right: boolean;\n};\n\nconst Legend = forwardRef<HTMLDivElement, LegendProps>((props, ref) => {\n  const themeColorRange = useThemeColorRange();\n  const {\n    customCategories,\n    categories,\n    colors = themeColorRange,\n    className,\n    onClickLegendItem,\n    activeLegend,\n    enableLegendSlider = false,\n    ...rest\n  } = props;\n  const scrollableRef = useRef<HTMLInputElement>(null);\n  const scrollButtonsRef = useRef<HTMLDivElement>(null);\n\n  const [hasScroll, setHasScroll] = useState<HasScrollProps | null>(null);\n  const [isKeyDowned, setIsKeyDowned] = useState<string | null>(null);\n  const intervalRef = useRef<any | null>(null);\n\n  const checkScroll = useCallback(() => {\n    const scrollable = scrollableRef?.current;\n    if (!scrollable) return;\n\n    const hasLeftScroll = scrollable.scrollLeft > 0;\n    const hasRightScroll = scrollable.scrollWidth - scrollable.clientWidth > scrollable.scrollLeft;\n\n    setHasScroll({ left: hasLeftScroll, right: hasRightScroll });\n  }, [setHasScroll]); // dependencies are listed here in the array\n\n  const scrollToTest = useCallback(\n    (direction: 'left' | 'right') => {\n      const element = scrollableRef?.current;\n      const scrollButtons = scrollButtonsRef?.current;\n      const width = element?.clientWidth ?? 0;\n      const scrollButtonsWith = scrollButtons?.clientWidth ?? 0;\n\n      if (element && enableLegendSlider) {\n        element.scrollTo({\n          behavior: 'smooth',\n          left:\n            direction === 'left'\n              ? element.scrollLeft - width + scrollButtonsWith\n              : element.scrollLeft + width - scrollButtonsWith,\n        });\n        setTimeout(() => {\n          checkScroll();\n        }, 400);\n      }\n    },\n    [enableLegendSlider, checkScroll],\n  );\n\n  useEffect(() => {\n    const keyDownHandler = (key: string) => {\n      if (key === 'ArrowLeft') {\n        scrollToTest('left');\n      } else if (key === 'ArrowRight') {\n        scrollToTest('right');\n      }\n    };\n    if (isKeyDowned) {\n      keyDownHandler(isKeyDowned);\n      intervalRef.current = setInterval(() => {\n        keyDownHandler(isKeyDowned);\n      }, 300);\n    } else {\n      clearInterval(intervalRef.current as any);\n    }\n    return () => clearInterval(intervalRef.current as any);\n  }, [isKeyDowned, scrollToTest]);\n\n  const keyDown = (e: KeyboardEvent) => {\n    e.stopPropagation();\n    if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {\n      e.preventDefault();\n      setIsKeyDowned(e.key);\n    }\n  };\n  const keyUp = (e: KeyboardEvent) => {\n    e.stopPropagation();\n    setIsKeyDowned(null);\n  };\n\n  useEffect(() => {\n    const scrollable = scrollableRef?.current;\n    if (enableLegendSlider) {\n      checkScroll();\n\n      scrollable?.addEventListener('keydown', keyDown);\n      scrollable?.addEventListener('keyup', keyUp);\n    }\n\n    return () => {\n      scrollable?.removeEventListener('keydown', keyDown);\n      scrollable?.removeEventListener('keyup', keyUp);\n    };\n  }, [checkScroll, enableLegendSlider]);\n\n  // @ts-ignore\n  return (\n    <Flexbox className={cx(styles.container, className)} gap={8} horizontal ref={ref} {...rest}>\n      <Flexbox\n        className={cx(\n          enableLegendSlider && (hasScroll?.right || hasScroll?.left) && styles.enableLegendSlider,\n        )}\n        flex={1}\n        height={'100%'}\n        horizontal\n        ref={scrollableRef}\n        style={{ overflow: 'hidden' }}\n        tabIndex={0}\n        wrap={enableLegendSlider ? 'nowrap' : 'wrap'}\n      >\n        {categories.map((category, idx) => (\n          <LegendItem\n            activeLegend={activeLegend}\n            color={colors[idx % colors.length]}\n            key={`item-${idx}`}\n            label={customCategories?.[category] || category}\n            name={category}\n            onClick={onClickLegendItem}\n          />\n        ))}\n      </Flexbox>\n      {enableLegendSlider && (hasScroll?.right || hasScroll?.left) ? (\n        <Flexbox\n          align={'center'}\n          className={styles.scrollButtons}\n          flex={'none'}\n          gap={4}\n          height={'100%'}\n          horizontal\n          justify={'center'}\n          ref={scrollButtonsRef}\n        >\n          <ScrollButton\n            disabled={!hasScroll?.left}\n            icon={ChevronLeft}\n            onClick={() => {\n              setIsKeyDowned(null);\n              scrollToTest('left');\n            }}\n          />\n          <ScrollButton\n            disabled={!hasScroll?.right}\n            icon={ChevronRight}\n            onClick={() => {\n              setIsKeyDowned(null);\n              scrollToTest('right');\n            }}\n          />\n        </Flexbox>\n      ) : null}\n    </Flexbox>\n  );\n});\n\nLegend.displayName = 'Legend';\n\nexport default Legend;\n"],"mappings":"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"}