Hold every calendar cell to the same size
A calendar whose boxes resize is not a calendar. Each week row is its own grid, and a bare 1fr track takes its minimum from its content, so the one week containing "Alla helgons dag" had its seven cells squeezed while every other week's stayed wide. The tracks are now minmax(0, 1fr) and the cell, the day and the holiday name each refuse to contribute an intrinsic width; the name clips to an ellipsis and keeps its full text in the title. Row height follows the same rule: the band lanes are reserved from the month's tallest week rather than each row's own, so a week with no leave in it stands as tall as the week beside it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ei7gCZzdd751uZtPzb1Pep
This commit is contained in:
@@ -600,6 +600,71 @@ describe('CalendarWeek', () => {
|
||||
expect(week.style.getPropertyValue('--band-reserved-height')).toBe('0px')
|
||||
})
|
||||
|
||||
describe('monthMaxLaneCount: uniform row height across the month', () => {
|
||||
it('reserves height for a week with NO bands of its own when given a month-wide max from other weeks', () => {
|
||||
// Calendar.tsx computes the max lane count across every week in the
|
||||
// displayed month and passes it down uniformly — a quiet week must
|
||||
// still reserve as much bottom padding as the tallest week, so
|
||||
// every row in the month renders the same height.
|
||||
const { container } = render(<CalendarWeek {...defaultProps} plannedDays={[]} monthMaxLaneCount={2} />)
|
||||
const week = container.querySelector('.calendar-week') as HTMLElement
|
||||
// bandBottomInset(4) + 2 lanes * (barHeight(20) + laneGap(2)) = 48px
|
||||
expect(week.style.getPropertyValue('--band-reserved-height')).toBe('48px')
|
||||
})
|
||||
|
||||
it('does not shrink below what this week\'s own bands need, even if monthMaxLaneCount is smaller', () => {
|
||||
// Defensive floor: monthMaxLaneCount is always computed as the max
|
||||
// over all weeks including this one, so it should never actually be
|
||||
// smaller than this week's own lane count — but the component must
|
||||
// not let a band get squeezed if it somehow were.
|
||||
const plannedDays = [
|
||||
pd({ id: '1', date: '2026-01-05', parentPersonalDataUuid: 'parent-1' }),
|
||||
pd({ id: '2', date: '2026-01-05', parentPersonalDataUuid: 'other-parent' }),
|
||||
]
|
||||
const { container } = render(
|
||||
<CalendarWeek {...defaultProps} plannedDays={plannedDays} monthMaxLaneCount={0} />,
|
||||
)
|
||||
const week = container.querySelector('.calendar-week') as HTMLElement
|
||||
// This week's own 2 lanes win over the smaller monthMaxLaneCount.
|
||||
expect(week.style.getPropertyValue('--band-reserved-height')).toBe('48px')
|
||||
})
|
||||
|
||||
it('falls back to this week\'s own lane count when monthMaxLaneCount is omitted (single-week render)', () => {
|
||||
const plannedDays = [pd({ id: '1', date: '2026-01-05' })]
|
||||
const { container } = render(<CalendarWeek {...defaultProps} plannedDays={plannedDays} />)
|
||||
const week = container.querySelector('.calendar-week') as HTMLElement
|
||||
// bandBottomInset(4) + 1 lane * (barHeight(20) + laneGap(2)) = 26px
|
||||
expect(week.style.getPropertyValue('--band-reserved-height')).toBe('26px')
|
||||
})
|
||||
|
||||
it('gives every week row the same --band-reserved-height when rendered together with a shared monthMaxLaneCount, even though only one has bands', () => {
|
||||
// Mirrors how Calendar.tsx renders a month: several CalendarWeek
|
||||
// rows side by side, all fed the same month-wide max. A week with
|
||||
// no bands of its own must still match a week with two overlapping
|
||||
// bands, or that row would render visibly shorter.
|
||||
const busyWeekDays = [
|
||||
pd({ id: '1', date: '2026-01-05', parentPersonalDataUuid: 'parent-1' }),
|
||||
pd({ id: '2', date: '2026-01-05', parentPersonalDataUuid: 'other-parent' }),
|
||||
]
|
||||
const { container } = render(
|
||||
<>
|
||||
<CalendarWeek {...defaultProps} plannedDays={busyWeekDays} monthMaxLaneCount={2} />
|
||||
<CalendarWeek
|
||||
{...defaultProps}
|
||||
weekDates={['2026-01-12', '2026-01-13', '2026-01-14', '2026-01-15', '2026-01-16', '2026-01-17', '2026-01-18']}
|
||||
plannedDays={[]}
|
||||
monthMaxLaneCount={2}
|
||||
/>
|
||||
</>,
|
||||
)
|
||||
const weeks = Array.from(container.querySelectorAll('.calendar-week')) as HTMLElement[]
|
||||
expect(weeks).toHaveLength(2)
|
||||
const heights = weeks.map((week) => week.style.getPropertyValue('--band-reserved-height'))
|
||||
expect(new Set(heights).size).toBe(1)
|
||||
expect(heights[0]).toBe('48px')
|
||||
})
|
||||
})
|
||||
|
||||
it('still fires the day cell\'s onClick/onPointerDown/onPointerEnter for a date under a band', () => {
|
||||
// The band overlays the day cell (same grid row); the day cell must
|
||||
// stay reachable for its own click/drag-select handlers underneath.
|
||||
|
||||
Reference in New Issue
Block a user