locale.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. 'use client'
  2. import { Menu, Transition } from '@headlessui/react'
  3. import { Fragment } from 'react'
  4. import { GlobeAltIcon } from '@heroicons/react/24/outline'
  5. export const LOCALES = [
  6. { value: 'en', name: 'EN' },
  7. { value: 'zh-Hans', name: '简体中文' },
  8. ]
  9. export const RFC_LOCALES = [
  10. { value: 'en-US', name: 'EN' },
  11. { value: 'zh-Hans', name: '简体中文' },
  12. ]
  13. type ISelectProps = {
  14. items: Array<{ value: string; name: string }>
  15. value?: string
  16. className?: string
  17. onChange?: (value: string) => void
  18. }
  19. export default function Select({
  20. items,
  21. value,
  22. onChange,
  23. }: ISelectProps) {
  24. const item = items.filter(item => item.value === value)[0]
  25. return (
  26. <div className="w-56 text-right">
  27. <Menu as="div" className="relative inline-block text-left">
  28. <div>
  29. <Menu.Button className="inline-flex w-full h-[44px]justify-center items-center
  30. rounded-lg px-[10px] py-[6px]
  31. text-gray-900 text-[13px] font-medium
  32. border border-gray-200
  33. hover:bg-gray-100">
  34. <GlobeAltIcon className="w-5 h-5 mr-1" aria-hidden="true" />
  35. {item?.name}
  36. </Menu.Button>
  37. </div>
  38. <Transition
  39. as={Fragment}
  40. enter="transition ease-out duration-100"
  41. enterFrom="transform opacity-0 scale-95"
  42. enterTo="transform opacity-100 scale-100"
  43. leave="transition ease-in duration-75"
  44. leaveFrom="transform opacity-100 scale-100"
  45. leaveTo="transform opacity-0 scale-95"
  46. >
  47. <Menu.Items className="absolute right-0 mt-2 w-[120px] origin-top-right divide-y divide-gray-100 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
  48. <div className="px-1 py-1 ">
  49. {items.map((item) => {
  50. return <Menu.Item key={item.value}>
  51. {({ active }) => (
  52. <button
  53. className={`${active ? 'bg-gray-100' : ''
  54. } group flex w-full items-center rounded-lg px-3 py-2 text-sm text-gray-700`}
  55. onClick={(evt) => {
  56. evt.preventDefault()
  57. onChange && onChange(item.value)
  58. }}
  59. >
  60. {item.name}
  61. </button>
  62. )}
  63. </Menu.Item>
  64. })}
  65. </div>
  66. </Menu.Items>
  67. </Transition>
  68. </Menu>
  69. </div>
  70. )
  71. }
  72. export function InputSelect({
  73. items,
  74. value,
  75. onChange,
  76. }: ISelectProps) {
  77. const item = items.filter(item => item.value === value)[0]
  78. return (
  79. <div className="w-full">
  80. <Menu as="div" className="w-full">
  81. <div>
  82. <Menu.Button className="iappearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 sm:text-sm h-[38px] text-left">
  83. {item?.name}
  84. </Menu.Button>
  85. </div>
  86. <Transition
  87. as={Fragment}
  88. enter="transition ease-out duration-100"
  89. enterFrom="transform opacity-0 scale-95"
  90. enterTo="transform opacity-100 scale-100"
  91. leave="transition ease-in duration-75"
  92. leaveFrom="transform opacity-100 scale-100"
  93. leaveTo="transform opacity-0 scale-95"
  94. >
  95. <Menu.Items className="absolute right-0 mt-2 w-full origin-top-right divide-y divide-gray-100 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none z-10">
  96. <div className="px-1 py-1 ">
  97. {items.map((item) => {
  98. return <Menu.Item key={item.value}>
  99. {({ active }) => (
  100. <button
  101. className={`${active ? 'bg-gray-100' : ''
  102. } group flex w-full items-center rounded-md px-2 py-2 text-sm`}
  103. onClick={() => {
  104. onChange && onChange(item.value)
  105. }}
  106. >
  107. {item.name}
  108. </button>
  109. )}
  110. </Menu.Item>
  111. })}
  112. </div>
  113. </Menu.Items>
  114. </Transition>
  115. </Menu>
  116. </div>
  117. )
  118. }