From 77950e48c76f4a3b29d01831d43039caba29888a Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期二, 18 十一月 2025 14:12:42 +0800
Subject: [PATCH] 修改
---
app/components/base/select/index.tsx | 151 +++++++++++++++++++++++++-------------------------
1 files changed, 76 insertions(+), 75 deletions(-)
diff --git a/app/components/base/select/index.tsx b/app/components/base/select/index.tsx
index fa8730f..221d703 100644
--- a/app/components/base/select/index.tsx
+++ b/app/components/base/select/index.tsx
@@ -1,9 +1,8 @@
'use client'
import type { FC } from 'react'
-import React, { useEffect, useState } from 'react'
-import { Combobox, ComboboxButton, ComboboxInput, ComboboxOption, ComboboxOptions, Listbox, ListboxButton, ListboxOption, ListboxOptions } from '@headlessui/react'
+import React, { Fragment, useEffect, useState } from 'react'
+import { Combobox, Listbox, Transition } from '@headlessui/react'
import { ChevronDownIcon, ChevronUpIcon, XMarkIcon } from '@heroicons/react/20/solid'
-import Badge from '../badge/index'
import { RiCheckLine } from '@remixicon/react'
import { useTranslation } from 'react-i18next'
import classNames from '@/utils/classnames'
@@ -31,7 +30,7 @@
export type ISelectProps = {
className?: string
wrapperClassName?: string
- renderTrigger?: (value: Item | null) => React.JSX.Element | null
+ renderTrigger?: (value: Item | null) => JSX.Element | null
items?: Item[]
defaultValue?: number | string
disabled?: boolean
@@ -59,7 +58,7 @@
disabled = false,
onSelect,
allowSearch = true,
- bgClassName = 'bg-components-input-bg-normal',
+ bgClassName = 'bg-gray-100',
overlayClassName,
optionClassName,
renderOption,
@@ -99,44 +98,44 @@
}
}}>
<div className={classNames('relative')}>
- <div className='group text-text-secondary'>
+ <div className='group text-gray-800'>
{allowSearch
- ? <ComboboxInput
- className={`w-full rounded-lg border-0 ${bgClassName} py-1.5 pl-3 pr-10 shadow-sm focus-visible:bg-state-base-hover focus-visible:outline-none group-hover:bg-state-base-hover sm:text-sm sm:leading-6 ${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}`}
+ ? <Combobox.Input
+ className={`w-full rounded-lg border-0 ${bgClassName} py-1.5 pl-3 pr-10 shadow-sm sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-gray-200 group-hover:bg-gray-200 ${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}`}
onChange={(event) => {
if (!disabled)
setQuery(event.target.value)
}}
displayValue={(item: Item) => item?.name}
/>
- : <ComboboxButton onClick={
+ : <Combobox.Button onClick={
() => {
if (!disabled)
setOpen(!open)
}
- } className={classNames(`flex items-center h-9 w-full rounded-lg border-0 ${bgClassName} py-1.5 pl-3 pr-10 shadow-sm sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-state-base-hover group-hover:bg-state-base-hover`, optionClassName)}>
- <div className='w-0 grow truncate text-left' title={selectedItem?.name}>{selectedItem?.name}</div>
- </ComboboxButton>}
- <ComboboxButton className="absolute inset-y-0 right-0 flex items-center rounded-r-md px-2 focus:outline-none" onClick={
+ } className={classNames(`flex items-center h-9 w-full rounded-lg border-0 ${bgClassName} py-1.5 pl-3 pr-10 shadow-sm sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-gray-200 group-hover:bg-gray-200`, optionClassName)}>
+ <div className='w-0 grow text-left truncate' title={selectedItem?.name}>{selectedItem?.name}</div>
+ </Combobox.Button>}
+ <Combobox.Button className="absolute inset-y-0 right-0 flex items-center rounded-r-md px-2 focus:outline-none group-hover:bg-gray-200" onClick={
() => {
if (!disabled)
setOpen(!open)
}
}>
{open ? <ChevronUpIcon className="h-5 w-5" /> : <ChevronDownIcon className="h-5 w-5" />}
- </ComboboxButton>
+ </Combobox.Button>
</div>
{(filteredItems.length > 0 && open) && (
- <ComboboxOptions className={`absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md border-[0.5px] border-components-panel-border bg-components-panel-bg-blur px-1 py-1 text-base shadow-lg backdrop-blur-sm focus:outline-none sm:text-sm ${overlayClassName}`}>
+ <Combobox.Options className={`absolute z-10 mt-1 px-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg border-gray-200 border-[0.5px] focus:outline-none sm:text-sm ${overlayClassName}`}>
{filteredItems.map((item: Item) => (
- <ComboboxOption
+ <Combobox.Option
key={item.value}
value={item}
className={({ active }: { active: boolean }) =>
classNames(
- 'relative cursor-default select-none py-2 pl-3 pr-9 rounded-lg hover:bg-state-base-hover text-text-secondary',
- active ? 'bg-state-base-hover' : '',
+ 'relative cursor-default select-none py-2 pl-3 pr-9 rounded-lg hover:bg-gray-100 text-gray-700',
+ active ? 'bg-gray-100' : '',
optionClassName,
)
}
@@ -151,7 +150,7 @@
{selected && (
<span
className={classNames(
- 'absolute inset-y-0 right-0 flex items-center pr-4 text-text-secondary',
+ 'absolute inset-y-0 right-0 flex items-center pr-4 text-gray-700',
)}
>
<RiCheckLine className="h-4 w-4" aria-hidden="true" />
@@ -161,9 +160,9 @@
)}
</>
)}
- </ComboboxOption>
+ </Combobox.Option>
))}
- </ComboboxOptions>
+ </Combobox.Options>
)}
</div>
</Combobox >
@@ -210,9 +209,9 @@
}}
>
<div className={classNames('group/simple-select relative h-9', wrapperClassName)}>
- {renderTrigger && <ListboxButton className='w-full'>{renderTrigger(selectedItem)}</ListboxButton>}
+ {renderTrigger && <Listbox.Button className='w-full'>{renderTrigger(selectedItem)}</Listbox.Button>}
{!renderTrigger && (
- <ListboxButton className={classNames(`flex items-center w-full h-full rounded-lg border-0 bg-components-input-bg-normal pl-3 pr-10 sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-state-base-hover-alt group-hover/simple-select:bg-state-base-hover-alt ${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}`, className)}>
+ <Listbox.Button className={classNames(`flex items-center w-full h-full rounded-lg border-0 bg-components-input-bg-normal pl-3 pr-10 sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-state-base-hover-alt group-hover/simple-select:bg-state-base-hover-alt ${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}`, className)}>
<span className={classNames('block truncate text-left system-sm-regular text-components-input-text-filled', !selectedItem?.name && 'text-components-input-text-placeholder')}>{selectedItem?.name ?? localPlaceholder}</span>
<span className="absolute inset-y-0 right-0 flex items-center pr-2">
{(selectedItem && !notClearable)
@@ -223,7 +222,7 @@
setSelectedItem(null)
onSelect({ name: '', value: '' })
}}
- className="h-4 w-4 cursor-pointer text-text-quaternary"
+ className="h-4 w-4 text-text-quaternary cursor-pointer"
aria-hidden="false"
/>
)
@@ -234,44 +233,52 @@
/>
)}
</span>
- </ListboxButton>
+ </Listbox.Button>
)}
{!disabled && (
- <ListboxOptions className={classNames('absolute z-10 mt-1 px-1 max-h-60 w-full overflow-auto rounded-xl bg-components-panel-bg-blur backdrop-blur-sm py-1 text-base shadow-lg border-components-panel-border border-[0.5px] focus:outline-none sm:text-sm', optionWrapClassName)}>
- {items.map((item: Item) => (
- <ListboxOption
- key={item.value}
- className={
- classNames(
- 'relative cursor-pointer select-none py-2 pl-3 pr-9 rounded-lg hover:bg-state-base-hover text-text-secondary',
- optionClassName,
- )
- }
- value={item}
- disabled={disabled}
- >
- {({ /* active, */ selected }) => (
- <>
- {renderOption
- ? renderOption({ item, selected })
- : (<>
- <span className={classNames('block', selected && 'font-normal')}>{item.name}</span>
- {selected && !hideChecked && (
- <span
- className={classNames(
- 'absolute inset-y-0 right-0 flex items-center pr-4 text-text-accent',
- )}
- >
- <RiCheckLine className="h-4 w-4" aria-hidden="true" />
- </span>
- )}
- </>)}
- </>
- )}
- </ListboxOption>
- ))}
- </ListboxOptions>
+ <Transition
+ as={Fragment}
+ leave="transition ease-in duration-100"
+ leaveFrom="opacity-100"
+ leaveTo="opacity-0"
+ >
+
+ <Listbox.Options className={classNames('absolute z-10 mt-1 px-1 max-h-60 w-full overflow-auto rounded-md bg-components-panel-bg-blur py-1 text-base shadow-lg border-components-panel-border border-[0.5px] focus:outline-none sm:text-sm', optionWrapClassName)}>
+ {items.map((item: Item) => (
+ <Listbox.Option
+ key={item.value}
+ className={({ active }) =>
+ classNames(
+ 'relative cursor-pointer select-none py-2 pl-3 pr-9 rounded-lg hover:bg-state-base-hover text-text-secondary',
+ optionClassName,
+ )
+ }
+ value={item}
+ disabled={disabled}
+ >
+ {({ /* active, */ selected }) => (
+ <>
+ {renderOption
+ ? renderOption({ item, selected })
+ : (<>
+ <span className={classNames('block', selected && 'font-normal')}>{item.name}</span>
+ {selected && !hideChecked && (
+ <span
+ className={classNames(
+ 'absolute inset-y-0 right-0 flex items-center pr-4 text-text-accent',
+ )}
+ >
+ <RiCheckLine className="h-4 w-4" aria-hidden="true" />
+ </span>
+ )}
+ </>)}
+ </>
+ )}
+ </Listbox.Option>
+ ))}
+ </Listbox.Options>
+ </Transition>
)}
</div>
</Listbox>
@@ -283,8 +290,7 @@
onSelect: (value: Item) => void
items: Item[]
placeholder?: string
- installedValue?: string | number
- renderTrigger?: (value?: Item) => React.JSX.Element | null
+ renderTrigger?: (value?: Item) => JSX.Element | null
triggerClassName?: string
triggerClassNameFn?: (open: boolean) => string
popupClassName?: string
@@ -297,7 +303,6 @@
onSelect,
items,
placeholder,
- installedValue,
renderTrigger,
triggerClassName,
triggerClassNameFn,
@@ -309,7 +314,7 @@
const { t } = useTranslation()
const [open, setOpen] = useState(false)
const localPlaceholder = placeholder || t('common.placeholder.select')
- const selectedItem = value ? items.find(item => item.value === value) : undefined
+ const selectedItem = items.find(item => item.value === value)
return (
<PortalToFollowElem
@@ -324,34 +329,33 @@
: (
<div
className={classNames(`
- group flex items-center justify-between px-2.5 h-9 rounded-lg border-0 bg-components-input-bg-normal hover:bg-state-base-hover-alt text-sm ${readonly ? 'cursor-not-allowed' : 'cursor-pointer'}
+ flex items-center justify-between px-2.5 h-9 rounded-lg border-0 bg-gray-100 text-sm ${readonly ? 'cursor-not-allowed' : 'cursor-pointer'}
`, triggerClassName, triggerClassNameFn?.(open))}
title={selectedItem?.name}
>
<span
className={`
grow truncate
- ${!selectedItem?.name && 'text-components-input-text-placeholder'}
+ ${!selectedItem?.name && 'text-gray-400'}
`}
>
{selectedItem?.name ?? localPlaceholder}
</span>
- <div className='mx-0.5'>{installedValue && selectedItem && selectedItem.value !== installedValue && <Badge>{installedValue} {'->'} {selectedItem.value} </Badge>}</div>
- <ChevronDownIcon className='h-4 w-4 shrink-0 text-text-quaternary group-hover:text-text-secondary' />
+ <ChevronDownIcon className='shrink-0 h-4 w-4 text-gray-400' />
</div>
)}
</PortalToFollowElemTrigger>
<PortalToFollowElemContent className={`z-20 ${popupClassName}`}>
<div
- className={classNames('px-1 py-1 max-h-60 overflow-auto rounded-md text-base shadow-lg border-components-panel-border bg-components-panel-bg border-[0.5px] focus:outline-none sm:text-sm', popupInnerClassName)}
+ className={classNames('px-1 py-1 max-h-60 overflow-auto rounded-md bg-white text-base shadow-lg border-gray-200 border-[0.5px] focus:outline-none sm:text-sm', popupInnerClassName)}
>
{items.map((item: Item) => (
<div
key={item.value}
className={`
- flex h-9 cursor-pointer items-center justify-between rounded-lg px-2.5 text-text-secondary hover:bg-state-base-hover
- ${item.value === value && 'bg-state-base-hover'}
+ flex items-center justify-between px-2.5 h-9 cursor-pointer rounded-lg hover:bg-gray-100 text-gray-700
+ ${item.value === value && 'bg-gray-100'}
`}
title={item.name}
onClick={() => {
@@ -363,13 +367,10 @@
className='w-0 grow truncate'
title={item.name}
>
- <span className='truncate'>{item.name}</span>
- {item.value === installedValue && (
- <Badge uppercase={true} className='ml-1 shrink-0'>INSTALLED</Badge>
- )}
+ {item.name}
</span>
{!hideChecked && item.value === value && (
- <RiCheckLine className='h-4 w-4 shrink-0 text-text-accent' />
+ <RiCheckLine className='shrink-0 h-4 w-4 text-text-accent' />
)}
</div>
))}
--
Gitblit v1.8.0