feat(ui): select bileşenini geliştir

Scroll butonları, metin kısaltma ve genişlik ayarlamaları ekleyerek
Select bileşenini daha kullanıcı dostu hale getirildi. TimerPage
düzenlemesi yeni özelliklere uyum sağlamak için güncellendi.
This commit is contained in:
2026-01-09 16:52:09 +03:00
parent f6d54ca623
commit 8089a816ad
2 changed files with 104 additions and 45 deletions

View File

@@ -17,6 +17,21 @@ const ChevronDown = ({ className }: { className?: string }) => (
</svg> </svg>
); );
const ChevronUp = ({ className }: { className?: string }) => (
<svg
viewBox="0 0 20 20"
fill="currentColor"
className={className}
aria-hidden="true"
>
<path
fillRule="evenodd"
d="M14.77 12.79a.75.75 0 0 1-1.06-.02L10 8.83l-3.71 3.94a.75.75 0 1 1-1.08-1.04l4.24-4.5a.75.75 0 0 1 1.08 0l4.24 4.5a.75.75 0 0 1-.02 1.06Z"
clipRule="evenodd"
/>
</svg>
);
const Check = ({ className }: { className?: string }) => ( const Check = ({ className }: { className?: string }) => (
<svg <svg
viewBox="0 0 20 20" viewBox="0 0 20 20"
@@ -38,6 +53,8 @@ export const SelectGroup = SelectPrimitive.Group;
export const SelectValue = SelectPrimitive.Value; export const SelectValue = SelectPrimitive.Value;
export const SelectLabel = SelectPrimitive.Label;
export const SelectTrigger = React.forwardRef< export const SelectTrigger = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Trigger>, React.ElementRef<typeof SelectPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger> React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
@@ -45,12 +62,12 @@ export const SelectTrigger = React.forwardRef<
<SelectPrimitive.Trigger <SelectPrimitive.Trigger
ref={ref} ref={ref}
className={clsx( className={clsx(
"flex h-10 items-center justify-between gap-2 rounded-md border border-slate-200 bg-white px-3 text-sm text-slate-700 shadow-sm transition focus:outline-none focus:ring-2 focus:ring-slate-300", "flex h-10 w-full items-center justify-between gap-2 rounded-md border border-slate-200 bg-white px-3 text-sm text-slate-700 shadow-sm transition focus:outline-none focus:ring-2 focus:ring-slate-300 data-[placeholder]:text-slate-400",
className className
)} )}
{...props} {...props}
> >
{children} <span className="line-clamp-1">{children}</span>
<SelectPrimitive.Icon asChild> <SelectPrimitive.Icon asChild>
<ChevronDown className="h-4 w-4 text-slate-400" /> <ChevronDown className="h-4 w-4 text-slate-400" />
</SelectPrimitive.Icon> </SelectPrimitive.Icon>
@@ -58,28 +75,73 @@ export const SelectTrigger = React.forwardRef<
)); ));
SelectTrigger.displayName = "SelectTrigger"; SelectTrigger.displayName = "SelectTrigger";
export const SelectScrollUpButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollUpButton
ref={ref}
className={clsx(
"flex cursor-default items-center justify-center py-1 text-slate-400",
className
)}
{...props}
>
<ChevronUp className="h-4 w-4" />
</SelectPrimitive.ScrollUpButton>
));
SelectScrollUpButton.displayName = "SelectScrollUpButton";
export const SelectScrollDownButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollDownButton
ref={ref}
className={clsx(
"flex cursor-default items-center justify-center py-1 text-slate-400",
className
)}
{...props}
>
<ChevronDown className="h-4 w-4" />
</SelectPrimitive.ScrollDownButton>
));
SelectScrollDownButton.displayName = "SelectScrollDownButton";
export const SelectContent = React.forwardRef< export const SelectContent = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Content>, React.ElementRef<typeof SelectPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content> React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
>(({ className, children, position = "popper", ...props }, ref) => ( >(({ className, children, position = "popper", sideOffset = 4, ...props }, ref) => (
<SelectPrimitive.Portal> <SelectPrimitive.Portal>
<SelectPrimitive.Content <SelectPrimitive.Content
ref={ref} ref={ref}
className={clsx( className={clsx(
"z-50 min-w-[8rem] overflow-hidden rounded-md border border-slate-200 bg-white text-slate-700 shadow-md", "relative z-50 max-h-72 min-w-[8rem] overflow-hidden rounded-md border border-slate-200 bg-white text-slate-700 shadow-md",
className className
)} )}
position={position} position={position}
sideOffset={sideOffset}
{...props} {...props}
> >
<SelectPrimitive.Viewport className="p-1"> <SelectScrollUpButton />
<SelectPrimitive.Viewport
className={clsx(
"p-1",
position === "popper" &&
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
)}
>
{children} {children}
</SelectPrimitive.Viewport> </SelectPrimitive.Viewport>
<SelectScrollDownButton />
</SelectPrimitive.Content> </SelectPrimitive.Content>
</SelectPrimitive.Portal> </SelectPrimitive.Portal>
)); ));
SelectContent.displayName = "SelectContent"; SelectContent.displayName = "SelectContent";
export const SelectSeparator = SelectPrimitive.Separator;
export const SelectItem = React.forwardRef< export const SelectItem = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Item>, React.ElementRef<typeof SelectPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item> React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
@@ -87,7 +149,7 @@ export const SelectItem = React.forwardRef<
<SelectPrimitive.Item <SelectPrimitive.Item
ref={ref} ref={ref}
className={clsx( className={clsx(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-slate-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50", "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-slate-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className className
)} )}
{...props} {...props}
@@ -101,4 +163,3 @@ export const SelectItem = React.forwardRef<
</SelectPrimitive.Item> </SelectPrimitive.Item>
)); ));
SelectItem.displayName = "SelectItem"; SelectItem.displayName = "SelectItem";

View File

@@ -337,7 +337,6 @@ export const TimerPage = () => {
<div className="min-w-0 space-y-6"> <div className="min-w-0 space-y-6">
<Card> <Card>
<CardHeader> <CardHeader>
<div className="flex flex-wrap items-center justify-between gap-3">
<CardTitle className="flex items-center gap-2"> <CardTitle className="flex items-center gap-2">
<FontAwesomeIcon icon={faHourglassHalf} className="text-slate-400" /> <FontAwesomeIcon icon={faHourglassHalf} className="text-slate-400" />
Zamanlayıcı Torrentleri Zamanlayıcı Torrentleri
@@ -353,10 +352,10 @@ export const TimerPage = () => {
} }
}} }}
> >
<SelectTrigger className="h-9 min-w-[180px] text-xs"> <SelectTrigger className="h-9 w-[180px] text-xs">
<SelectValue /> <SelectValue />
</SelectTrigger> </SelectTrigger>
<SelectContent> <SelectContent align="end">
{sortOptions.map((option) => ( {sortOptions.map((option) => (
<SelectItem <SelectItem
key={option.value} key={option.value}
@@ -375,7 +374,6 @@ export const TimerPage = () => {
</SelectContent> </SelectContent>
</Select> </Select>
</div> </div>
</div>
</CardHeader> </CardHeader>
<CardContent className="space-y-4"> <CardContent className="space-y-4">
{sortedMatchingTorrents.length === 0 ? ( {sortedMatchingTorrents.length === 0 ? (