SelectInput.tsx 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import * as React from 'react'
  2. import * as Select from '@radix-ui/react-select'
  3. import { TablerIcon } from '../icons'
  4. export interface SelectOption {
  5. value: string
  6. label: React.ReactNode
  7. }
  8. interface SelectInputProps extends React.HTMLAttributes<HTMLElement> {
  9. options: SelectOption[]
  10. value: string
  11. onValueChange: (value: string) => void
  12. }
  13. export function SelectInput({ options, value, onValueChange, ...rest }: SelectInputProps) {
  14. const [isOpen, setIsOpen] = React.useState(false)
  15. return (
  16. <div {...rest} className="tl-select-input">
  17. <Select.Root
  18. open={isOpen}
  19. onOpenChange={setIsOpen}
  20. value={value}
  21. onValueChange={onValueChange}
  22. >
  23. <Select.Trigger className="tl-select-input-trigger">
  24. <div className="tl-select-input-trigger-value">
  25. <Select.Value />
  26. </div>
  27. <Select.Icon style={{ lineHeight: 1 }}>
  28. <TablerIcon name={isOpen ? 'chevron-up' : 'chevron-down'} />
  29. </Select.Icon>
  30. </Select.Trigger>
  31. <Select.Portal className="tl-select-input-portal">
  32. <Select.Content className="tl-select-input-content">
  33. <Select.ScrollUpButton />
  34. <Select.Viewport className="tl-select-input-viewport">
  35. {options.map(option => {
  36. return (
  37. <Select.Item
  38. className="tl-select-input-select-item"
  39. key={option.value}
  40. value={option.value}
  41. >
  42. <Select.ItemText>{option.label}</Select.ItemText>
  43. </Select.Item>
  44. )
  45. })}
  46. </Select.Viewport>
  47. <Select.ScrollDownButton />
  48. </Select.Content>
  49. </Select.Portal>
  50. </Select.Root>
  51. </div>
  52. )
  53. }