Horizontalen Scroll verhindern: Lange Task-Titel werden überall abgeschnitten
continuous-integration/drone/push Build is passing

- Globales overflow-x: hidden auf html/body/#root in index.css
- App.tsx: overflow-x-hidden und min-w-0 auf Hauptcontainer
- TaskCard: Eltern-Task-Titel mit truncate/min-w-0 im Flex-Layout
- KanbanBoard: min-w-0 overflow-hidden auf Spalten-Cards
- FiveMinuteStarter: truncate auf Task-Titel
- HyperfocusGuard: truncate auf Task-Buttons
- TaskBreakdownModal: truncate auf Task- und Subtask-Titel
- NotificationsPage: truncate + min-w-0 auf Benachrichtigungs-Titel
This commit is contained in:
NotiBot
2026-02-03 14:59:40 +01:00
parent 79d5fae97c
commit 8e8b96fcde
8 changed files with 23 additions and 16 deletions
+2 -2
View File
@@ -349,7 +349,7 @@ function AppContent() {
<SidebarProvider>
<AppSidebar user={user} />
<SidebarInset>
<div className={`min-h-screen bg-background flex flex-col ${adhdEnabled ? 'adhd-mode' : ''} ${adhdEnabled && adhdSettings.reducedAnimations ? 'reduced-motion' : ''} ${adhdEnabled && adhdSettings.largerTargets ? 'larger-targets' : ''}`}>
<div className={`min-h-screen bg-background flex flex-col min-w-0 overflow-x-hidden ${adhdEnabled ? 'adhd-mode' : ''} ${adhdEnabled && adhdSettings.reducedAnimations ? 'reduced-motion' : ''} ${adhdEnabled && adhdSettings.largerTargets ? 'larger-targets' : ''}`}>
{/* Mobile Header with Sidebar Toggle */}
<header className="sticky top-0 z-50 flex items-center gap-3 px-4 py-3 bg-background/80 backdrop-blur-xl border-b border-border/50 md:hidden">
<SidebarTrigger className="h-9 w-9" />
@@ -360,7 +360,7 @@ function AppContent() {
<span className="font-bold text-lg">{t('app.title')}</span>
</div>
</header>
<main className="flex-1 p-4 md:p-6 max-w-screen-2xl mx-auto w-full relative">
<main className="flex-1 p-4 md:p-6 max-w-screen-2xl mx-auto w-full relative overflow-x-hidden">
<Switch>
<Route path="/">
<FocusMode
+3 -3
View File
@@ -430,7 +430,7 @@ export default function KanbanBoard({ tasks, onTaskStatusChange, onTaskUpdate, o
return (
<Card
key={column.id}
className="p-3 sm:p-4"
className="p-3 sm:p-4 min-w-0 overflow-hidden"
onDragOver={handleDragOver}
onDrop={() => handleDrop(column.status)}
data-testid={`column-${column.id}`}
@@ -494,7 +494,7 @@ export default function KanbanBoard({ tasks, onTaskStatusChange, onTaskUpdate, o
return (
<Card
key={column.id}
className="p-3 sm:p-4"
className="p-3 sm:p-4 min-w-0 overflow-hidden"
onDragOver={handleDragOver}
onDrop={() => handleDrop(column.status)}
data-testid={`column-${column.id}`}
@@ -558,7 +558,7 @@ export default function KanbanBoard({ tasks, onTaskStatusChange, onTaskUpdate, o
return (
<Card
key={column.id}
className="p-3 sm:p-4"
className="p-3 sm:p-4 min-w-0 overflow-hidden"
onDragOver={handleDragOver}
onDrop={() => handleDrop(column.status)}
data-testid={`column-${column.id}`}
+4 -4
View File
@@ -351,10 +351,10 @@ export default function TaskCard({ task, onStartTimer, onStopTimer, onEdit, onDe
{/* Parent Task Link rendered in title now */}
<h3 className={`font-medium text-sm leading-tight truncate ${task.status === 'done' ? 'line-through' : ''}`} data-testid={`text-task-title-${task.id}`}>
{parentTask ? (
<span className="flex items-center gap-1">
<span className="text-muted-foreground font-normal">{parentTask.title}</span>
<span className="text-muted-foreground"></span>
<span>{task.title}</span>
<span className="flex items-center gap-1 min-w-0">
<span className="text-muted-foreground font-normal truncate shrink">{parentTask.title}</span>
<span className="text-muted-foreground shrink-0"></span>
<span className="truncate shrink">{task.title}</span>
</span>
) : (
task.title
@@ -125,7 +125,7 @@ export function TaskBreakdownModal({ task, open, onOpenChange }: TaskBreakdownMo
{/* Task info */}
<div className="bg-muted/50 rounded-lg p-4 mb-4">
<h4 className="font-medium mb-1">{task.title}</h4>
<h4 className="font-medium mb-1 truncate">{task.title}</h4>
{task.description && (
<p className="text-sm text-muted-foreground">{task.description}</p>
)}
@@ -195,8 +195,8 @@ export function TaskBreakdownModal({ task, open, onOpenChange }: TaskBreakdownMo
onCheckedChange={() => handleToggleSubtask(index)}
className="mt-0.5"
/>
<div className="flex-1">
<p className="font-medium text-sm">{subtask.title}</p>
<div className="flex-1 min-w-0">
<p className="font-medium text-sm truncate">{subtask.title}</p>
<div className="flex items-center gap-1 mt-1 text-xs text-muted-foreground">
<Clock className="h-3 w-3" />
<span>~{subtask.estimatedMinutes} min</span>
@@ -117,7 +117,7 @@ export function FiveMinuteStarter({
<h3 className="text-xl font-bold mb-2">
{t('adhd.fiveMin.title')}
</h3>
<p className="text-muted-foreground mb-2">
<p className="text-muted-foreground mb-2 truncate max-w-full">
{task.title}
</p>
<p className="text-sm text-muted-foreground mb-6">
@@ -147,6 +147,7 @@ export function HyperfocusGuard({ activeTaskId, onTaskStart }: HyperfocusGuardPr
hover:bg-amber-200 dark:hover:bg-amber-900
transition-colors text-sm
text-amber-900 dark:text-amber-100
truncate
`}
>
{task.title}
+6
View File
@@ -2,6 +2,12 @@
@tailwind components;
@tailwind utilities;
/* Prevent horizontal scroll globally */
html, body, #root {
overflow-x: hidden;
max-width: 100vw;
}
/* LIGHT MODE */
:root {
--button-outline: rgba(0,0,0, .10);
+3 -3
View File
@@ -110,9 +110,9 @@ export default function NotificationsPage() {
<div className={`p-2 rounded-full shrink-0 ${notif.type === 'overdue' ? 'bg-red-100 text-red-600 dark:bg-red-900/30 dark:text-red-400' : 'bg-blue-100 text-blue-600 dark:bg-blue-900/30 dark:text-blue-400'}`}>
{notif.type === 'overdue' ? <AlertCircle className="h-5 w-5" /> : <Calendar className="h-5 w-5" />}
</div>
<div className="flex-1">
<div className="flex items-center justify-between">
<h3 className="font-semibold">{notif.task.title}</h3>
<div className="flex-1 min-w-0">
<div className="flex items-center justify-between gap-2">
<h3 className="font-semibold truncate">{notif.task.title}</h3>
<span className="text-xs text-muted-foreground whitespace-nowrap">
{formatDistanceToNow(notif.timestamp, { addSuffix: true, locale: i18n.language === 'de' ? de : enUS })}
</span>