File size: 2,223 Bytes
74aacd5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import React, { useRef } from 'react'
import {
  CheckIcon,
  ChevronDownIcon,
  ChevronUpIcon,
} from '@heroicons/react/24/outline'
import * as Select from '@radix-ui/react-select'

type SelectorChevronDirection = 'up' | 'down'

interface Props {
  width?: number
  value: string
  options: string[]
  chevronDirection?: SelectorChevronDirection
  autoFocusAfterClose?: boolean
  onChange: (value: string) => void
  disabled?: boolean
}

const Selector = (props: Props) => {
  const {
    width,
    value,
    chevronDirection,
    options,
    autoFocusAfterClose,
    onChange,
    disabled,
  } = props

  const contentRef = useRef<HTMLButtonElement>(null)

  const onOpenChange = (open: boolean) => {
    if (!open) {
      if (!autoFocusAfterClose) {
        // 如果使用 Select.Content 的 onCloseAutoFocus 来取消 focus(防止空格继续打开这个 select)
        // 会导致其它快捷键失效,原因未知
        window.setTimeout(() => {
          contentRef?.current?.blur()
        }, 100)
      }
    }
  }

  return (
    <Select.Root
      value={value}
      onValueChange={onChange}
      onOpenChange={onOpenChange}
    >
      <Select.Trigger
        className="select-trigger"
        style={{ width }}
        ref={contentRef}
        onKeyDown={e => e.preventDefault()}
        disabled={disabled}
      >
        <Select.Value />
        <Select.Icon>
          {chevronDirection === 'up' ? <ChevronUpIcon /> : <ChevronDownIcon />}
        </Select.Icon>
      </Select.Trigger>

      <Select.Content className="select-content">
        <Select.Viewport className="select-viewport">
          {options.map(val => (
            <Select.Item value={val} className="select-item" key={val}>
              <Select.ItemText>{val}</Select.ItemText>
              <Select.ItemIndicator className="select-item-indicator">
                <CheckIcon />
              </Select.ItemIndicator>
            </Select.Item>
          ))}
        </Select.Viewport>
      </Select.Content>
    </Select.Root>
  )
}

const selectorDefaultProps = {
  chevronDirection: 'down',
  autoFocusAfterClose: true,
  disabled: false,
}

Selector.defaultProps = selectorDefaultProps

export default Selector