feat(selection): 重构选股结果筛选与状态入口

This commit is contained in:
yuxuanhui
2026-08-10 14:50:56 +08:00
parent 78be0f53d4
commit 8d4f80f2f1
17 changed files with 1123 additions and 156 deletions
+200
View File
@@ -0,0 +1,200 @@
import { Check, ChevronDown, ChevronUp } from "lucide-react"
import { Select as SelectPrimitive } from "@base-ui/react/select"
import { cn } from "@/shared/ui/utils"
function Select<Value, Multiple extends boolean | undefined = false>(
props: SelectPrimitive.Root.Props<Value, Multiple>,
) {
return <SelectPrimitive.Root data-slot="select" {...props} />
}
function SelectGroup({ className, ...props }: SelectPrimitive.Group.Props) {
return (
<SelectPrimitive.Group
data-slot="select-group"
className={cn("p-1", className)}
{...props}
/>
)
}
function SelectLabel({
className,
...props
}: SelectPrimitive.GroupLabel.Props) {
return (
<SelectPrimitive.GroupLabel
data-slot="select-label"
className={cn(
"px-2 py-1.5 text-xs font-medium text-muted-foreground",
className,
)}
{...props}
/>
)
}
function SelectTrigger({
className,
children,
size = "default",
...props
}: SelectPrimitive.Trigger.Props & {
size?: "sm" | "default"
}) {
return (
<SelectPrimitive.Trigger
data-slot="select-trigger"
data-size={size}
className={cn(
"flex w-full items-center justify-between gap-2 rounded-lg border border-input bg-transparent px-2.5 text-sm whitespace-nowrap outline-none transition-colors focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 data-[placeholder]:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 [&>span]:line-clamp-1 [&>svg]:pointer-events-none [&>svg]:size-4 [&>svg]:shrink-0",
className,
)}
{...props}
>
{children}
<SelectPrimitive.Icon
data-slot="select-icon"
className="text-muted-foreground"
>
<ChevronDown aria-hidden="true" />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
)
}
function SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {
return (
<SelectPrimitive.Value
data-slot="select-value"
className={cn("line-clamp-1", className)}
{...props}
/>
)
}
function SelectContent({
className,
children,
sideOffset = 4,
...props
}: SelectPrimitive.Popup.Props & {
sideOffset?: number
}) {
return (
<SelectPrimitive.Portal>
<SelectPrimitive.Positioner
data-slot="select-positioner"
sideOffset={sideOffset}
className="z-50 outline-none"
>
<SelectPrimitive.Popup
data-slot="select-content"
className={cn(
"relative z-50 max-h-(--available-height) min-w-[8rem] origin-(--transform-origin) overflow-hidden rounded-lg border border-border bg-card text-card-foreground shadow-lg ring-1 ring-foreground/10 outline-none data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
className,
)}
{...props}
>
<SelectScrollUpButton />
<SelectPrimitive.List
data-slot="select-list"
className="max-h-72 overflow-y-auto p-1"
>
{children}
</SelectPrimitive.List>
<SelectScrollDownButton />
</SelectPrimitive.Popup>
</SelectPrimitive.Positioner>
</SelectPrimitive.Portal>
)
}
function SelectItem({
className,
children,
...props
}: SelectPrimitive.Item.Props) {
return (
<SelectPrimitive.Item
data-slot="select-item"
className={cn(
"relative flex min-h-8 w-full cursor-default items-center rounded-md py-1.5 pr-8 pl-2 text-sm outline-none select-none data-[highlighted]:bg-muted data-[highlighted]:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className,
)}
{...props}
>
<span className="absolute right-2 flex size-4 items-center justify-center">
<SelectPrimitive.ItemIndicator data-slot="select-item-indicator">
<Check aria-hidden="true" className="size-4" />
</SelectPrimitive.ItemIndicator>
</span>
<SelectPrimitive.ItemText data-slot="select-item-text">
{children}
</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
)
}
function SelectSeparator({
className,
...props
}: SelectPrimitive.Separator.Props) {
return (
<SelectPrimitive.Separator
data-slot="select-separator"
className={cn("-mx-1 my-1 h-px bg-border", className)}
{...props}
/>
)
}
function SelectScrollUpButton({
className,
...props
}: SelectPrimitive.ScrollUpArrow.Props) {
return (
<SelectPrimitive.ScrollUpArrow
data-slot="select-scroll-up-button"
className={cn(
"flex h-6 items-center justify-center bg-card text-muted-foreground",
className,
)}
{...props}
>
<ChevronUp aria-hidden="true" className="size-4" />
</SelectPrimitive.ScrollUpArrow>
)
}
function SelectScrollDownButton({
className,
...props
}: SelectPrimitive.ScrollDownArrow.Props) {
return (
<SelectPrimitive.ScrollDownArrow
data-slot="select-scroll-down-button"
className={cn(
"flex h-6 items-center justify-center bg-card text-muted-foreground",
className,
)}
{...props}
>
<ChevronDown aria-hidden="true" className="size-4" />
</SelectPrimitive.ScrollDownArrow>
)
}
export {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectScrollDownButton,
SelectScrollUpButton,
SelectSeparator,
SelectTrigger,
SelectValue,
}