refactor: Update TabBar component for improved styling and functionality

- Replaced `RefreshCw` icon with `RotateCw` for better visual representation of refresh action.
- Adjusted tab height and padding for a more compact design.
- Updated text sizes for tab titles and buttons to enhance readability.
- Improved button sizes and hover effects for a more consistent user experience.
- Enhanced layout structure to ensure proper alignment and spacing of elements.

Made-with: Cursor
This commit is contained in:
syc0123 2026-03-03 10:23:07 +09:00
parent 83437e76dd
commit eb471d087f
1 changed files with 15 additions and 14 deletions

View File

@ -1,7 +1,7 @@
"use client"; "use client";
import React, { useRef, useState, useEffect, useCallback } from "react"; import React, { useRef, useState, useEffect, useCallback } from "react";
import { X, RefreshCw, ChevronDown } from "lucide-react"; import { X, RotateCw, ChevronDown } from "lucide-react";
import { useTabStore, selectTabs, selectActiveTabId, Tab } from "@/stores/tabStore"; import { useTabStore, selectTabs, selectActiveTabId, Tab } from "@/stores/tabStore";
import { menuScreenApi } from "@/lib/api/screen"; import { menuScreenApi } from "@/lib/api/screen";
import { import {
@ -350,33 +350,33 @@ export function TabBar() {
onPointerUp={handlePointerUp} onPointerUp={handlePointerUp}
onContextMenu={(e) => handleContextMenu(e, tab.id)} onContextMenu={(e) => handleContextMenu(e, tab.id)}
className={cn( className={cn(
"group relative flex h-9 shrink-0 cursor-pointer items-center gap-1 rounded-t-lg border border-b-0 px-3 text-sm select-none", "group relative flex h-7 shrink-0 cursor-pointer items-center gap-0.5 rounded-t-md border border-b-0 px-3 select-none",
isActive isActive
? "border-border bg-white text-foreground z-10" ? "border-border bg-white text-foreground z-10 mb-[-1px] h-[30px]"
: "border-transparent bg-muted/50 text-muted-foreground hover:bg-muted hover:text-foreground", : "border-transparent bg-muted/50 text-muted-foreground hover:bg-muted hover:text-foreground",
)} )}
style={{ width: TAB_WIDTH, touchAction: "none", ...animStyle }} style={{ width: TAB_WIDTH, touchAction: "none", ...animStyle }}
title={tab.title} title={tab.title}
> >
<span className="min-w-0 flex-1 truncate text-xs font-medium">{tab.title}</span> <span className="min-w-0 flex-1 truncate text-[11px] font-medium">{tab.title}</span>
<div className="flex shrink-0 items-center gap-0.5"> <div className="flex shrink-0 items-center">
{isActive && ( {isActive && (
<button <button
onClick={(e) => { e.stopPropagation(); refreshTab(tab.id); }} onClick={(e) => { e.stopPropagation(); refreshTab(tab.id); }}
className="text-muted-foreground hover:bg-accent hover:text-foreground flex h-5 w-5 items-center justify-center rounded-sm transition-colors" className="text-muted-foreground hover:bg-accent hover:text-foreground flex h-4 w-4 items-center justify-center rounded-sm transition-colors"
> >
<RefreshCw className="h-3 w-3" /> <RotateCw className="h-2.5 w-2.5" />
</button> </button>
)} )}
<button <button
onClick={(e) => { e.stopPropagation(); closeTab(tab.id); }} onClick={(e) => { e.stopPropagation(); closeTab(tab.id); }}
className={cn( className={cn(
"text-muted-foreground hover:bg-destructive/10 hover:text-destructive flex h-5 w-5 items-center justify-center rounded-sm transition-colors", "text-muted-foreground hover:bg-destructive/10 hover:text-destructive flex h-4 w-4 items-center justify-center rounded-sm transition-colors",
!isActive && "opacity-0 group-hover:opacity-100", !isActive && "opacity-0 group-hover:opacity-100",
)} )}
> >
<X className="h-3 w-3" /> <X className="h-2.5 w-2.5" />
</button> </button>
</div> </div>
</div> </div>
@ -389,19 +389,20 @@ export function TabBar() {
<> <>
<div <div
ref={containerRef} ref={containerRef}
className="border-border bg-muted/30 flex h-[37px] shrink-0 items-end gap-[2px] overflow-hidden border-b px-2 pt-1" className="border-border bg-muted/30 relative flex h-[33px] shrink-0 items-end gap-[2px] overflow-hidden px-1.5"
onDragOver={handleBarDragOver} onDragOver={handleBarDragOver}
onDragLeave={handleBarDragLeave} onDragLeave={handleBarDragLeave}
onDrop={handleBarDrop} onDrop={handleBarDrop}
> >
<div className="border-border pointer-events-none absolute inset-x-0 bottom-0 z-0 border-b" />
{displayVisible.map((tab, i) => renderTab(tab, i))} {displayVisible.map((tab, i) => renderTab(tab, i))}
{hasOverflow && ( {hasOverflow && (
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild>
<button className="bg-muted/50 text-muted-foreground hover:bg-muted hover:text-foreground flex h-9 shrink-0 items-center gap-1 rounded-t-lg border border-b-0 border-transparent px-3 text-xs font-medium transition-colors"> <button className="bg-muted/50 text-muted-foreground hover:bg-muted hover:text-foreground flex h-7 shrink-0 items-center gap-0.5 rounded-t-md border border-b-0 border-transparent px-2 text-[11px] font-medium transition-colors">
+{displayOverflow.length} +{displayOverflow.length}
<ChevronDown className="h-3 w-3" /> <ChevronDown className="h-2.5 w-2.5" />
</button> </button>
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent align="end" className="max-h-[300px] overflow-y-auto"> <DropdownMenuContent align="end" className="max-h-[300px] overflow-y-auto">
@ -425,10 +426,10 @@ export function TabBar() {
{ghostStyle && draggedTab && ( {ghostStyle && draggedTab && (
<div <div
style={ghostStyle} style={ghostStyle}
className="border-primary/50 bg-background rounded-t-lg border border-b-0 px-3 shadow-lg" className="border-primary/50 bg-background rounded-t-md border border-b-0 px-3 shadow-lg"
> >
<div className="flex h-full items-center"> <div className="flex h-full items-center">
<span className="truncate text-xs font-medium">{draggedTab.title}</span> <span className="truncate text-[11px] font-medium">{draggedTab.title}</span>
</div> </div>
</div> </div>
)} )}