Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

index.tsx 2.5KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import React from 'react'
  2. import classNames from '@/utils/classnames'
  3. import type { RemixiconComponentType } from '@remixicon/react'
  4. import Divider from '../divider'
  5. // Updated generic type to allow enum values
  6. type SegmentedControlProps<T extends string | number | symbol> = {
  7. options: { Icon: RemixiconComponentType, text: string, value: T }[]
  8. value: T
  9. onChange: (value: T) => void
  10. className?: string
  11. }
  12. export const SegmentedControl = <T extends string | number | symbol>({
  13. options,
  14. value,
  15. onChange,
  16. className,
  17. }: SegmentedControlProps<T>): JSX.Element => {
  18. const selectedOptionIndex = options.findIndex(option => option.value === value)
  19. return (
  20. <div className={classNames(
  21. 'flex items-center rounded-lg bg-components-segmented-control-bg-normal gap-x-[1px] p-0.5',
  22. className,
  23. )}>
  24. {options.map((option, index) => {
  25. const { Icon } = option
  26. const isSelected = index === selectedOptionIndex
  27. const isNextSelected = index === selectedOptionIndex - 1
  28. const isLast = index === options.length - 1
  29. return (
  30. <button
  31. type='button'
  32. key={String(option.value)}
  33. className={classNames(
  34. 'flex items-center justify-center relative px-2 py-1 rounded-lg gap-x-0.5 group border-0.5 border-transparent',
  35. isSelected
  36. ? 'border-components-segmented-control-item-active-border bg-components-segmented-control-item-active-bg shadow-xs shadow-shadow-shadow-3'
  37. : 'hover:bg-state-base-hover',
  38. )}
  39. onClick={() => onChange(option.value)}
  40. >
  41. <span className='flex h-5 w-5 items-center justify-center'>
  42. <Icon className={classNames(
  43. 'w-4 h-4 text-text-tertiary',
  44. isSelected ? 'text-text-accent-light-mode-only' : 'group-hover:text-text-secondary',
  45. )} />
  46. </span>
  47. <span className={classNames(
  48. 'p-0.5 text-text-tertiary system-sm-medium',
  49. isSelected ? 'text-text-accent-light-mode-only' : 'group-hover:text-text-secondary',
  50. )}>
  51. {option.text}
  52. </span>
  53. {!isLast && !isSelected && !isNextSelected && (
  54. <div className='absolute right-[-1px] top-0 flex h-full items-center'>
  55. <Divider type='vertical' className='mx-0 h-3.5' />
  56. </div>
  57. )}
  58. </button>
  59. )
  60. })}
  61. </div>
  62. )
  63. }
  64. export default React.memo(SegmentedControl) as typeof SegmentedControl