feat(ui): 替换原生下拉控件
This commit is contained in:
+61
-6
@@ -1,3 +1,5 @@
|
||||
import * as RadixSelect from '@radix-ui/react-select'
|
||||
import { Check, ChevronDown } from 'lucide-react'
|
||||
import type { ComponentPropsWithoutRef, ReactNode } from 'react'
|
||||
|
||||
type Variant = 'default' | 'muted' | 'success' | 'warning' | 'danger' | 'info'
|
||||
@@ -72,17 +74,70 @@ export function Input({ className, ...props }: ComponentPropsWithoutRef<'input'>
|
||||
)
|
||||
}
|
||||
|
||||
export function Select({ className, children, ...props }: ComponentPropsWithoutRef<'select'>) {
|
||||
export function Select({
|
||||
value,
|
||||
onValueChange,
|
||||
children,
|
||||
className,
|
||||
id,
|
||||
}: {
|
||||
value?: string | number
|
||||
onValueChange?: (value: string) => void
|
||||
children: ReactNode
|
||||
className?: string
|
||||
id?: string
|
||||
}) {
|
||||
return (
|
||||
<select
|
||||
<RadixSelect.Root value={value?.toString()} onValueChange={onValueChange}>
|
||||
<RadixSelect.Trigger
|
||||
id={id}
|
||||
className={cn(
|
||||
'flex h-10 w-full items-center justify-between gap-2 rounded-lg border border-white/10 bg-zinc-950/95 px-3 py-2 text-sm text-zinc-100 outline-none transition-colors focus:border-teal-400/60 focus:ring-2 focus:ring-teal-400/10 data-[placeholder]:text-zinc-500',
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<RadixSelect.Value />
|
||||
<RadixSelect.Icon asChild>
|
||||
<ChevronDown className="size-4 opacity-50" />
|
||||
</RadixSelect.Icon>
|
||||
</RadixSelect.Trigger>
|
||||
<RadixSelect.Portal>
|
||||
<RadixSelect.Content
|
||||
className="relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-lg border border-white/10 bg-zinc-950 text-zinc-100 shadow-xl shadow-black/40"
|
||||
position="popper"
|
||||
sideOffset={4}
|
||||
>
|
||||
<RadixSelect.Viewport className="p-1">{children}</RadixSelect.Viewport>
|
||||
</RadixSelect.Content>
|
||||
</RadixSelect.Portal>
|
||||
</RadixSelect.Root>
|
||||
)
|
||||
}
|
||||
|
||||
export function SelectOption({
|
||||
value,
|
||||
children,
|
||||
className,
|
||||
}: {
|
||||
value: string | number
|
||||
children: ReactNode
|
||||
className?: string
|
||||
}) {
|
||||
return (
|
||||
<RadixSelect.Item
|
||||
value={value.toString()}
|
||||
className={cn(
|
||||
'h-10 rounded-lg border border-white/10 bg-zinc-950/95 px-3 py-2 text-sm text-zinc-100 outline-none transition-colors [color-scheme:dark] focus:border-teal-400/60 focus:ring-2 focus:ring-teal-400/10',
|
||||
'relative flex w-full cursor-default select-none items-center rounded-md py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-white/10 focus:text-zinc-50 data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</select>
|
||||
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
|
||||
<RadixSelect.ItemIndicator>
|
||||
<Check className="size-4" />
|
||||
</RadixSelect.ItemIndicator>
|
||||
</span>
|
||||
<RadixSelect.ItemText>{children}</RadixSelect.ItemText>
|
||||
</RadixSelect.Item>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user