{"version":3,"sources":["../src/Pagination/Pagination.tsx"],"sourcesContent":["import * as React from 'react';\nimport { clsx } from 'clsx';\nimport { ChevronsLeft, ChevronLeft, ChevronRight, ChevronsRight } from 'lucide-react';\n\nexport interface PaginationProps {\n  /**\n   * Current page number (1-indexed)\n   */\n  currentPage: number;\n  /**\n   * Total number of pages\n   */\n  totalPages: number;\n  /**\n   * Callback when page changes\n   */\n  onPageChange: (page: number) => void;\n  /**\n   * Custom className\n   */\n  className?: string;\n  /**\n   * Custom style\n   */\n  style?: React.CSSProperties;\n  /**\n   * Test ID for testing\n   */\n  'data-testid'?: string;\n}\n\nconst containerStyles: React.CSSProperties = {\n  display: 'flex',\n  alignItems: 'center',\n  gap: '8px',\n  fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n};\n\nconst buttonStyles: React.CSSProperties = {\n  width: '24px',\n  height: '24px',\n  borderRadius: '50%',\n  border: 'none',\n  background: 'transparent',\n  cursor: 'pointer',\n  display: 'flex',\n  alignItems: 'center',\n  justifyContent: 'center',\n  padding: 0,\n  transition: 'background-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out',\n  flexShrink: 0,\n  WebkitTapHighlightColor: 'transparent',\n  outline: 'none',\n};\n\nconst buttonDisabledStyles: React.CSSProperties = {\n  cursor: 'not-allowed',\n  opacity: 0.5,\n};\n\nconst labelStyles: React.CSSProperties = {\n  fontSize: '13px',\n  fontWeight: 600,\n  lineHeight: '1.5',\n  color: '#2f2f2f',\n};\n\nconst inputWrapperStyles: React.CSSProperties = {\n  display: 'flex',\n  alignItems: 'center',\n  gap: '8px',\n};\n\nconst inputStyles: React.CSSProperties = {\n  width: '60px',\n  paddingTop: '12px',\n  paddingBottom: '12px',\n  paddingLeft: '16px',\n  paddingRight: '16px',\n  fontSize: '13px',\n  fontWeight: 400,\n  lineHeight: '1.5',\n  color: '#2f2f2f',\n  backgroundColor: 'white',\n  border: '1px solid #dfdfdf',\n  borderRadius: '8px',\n  fontFamily: 'inherit',\n  textAlign: 'center',\n  outline: 'none',\n};\n\nconst inputFocusStyles: React.CSSProperties = {\n  boxShadow: '0px 0px 0px 3px #3cad51',\n};\n\nconst textStyles: React.CSSProperties = {\n  fontSize: '13px',\n  fontWeight: 400,\n  lineHeight: '1.5',\n  color: '#2f2f2f',\n};\n\n/**\n * Pagination component - Arbor Design System\n *\n * A pagination control with first/previous/next/last buttons and a page input field.\n */\nexport const Pagination = React.forwardRef<HTMLDivElement, PaginationProps>(\n  (\n    {\n      currentPage,\n      totalPages,\n      onPageChange,\n      className,\n      style,\n      'data-testid': dataTestId,\n    },\n    ref\n  ) => {\n    const [inputValue, setInputValue] = React.useState(currentPage.toString());\n    const [focusedButton, setFocusedButton] = React.useState<string | null>(null);\n    const [hoveredButton, setHoveredButton] = React.useState<string | null>(null);\n    const [activeButton, setActiveButton] = React.useState<string | null>(null);\n    const [inputFocused, setInputFocused] = React.useState(false);\n\n    React.useEffect(() => {\n      setInputValue(currentPage.toString());\n    }, [currentPage]);\n\n    const handleFirstPage = () => {\n      if (currentPage !== 1) {\n        onPageChange(1);\n      }\n    };\n\n    const handlePreviousPage = () => {\n      if (currentPage > 1) {\n        onPageChange(currentPage - 1);\n      }\n    };\n\n    const handleNextPage = () => {\n      if (currentPage < totalPages) {\n        onPageChange(currentPage + 1);\n      }\n    };\n\n    const handleLastPage = () => {\n      if (currentPage !== totalPages) {\n        onPageChange(totalPages);\n      }\n    };\n\n    const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n      const value = e.target.value;\n      // Allow empty or valid numbers\n      if (value === '' || /^\\d+$/.test(value)) {\n        setInputValue(value);\n      }\n    };\n\n    const handleInputBlur = () => {\n      setInputFocused(false);\n      const pageNumber = parseInt(inputValue, 10);\n      if (isNaN(pageNumber) || pageNumber < 1) {\n        setInputValue(currentPage.toString());\n      } else if (pageNumber > totalPages) {\n        setInputValue(totalPages.toString());\n        onPageChange(totalPages);\n      } else if (pageNumber !== currentPage) {\n        onPageChange(pageNumber);\n      }\n    };\n\n    const handleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n      if (e.key === 'Enter') {\n        handleInputBlur();\n        (e.target as HTMLInputElement).blur();\n      }\n    };\n\n    const getButtonStyle = (buttonName: string, disabled: boolean): React.CSSProperties => {\n      if (disabled) {\n        return { ...buttonStyles, ...buttonDisabledStyles };\n      }\n\n      const isHovered = hoveredButton === buttonName;\n      const isFocused = focusedButton === buttonName;\n      const isActive = activeButton === buttonName;\n\n      const style: React.CSSProperties = {\n        ...buttonStyles,\n      };\n\n      // Apply hover state (light gray background)\n      if (isHovered && !isFocused && !isActive) {\n        style.backgroundColor = '#efefef';\n      }\n\n      // Apply active state (same as hover or transparent)\n      if (isActive && !isFocused) {\n        style.backgroundColor = 'transparent';\n      }\n\n      // Apply focus state (green ring, transparent background)\n      if (isFocused) {\n        style.boxShadow = '0px 0px 0px 3px #3cad51';\n        style.backgroundColor = 'rgba(255, 255, 255, 0.01)';\n      }\n\n      return style;\n    };\n\n    const isFirstDisabled = currentPage === 1;\n    const isPreviousDisabled = currentPage === 1;\n    const isNextDisabled = currentPage === totalPages;\n    const isLastDisabled = currentPage === totalPages;\n\n    return (\n      <div\n        ref={ref}\n        className={clsx('arbor-pagination', className)}\n        style={{ ...containerStyles, ...style }}\n        data-testid={dataTestId}\n      >\n        {/* First page button */}\n        <button\n          type=\"button\"\n          onClick={handleFirstPage}\n          disabled={isFirstDisabled}\n          onMouseEnter={() => setHoveredButton('first')}\n          onMouseLeave={() => setHoveredButton(null)}\n          onMouseDown={() => setActiveButton('first')}\n          onMouseUp={() => setActiveButton(null)}\n          onFocus={() => setFocusedButton('first')}\n          onBlur={() => setFocusedButton(null)}\n          style={getButtonStyle('first', isFirstDisabled)}\n          aria-label=\"Go to first page\"\n        >\n          <ChevronsLeft size={16} color=\"#2f2f2f\" />\n        </button>\n\n        {/* Previous page button */}\n        <button\n          type=\"button\"\n          onClick={handlePreviousPage}\n          disabled={isPreviousDisabled}\n          onMouseEnter={() => setHoveredButton('previous')}\n          onMouseLeave={() => setHoveredButton(null)}\n          onMouseDown={() => setActiveButton('previous')}\n          onMouseUp={() => setActiveButton(null)}\n          onFocus={() => setFocusedButton('previous')}\n          onBlur={() => setFocusedButton(null)}\n          style={getButtonStyle('previous', isPreviousDisabled)}\n          aria-label=\"Go to previous page\"\n        >\n          <ChevronLeft size={16} color=\"#2f2f2f\" />\n        </button>\n\n        {/* Page input */}\n        <div style={inputWrapperStyles}>\n          <span style={labelStyles}>Page</span>\n          <input\n            type=\"text\"\n            value={inputValue}\n            onChange={handleInputChange}\n            onBlur={handleInputBlur}\n            onFocus={() => setInputFocused(true)}\n            onKeyDown={handleInputKeyDown}\n            style={{\n              ...inputStyles,\n              ...(inputFocused && inputFocusStyles),\n            }}\n            aria-label={`Page ${currentPage} of ${totalPages}`}\n          />\n          <span style={textStyles}>of {totalPages}</span>\n        </div>\n\n        {/* Next page button */}\n        <button\n          type=\"button\"\n          onClick={handleNextPage}\n          disabled={isNextDisabled}\n          onMouseEnter={() => setHoveredButton('next')}\n          onMouseLeave={() => setHoveredButton(null)}\n          onMouseDown={() => setActiveButton('next')}\n          onMouseUp={() => setActiveButton(null)}\n          onFocus={() => setFocusedButton('next')}\n          onBlur={() => setFocusedButton(null)}\n          style={getButtonStyle('next', isNextDisabled)}\n          aria-label=\"Go to next page\"\n        >\n          <ChevronRight size={16} color=\"#2f2f2f\" />\n        </button>\n\n        {/* Last page button */}\n        <button\n          type=\"button\"\n          onClick={handleLastPage}\n          disabled={isLastDisabled}\n          onMouseEnter={() => setHoveredButton('last')}\n          onMouseLeave={() => setHoveredButton(null)}\n          onMouseDown={() => setActiveButton('last')}\n          onMouseUp={() => setActiveButton(null)}\n          onFocus={() => setFocusedButton('last')}\n          onBlur={() => setFocusedButton(null)}\n          style={getButtonStyle('last', isLastDisabled)}\n          aria-label=\"Go to last page\"\n        >\n          <ChevronsRight size={16} color=\"#2f2f2f\" />\n        </button>\n      </div>\n    );\n  }\n);\n\nPagination.displayName = 'Pagination';\n"],"mappings":"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","names":["style"]}