Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend/src/components/ui/DateTimePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export function DateTimePicker({
const base = selectedDate ?? new Date();
onChange(dateToIso(base, h, m));
}}
className="border-border bg-surface focus:border-brand-500 focus:ring-brand-200 h-8 rounded-md border px-2 text-sm outline-none focus:ring-1"
className="border-border bg-surface focus:border-brand-500 focus:ring-brand-200 h-8 rounded-md border px-2 text-base outline-none focus:ring-1 md:text-sm"
/>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/ui/LocationField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export function LocationField({
maxLength={maxLength}
placeholder={placeholder}
className={[
'bg-surface h-10 w-full rounded-md border px-3 text-sm transition-colors outline-none focus:ring-2',
'bg-surface h-10 w-full rounded-md border px-3 text-base transition-colors outline-none focus:ring-2 md:text-sm',
'border-border-strong focus:border-brand-500 focus:ring-brand-200',
error && 'border-destructive-border focus:border-red-500 focus:ring-red-100',
disabled && 'bg-surface-dim text-muted-foreground',
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/ui/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const Select = forwardRef<HTMLSelectElement, Props>(function Select(
aria-invalid={error ? true : undefined}
aria-describedby={error ? `${inputId}-error` : undefined}
className={cn(
'border-border-strong bg-surface focus:ring-border h-10 w-full appearance-none rounded-md border pr-9 pl-3 text-sm transition-colors outline-none focus:border-neutral-500 focus:ring-2',
'border-border-strong bg-surface focus:ring-border h-10 w-full appearance-none rounded-md border pr-9 pl-3 text-base transition-colors outline-none focus:border-neutral-500 focus:ring-2 md:text-sm',
error && 'border-destructive-border focus:border-red-500 focus:ring-red-100',
className,
)}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/ui/TextField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const TextField = forwardRef<HTMLInputElement, Props>(function TextField(
aria-invalid={error ? true : undefined}
aria-describedby={describedBy}
className={cn(
'focus:border-brand-500 focus:ring-brand-200 border-border-strong bg-surface h-10 w-full rounded-md border px-3 text-sm transition-colors outline-none focus:ring-2',
'focus:border-brand-500 focus:ring-brand-200 border-border-strong bg-surface h-10 w-full rounded-md border px-3 text-base transition-colors outline-none focus:ring-2 md:text-sm',
error && 'border-destructive-border focus:border-red-500 focus:ring-red-100',
rightAdornment && 'pr-10',
className,
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/ui/Textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const Textarea = forwardRef<HTMLTextAreaElement, Props>(function Textarea
aria-invalid={error ? true : undefined}
aria-describedby={describedBy}
className={cn(
'focus:border-brand-500 focus:ring-brand-200 border-border-strong bg-surface min-h-[80px] w-full rounded-md border px-3 py-2 text-sm transition-colors outline-none focus:ring-2',
'focus:border-brand-500 focus:ring-brand-200 border-border-strong bg-surface min-h-[80px] w-full rounded-md border px-3 py-2 text-base transition-colors outline-none focus:ring-2 md:text-sm',
error && 'border-destructive-border focus:border-red-500 focus:ring-red-100',
className,
)}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/screens/events/EmailBlastDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export function EmailBlastDialog({ event, open, onClose }: Props) {
onChange={(e) => {
setMessage(e.target.value);
}}
className="border-border-strong bg-surface focus:ring-brand-200 focus:border-brand-500 h-32 w-full rounded-md border px-3 py-2 text-sm transition-colors outline-none focus:ring-2"
className="border-border-strong bg-surface focus:ring-brand-200 focus:border-brand-500 h-32 w-full rounded-md border px-3 py-2 text-base transition-colors outline-none focus:ring-2 md:text-sm"
/>
</div>
<div className="flex flex-col gap-1.5">
Expand Down
41 changes: 41 additions & 0 deletions frontend/src/screens/events/EventMemberSection.overflow.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { describe, expect, it } from 'vitest';

import type { Event } from '@/models/event';

import { CostSection, LinksSection, LocationSection } from './EventMemberSection';

const LONG_TOKEN = 'x'.repeat(200);

function renderIn(node: React.ReactElement) {
return render(<MemoryRouter>{node}</MemoryRouter>);
}

describe('event detail — long user content wraps (issue 1131)', () => {
it('wraps a long location so it cannot overflow the viewport', () => {
const event = { location: `somewhere/${LONG_TOKEN}` } as Event;
renderIn(<LocationSection event={event} />);
const link = screen.getByRole('link');
expect(link).toHaveClass('break-words', '[overflow-wrap:anywhere]');
});

it('wraps a long other-link label so it cannot overflow the viewport', () => {
const event = {
otherLink: `https://example.com/${LONG_TOKEN}`,
surveySlugs: [],
} as unknown as Event;
renderIn(<LinksSection event={event} />);
const link = screen.getByRole('link');
expect(link).toHaveClass('break-words', '[overflow-wrap:anywhere]');
});

it('wraps long zelle info so it cannot overflow the viewport', () => {
const event = { zelleInfo: LONG_TOKEN } as Event;
renderIn(<CostSection event={event} />);
expect(screen.getByText(new RegExp(LONG_TOKEN.slice(0, 40)))).toHaveClass(
'break-words',
'[overflow-wrap:anywhere]',
);
});
});
10 changes: 6 additions & 4 deletions frontend/src/screens/events/EventMemberSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export function LocationSection({ event }: { event: Event }) {
target="_blank"
rel="noopener noreferrer"
aria-label={`open ${event.location} in maps`}
className="text-brand-700 hover:text-brand-900 text-sm"
className="text-brand-700 hover:text-brand-900 text-sm [overflow-wrap:anywhere] break-words"
>
{primary}
</a>
Expand All @@ -135,7 +135,7 @@ export function LinksSection({ event }: { event: Event }) {
href={l.url}
target="_blank"
rel="noopener noreferrer"
className="text-brand-700 hover:text-brand-900"
className="text-brand-700 hover:text-brand-900 [overflow-wrap:anywhere] break-words"
>
{l.label}
</a>
Expand Down Expand Up @@ -170,12 +170,14 @@ export function CostSection({ event }: { event: Event }) {
href={item.url}
target="_blank"
rel="noopener noreferrer"
className="text-brand-700 hover:text-brand-900"
className="text-brand-700 hover:text-brand-900 [overflow-wrap:anywhere] break-words"
>
{item.label}
</a>
) : (
<span className="text-foreground">{item.label}</span>
<span className="text-foreground [overflow-wrap:anywhere] break-words">
{item.label}
</span>
)}
</li>
))}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/screens/events/comments/CommentComposer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function CommentComposer({
void submit();
}
}}
className="focus:border-brand-500 focus:ring-brand-200 border-border-strong bg-surface min-h-[80px] w-full rounded-md border px-3 py-2 text-sm transition-colors outline-none focus:ring-2"
className="focus:border-brand-500 focus:ring-brand-200 border-border-strong bg-surface min-h-[80px] w-full rounded-md border px-3 py-2 text-base transition-colors outline-none focus:ring-2 md:text-sm"
/>
<div className="flex items-center justify-between">
<span
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/screens/events/comments/CommentItem.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ describe('CommentItem', () => {
expect(screen.getByText('Alice')).toBeInTheDocument();
});

it('wraps a long unbroken body so it cannot overflow the viewport', () => {
const longToken = `https://example.com/${'x'.repeat(200)}`;
wrap(
<CommentItem comment={{ ...baseComment, body: longToken }} eventId="evt" canReact canReply />,
);
expect(screen.getByText(longToken)).toHaveClass('break-words', '[overflow-wrap:anywhere]');
});

it('renders [deleted] placeholder when isDeleted', () => {
wrap(
<CommentItem
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/screens/events/comments/CommentItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ export function CommentItem({
{comment.isDeleted ? (
<p className="text-foreground-tertiary text-sm italic">[deleted]</p>
) : (
<p className="text-sm whitespace-pre-wrap">{comment.body}</p>
<p className="text-sm [overflow-wrap:anywhere] break-words whitespace-pre-wrap">
{comment.body}
</p>
)}
{!comment.isDeleted ? (
<div className="flex items-center justify-between gap-2">
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/screens/events/comments/ReplyItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ export function ReplyItem({ reply, eventId, token, canReact, reactDisabledReason
{reply.isDeleted ? (
<p className="text-foreground-tertiary text-sm italic">[deleted]</p>
) : (
<p className="text-sm whitespace-pre-wrap">{reply.body}</p>
<p className="text-sm [overflow-wrap:anywhere] break-words whitespace-pre-wrap">
{reply.body}
</p>
)}
{!reply.isDeleted ? (
<div className="mt-1 flex items-center justify-between gap-2">
Expand Down
Loading