Merge pull request #693 from AutoMaker-Org/feature/bug-fix-columns-overflow-title-wrap-t6j1

Fix: Column header overflow and title wrapping in Kanban board
This commit is contained in:
Shirone
2026-01-25 11:29:13 +00:00
committed by GitHub
4 changed files with 51 additions and 34 deletions

View File

@@ -78,7 +78,9 @@ export const KanbanColumn = memo(function KanbanColumn({
)}
>
<div className={cn('w-2.5 h-2.5 rounded-full shrink-0', colorClass)} />
<h3 className="font-semibold text-sm text-foreground/90 flex-1 tracking-tight">{title}</h3>
<h3 className="font-semibold text-sm text-foreground/90 flex-1 tracking-tight whitespace-nowrap">
{title}
</h3>
{headerAction}
<span className="text-xs font-medium text-muted-foreground/80 bg-muted/50 px-2 py-0.5 rounded-md tabular-nums">
{count}

View File

@@ -132,7 +132,7 @@ const SortableColumnHeader = memo(function SortableColumnHeader({
)}
data-testid={`list-header-${column.id}`}
>
<span>{column.label}</span>
<span className="whitespace-nowrap truncate">{column.label}</span>
<SortIcon column={column.id} sortConfig={sortConfig} />
</div>
);
@@ -156,7 +156,7 @@ const StaticColumnHeader = memo(function StaticColumnHeader({ column }: { column
)}
data-testid={`list-header-${column.id}`}
>
<span>{column.label}</span>
<span className="whitespace-nowrap truncate">{column.label}</span>
</div>
);
});

View File

@@ -12,7 +12,8 @@ import { SortableContext, verticalListSortingStrategy } from '@dnd-kit/sortable'
import { Button } from '@/components/ui/button';
import { KanbanColumn, KanbanCard, EmptyStateCard } from './components';
import { Feature, useAppStore, formatShortcut } from '@/store/app-store';
import { Archive, Settings2, CheckSquare, GripVertical, Plus } from 'lucide-react';
import { Archive, Settings2, CheckSquare, GripVertical, Plus, CheckCircle2 } from 'lucide-react';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
import { useResponsiveKanban } from '@/hooks/use-responsive-kanban';
import { getColumnsWithPipeline, type ColumnId } from './constants';
import type { PipelineConfig } from '@automaker/types';
@@ -357,35 +358,49 @@ export function KanbanBoard({
contentClassName="perf-contain"
headerAction={
column.id === 'verified' ? (
<div className="flex items-center gap-1">
{columnFeatures.length > 0 && (
<Button
variant="ghost"
size="sm"
className="h-6 px-2 text-xs"
onClick={onArchiveAllVerified}
data-testid="archive-all-verified-button"
>
<Archive className="w-3 h-3 mr-1" />
Complete All
</Button>
)}
<Button
variant="ghost"
size="sm"
className="h-6 w-6 p-0 relative"
onClick={onShowCompletedModal}
title={`Completed Features (${completedCount})`}
data-testid="completed-features-button"
>
<Archive className="w-3.5 h-3.5 text-muted-foreground" />
{completedCount > 0 && (
<span className="absolute -top-1 -right-1 bg-brand-500 text-white text-[8px] font-bold rounded-full w-3.5 h-3.5 flex items-center justify-center">
{completedCount > 99 ? '99+' : completedCount}
</span>
<TooltipProvider>
<div className="flex items-center gap-1">
{columnFeatures.length > 0 && (
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="sm"
className="h-6 w-6 p-0"
onClick={onArchiveAllVerified}
data-testid="archive-all-verified-button"
>
<CheckCircle2 className="w-3.5 h-3.5" />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Complete All</p>
</TooltipContent>
</Tooltip>
)}
</Button>
</div>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
size="sm"
className="h-6 w-6 p-0 relative"
onClick={onShowCompletedModal}
data-testid="completed-features-button"
>
<Archive className="w-3.5 h-3.5 text-muted-foreground" />
{completedCount > 0 && (
<span className="absolute -top-1 -right-1 bg-brand-500 text-white text-[8px] font-bold rounded-full w-3.5 h-3.5 flex items-center justify-center">
{completedCount > 99 ? '99+' : completedCount}
</span>
)}
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Completed Features ({completedCount})</p>
</TooltipContent>
</Tooltip>
</div>
</TooltipProvider>
) : column.id === 'backlog' ? (
<div className="flex items-center gap-1">
<Button

View File

@@ -14,8 +14,8 @@ export interface ResponsiveKanbanConfig {
* Default configuration for responsive Kanban columns
*/
const DEFAULT_CONFIG: ResponsiveKanbanConfig = {
columnWidth: 288, // 18rem = 288px (w-72)
columnMinWidth: 280, // Minimum column width - ensures usability
columnWidth: 320, // Increased from 288px to accommodate longer column titles
columnMinWidth: 320, // Increased from 280px to prevent title overflow
columnMaxWidth: Infinity, // No max width - columns scale evenly to fill viewport
gap: 20, // gap-5 = 20px
padding: 40, // px-5 on both sides = 40px (matches gap between columns)