wwf
2 天以前 a430284aa21e3ae1f0d5654e55b2ad2852519cc2
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
'use client'
import React, { useEffect, useState } from 'react'
import { Switch as OriginalSwitch } from '@headlessui/react'
import classNames from '@/utils/classnames'
 
type SwitchProps = {
  onChange?: (value: boolean) => void
  size?: 'sm' | 'md' | 'lg' | 'l'
  defaultValue?: boolean
  disabled?: boolean
  className?: string
}
 
const Switch = React.forwardRef(
  ({ onChange, size = 'md', defaultValue = false, disabled = false, className }: SwitchProps,
    propRef: React.Ref<HTMLButtonElement>) => {
    const [enabled, setEnabled] = useState(defaultValue)
    useEffect(() => {
      setEnabled(defaultValue)
    }, [defaultValue])
    const wrapStyle = {
      lg: 'h-6 w-11',
      l: 'h-5 w-9',
      md: 'h-4 w-7',
      sm: 'h-3 w-5',
    }
 
    const circleStyle = {
      lg: 'h-5 w-5',
      l: 'h-4 w-4',
      md: 'h-3 w-3',
      sm: 'h-2 w-2',
    }
 
    const translateLeft = {
      lg: 'translate-x-5',
      l: 'translate-x-4',
      md: 'translate-x-3',
      sm: 'translate-x-2',
    }
    return (
      <OriginalSwitch
        ref={propRef}
        checked={enabled}
        onChange={(checked: boolean) => {
          if (disabled)
            return
          setEnabled(checked)
          onChange?.(checked)
        }}
        className={classNames(
          wrapStyle[size],
          enabled ? 'bg-components-toggle-bg' : 'bg-components-toggle-bg-unchecked',
          'relative inline-flex  flex-shrink-0 cursor-pointer rounded-[5px] border-2 border-transparent transition-colors duration-200 ease-in-out',
          disabled ? '!opacity-50 !cursor-not-allowed' : '',
          className,
        )}
      >
        <span
          aria-hidden="true"
          className={classNames(
            circleStyle[size],
            enabled ? translateLeft[size] : 'translate-x-0',
            'pointer-events-none inline-block transform rounded-[3px] bg-components-toggle-knob shadow ring-0 transition duration-200 ease-in-out',
          )}
        />
      </OriginalSwitch>
    )
  })
 
Switch.displayName = 'Switch'
 
export default React.memo(Switch)