fix(web): Kalender-Tooltip bricht lange Termintitel um (Breite/Klemmung aus einer Konstante)
- Titel-Span im Tooltip: min-w-0 break-words statt truncate - Breite (288px) und Rand-Klemmung aus TOOLTIP_WIDTH_PX/TOOLTIP_EDGE_PX - Test 4c: belegt Klassen und Tooltip-Breite Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -200,6 +200,35 @@ describe('CalendarWidget', () => {
|
|||||||
expect(tooltip).not.toHaveTextContent('e6');
|
expect(tooltip).not.toHaveTextContent('e6');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Test 4c: Tooltip bricht lange Termintitel um statt sie abzuschneiden', async () => {
|
||||||
|
mockFetchEvents.mockResolvedValue([
|
||||||
|
ev(
|
||||||
|
'Deutscher Weltkindertag (Aktionstag der Kinderrechte)',
|
||||||
|
new Date(2026, 6, 20, 9, 0),
|
||||||
|
new Date(2026, 6, 20, 10, 0),
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const { CalendarWidget } = await import('./calendar-widget');
|
||||||
|
render(<CalendarWidget instanceId="cal-4c" config={{}} isEditMode={false} />);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(screen.getByText('Juli 2026')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
const day20 = document.querySelector('[data-date="2026-07-20"]') as HTMLElement;
|
||||||
|
fireEvent.mouseEnter(day20);
|
||||||
|
|
||||||
|
const tooltip = screen.getByTestId('calendar-day-tooltip');
|
||||||
|
const title = within(tooltip).getByText(
|
||||||
|
'Deutscher Weltkindertag (Aktionstag der Kinderrechte)',
|
||||||
|
);
|
||||||
|
expect(title).toHaveClass('break-words');
|
||||||
|
expect(title).toHaveClass('min-w-0');
|
||||||
|
expect(title).not.toHaveClass('truncate');
|
||||||
|
expect(tooltip).toHaveStyle({ width: '288px' });
|
||||||
|
});
|
||||||
|
|
||||||
it('Test 5: Naechste Termine respektiert maxEvents, Reihenfolge und zeigt Ort/Farbpunkt', async () => {
|
it('Test 5: Naechste Termine respektiert maxEvents, Reihenfolge und zeigt Ort/Farbpunkt', async () => {
|
||||||
mockFetchEvents.mockResolvedValue([
|
mockFetchEvents.mockResolvedValue([
|
||||||
ev('E1', new Date(2026, 6, 16, 9, 0), new Date(2026, 6, 16, 10, 0)),
|
ev('E1', new Date(2026, 6, 16, 9, 0), new Date(2026, 6, 16, 10, 0)),
|
||||||
|
|||||||
@@ -18,6 +18,12 @@ import {
|
|||||||
WEEKDAY_LABELS,
|
WEEKDAY_LABELS,
|
||||||
} from './calendar-month';
|
} from './calendar-month';
|
||||||
|
|
||||||
|
// quick-260916-j4f: Breite und Rand-Klemmung des Termin-Tooltips aus einer
|
||||||
|
// Quelle, damit Breite und Klemmwert nicht auseinanderlaufen; 288 px
|
||||||
|
// entspricht Tailwind w-72.
|
||||||
|
const TOOLTIP_WIDTH_PX = 288;
|
||||||
|
const TOOLTIP_EDGE_PX = 4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calendar widget (DASH-05, D-10 read-only), neu gebaut nach dem Vorbild des
|
* Calendar widget (DASH-05, D-10 read-only), neu gebaut nach dem Vorbild des
|
||||||
* alten persoenlichen Dashboards des Anwenders (quick-260916-htc).
|
* alten persoenlichen Dashboards des Anwenders (quick-260916-htc).
|
||||||
@@ -30,7 +36,9 @@ import {
|
|||||||
*
|
*
|
||||||
* Der Tooltip wird per `createPortal` in `document.body` gerendert, weil die
|
* Der Tooltip wird per `createPortal` in `document.body` gerendert, weil die
|
||||||
* Karte in widget-wrapper.tsx `overflow-hidden` traegt und ein absolut
|
* Karte in widget-wrapper.tsx `overflow-hidden` traegt und ein absolut
|
||||||
* positionierter Tooltip sonst abgeschnitten wuerde.
|
* positionierter Tooltip sonst abgeschnitten wuerde. Titel im Tooltip
|
||||||
|
* brechen um (kein truncate); Breite/Klemmung kommen aus
|
||||||
|
* `TOOLTIP_WIDTH_PX`/`TOOLTIP_EDGE_PX` (quick-260916-j4f).
|
||||||
*
|
*
|
||||||
* Das Ladefenster ist IMMER auf lokale Tagesgrenzen gerundet
|
* Das Ladefenster ist IMMER auf lokale Tagesgrenzen gerundet
|
||||||
* (`computeFetchWindow`), damit der Backend-Cache-Schluessel
|
* (`computeFetchWindow`), damit der Backend-Cache-Schluessel
|
||||||
@@ -293,10 +301,14 @@ export function CalendarWidget({ config }: WidgetProps) {
|
|||||||
<div
|
<div
|
||||||
data-testid="calendar-day-tooltip"
|
data-testid="calendar-day-tooltip"
|
||||||
role="tooltip"
|
role="tooltip"
|
||||||
className="pointer-events-none fixed z-50 w-60 rounded border border-border bg-card p-2 text-xs text-foreground shadow-lg"
|
className="pointer-events-none fixed z-50 rounded border border-border bg-card p-2 text-xs text-foreground shadow-lg"
|
||||||
style={{
|
style={{
|
||||||
top: hover.rect.bottom + 4,
|
width: TOOLTIP_WIDTH_PX,
|
||||||
left: Math.max(4, Math.min(hover.rect.left, window.innerWidth - 244)),
|
top: hover.rect.bottom + TOOLTIP_EDGE_PX,
|
||||||
|
left: Math.max(
|
||||||
|
TOOLTIP_EDGE_PX,
|
||||||
|
Math.min(hover.rect.left, window.innerWidth - TOOLTIP_WIDTH_PX - TOOLTIP_EDGE_PX),
|
||||||
|
),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{hoverEvents.slice(0, 5).map((event) => (
|
{hoverEvents.slice(0, 5).map((event) => (
|
||||||
@@ -304,7 +316,7 @@ export function CalendarWidget({ config }: WidgetProps) {
|
|||||||
<span className="shrink-0 tabular-nums text-muted-foreground">
|
<span className="shrink-0 tabular-nums text-muted-foreground">
|
||||||
{event.allDay ? t('calendar.allDay') : formatEventTime(event.start)}
|
{event.allDay ? t('calendar.allDay') : formatEventTime(event.start)}
|
||||||
</span>
|
</span>
|
||||||
<span className="truncate">{event.title}</span>
|
<span className="min-w-0 break-words">{event.title}</span>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
{hoverEvents.length > 5 && (
|
{hoverEvents.length > 5 && (
|
||||||
|
|||||||
Reference in New Issue
Block a user