fix: uniform cell heights in park month calendar
All checks were successful
Build and Deploy / Build & Push (push) Successful in 51s
All checks were successful
Build and Deploy / Build & Push (push) Successful in 51s
Root cause: each week row was its own CSS Grid container, so rows with open-day pills (hours + separate timezone line) grew taller than closed rows, making the calendar column lines look staggered/slanted. - Flatten all day cells into a single grid with gridAutoRows: 76 so every row is exactly the same fixed height - All cells get overflow: hidden so content can never push height - Compact the status pill to a single line (hours + tz inline, truncated with ellipsis) — the stacked two-line pill was the primary height expander on narrow mobile columns - Row/column border logic moves from week-wrapper divs to individual cell borderRight / borderBottom properties - Nav link touch targets: padding 6×14 → 10×16, minWidth: 44px Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -118,103 +118,108 @@ export function ParkMonthCalendar({ parkId, year, month, monthData, today, timez
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Weeks */}
|
||||
{weeks.map((week, wi) => (
|
||||
<div key={wi} style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "repeat(7, 1fr)",
|
||||
borderBottom: wi < weeks.length - 1 ? "1px solid var(--color-border-subtle)" : "none",
|
||||
}}>
|
||||
{week.map((cell, ci) => {
|
||||
if (!cell.day || !cell.iso) {
|
||||
return (
|
||||
<div key={ci} style={{
|
||||
minHeight: 96,
|
||||
background: ci === 0 || ci === 6 ? "var(--color-weekend-header)" : "transparent",
|
||||
borderRight: ci < 6 ? "1px solid var(--color-border-subtle)" : "none",
|
||||
}} />
|
||||
);
|
||||
}
|
||||
|
||||
const dayData = monthData[cell.iso];
|
||||
const isToday = cell.iso === today;
|
||||
const isWeekend = ci === 0 || ci === 6;
|
||||
const isOpen = dayData?.isOpen && dayData?.hoursLabel;
|
||||
const isPH = dayData?.specialType === "passholder_preview";
|
||||
|
||||
const bg = isToday
|
||||
? "var(--color-today-bg)"
|
||||
: isWeekend
|
||||
? "var(--color-weekend-header)"
|
||||
: "transparent";
|
||||
{/*
|
||||
All day cells in ONE flat grid so every row shares the same
|
||||
fixed height — no per-week wrapper divs that could produce
|
||||
rows of different heights on mobile.
|
||||
*/}
|
||||
<div style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "repeat(7, 1fr)",
|
||||
gridAutoRows: 76,
|
||||
}}>
|
||||
{cells.map((cell, idx) => {
|
||||
const ci = idx % 7;
|
||||
const isLastRow = idx >= cells.length - 7;
|
||||
const borderBottom = !isLastRow ? "1px solid var(--color-border-subtle)" : "none";
|
||||
const borderRight = ci < 6 ? "1px solid var(--color-border-subtle)" : "none";
|
||||
|
||||
if (!cell.day || !cell.iso) {
|
||||
return (
|
||||
<div key={ci} style={{
|
||||
minHeight: 96,
|
||||
padding: "10px 12px",
|
||||
background: bg,
|
||||
borderRight: ci < 6 ? "1px solid var(--color-border-subtle)" : "none",
|
||||
borderLeft: isToday ? "2px solid var(--color-today-border)" : "none",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 5,
|
||||
}}>
|
||||
{/* Date number */}
|
||||
<span style={{
|
||||
fontSize: "0.95rem",
|
||||
fontWeight: isToday ? 700 : isWeekend ? 600 : 400,
|
||||
color: isToday
|
||||
? "var(--color-today-text)"
|
||||
: isWeekend
|
||||
? "var(--color-text)"
|
||||
: "var(--color-text-muted)",
|
||||
lineHeight: 1,
|
||||
}}>
|
||||
{cell.day}
|
||||
</span>
|
||||
|
||||
{/* Status */}
|
||||
{!dayData ? (
|
||||
<span style={{ fontSize: "0.75rem", color: "var(--color-text-dim)" }}>—</span>
|
||||
) : isPH && isOpen ? (
|
||||
<div style={{
|
||||
background: "var(--color-ph-bg)",
|
||||
border: "1px solid var(--color-ph-border)",
|
||||
borderRadius: 5,
|
||||
padding: "3px 6px",
|
||||
}}>
|
||||
<div style={{ fontSize: "0.6rem", fontWeight: 700, color: "var(--color-ph-label)", textTransform: "uppercase", letterSpacing: "0.05em" }}>
|
||||
Passholder
|
||||
</div>
|
||||
<div style={{ fontSize: "0.65rem", color: "var(--color-ph-hours)", marginTop: 2 }}>
|
||||
{dayData.hoursLabel}
|
||||
</div>
|
||||
<div style={{ fontSize: "0.58rem", color: "var(--color-ph-label)", opacity: 0.75, marginTop: 1, letterSpacing: "0.04em" }}>
|
||||
{tzAbbr}
|
||||
</div>
|
||||
</div>
|
||||
) : isOpen ? (
|
||||
<div style={{
|
||||
background: "var(--color-open-bg)",
|
||||
border: "1px solid var(--color-open-border)",
|
||||
borderRadius: 5,
|
||||
padding: "3px 6px",
|
||||
}}>
|
||||
<div style={{ fontSize: "0.65rem", color: "var(--color-open-hours)" }}>
|
||||
{dayData.hoursLabel}
|
||||
</div>
|
||||
<div style={{ fontSize: "0.58rem", color: "var(--color-open-hours)", opacity: 0.6, marginTop: 1, letterSpacing: "0.04em" }}>
|
||||
{tzAbbr}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<span style={{ fontSize: "1rem", color: "var(--color-text-dim)", lineHeight: 1 }}>·</span>
|
||||
)}
|
||||
</div>
|
||||
<div key={idx} style={{
|
||||
background: ci === 0 || ci === 6 ? "var(--color-weekend-header)" : "transparent",
|
||||
borderRight,
|
||||
borderBottom,
|
||||
}} />
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
))}
|
||||
}
|
||||
|
||||
const dayData = monthData[cell.iso];
|
||||
const isToday = cell.iso === today;
|
||||
const isWeekend = ci === 0 || ci === 6;
|
||||
const isOpen = dayData?.isOpen && dayData?.hoursLabel;
|
||||
const isPH = dayData?.specialType === "passholder_preview";
|
||||
|
||||
const bg = isToday
|
||||
? "var(--color-today-bg)"
|
||||
: isWeekend
|
||||
? "var(--color-weekend-header)"
|
||||
: "transparent";
|
||||
|
||||
return (
|
||||
<div key={idx} style={{
|
||||
padding: "8px 8px",
|
||||
overflow: "hidden",
|
||||
background: bg,
|
||||
borderRight,
|
||||
borderBottom,
|
||||
borderLeft: isToday ? "2px solid var(--color-today-border)" : "none",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: 4,
|
||||
}}>
|
||||
{/* Date number */}
|
||||
<span style={{
|
||||
fontSize: "0.88rem",
|
||||
fontWeight: isToday ? 700 : isWeekend ? 600 : 400,
|
||||
color: isToday
|
||||
? "var(--color-today-text)"
|
||||
: isWeekend
|
||||
? "var(--color-text)"
|
||||
: "var(--color-text-muted)",
|
||||
lineHeight: 1,
|
||||
flexShrink: 0,
|
||||
}}>
|
||||
{cell.day}
|
||||
</span>
|
||||
|
||||
{/* Status — single-line pill so all cells stay uniform height */}
|
||||
{!dayData ? (
|
||||
<span style={{ fontSize: "0.75rem", color: "var(--color-text-dim)" }}>—</span>
|
||||
) : isPH && isOpen ? (
|
||||
<div style={{
|
||||
background: "var(--color-ph-bg)",
|
||||
border: "1px solid var(--color-ph-border)",
|
||||
borderRadius: 4,
|
||||
padding: "2px 4px",
|
||||
overflow: "hidden",
|
||||
}}>
|
||||
<div style={{ fontSize: "0.58rem", fontWeight: 700, color: "var(--color-ph-label)", textTransform: "uppercase", letterSpacing: "0.04em", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
|
||||
Passholder
|
||||
</div>
|
||||
<div style={{ fontSize: "0.6rem", color: "var(--color-ph-hours)", marginTop: 1, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
|
||||
{dayData.hoursLabel} <span style={{ opacity: 0.6 }}>{tzAbbr}</span>
|
||||
</div>
|
||||
</div>
|
||||
) : isOpen ? (
|
||||
<div style={{
|
||||
background: "var(--color-open-bg)",
|
||||
border: "1px solid var(--color-open-border)",
|
||||
borderRadius: 4,
|
||||
padding: "2px 4px",
|
||||
overflow: "hidden",
|
||||
}}>
|
||||
<div style={{ fontSize: "0.6rem", color: "var(--color-open-hours)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
|
||||
{dayData.hoursLabel} <span style={{ opacity: 0.6 }}>{tzAbbr}</span>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<span style={{ fontSize: "1rem", color: "var(--color-text-dim)", lineHeight: 1 }}>·</span>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -224,12 +229,13 @@ const navLinkStyle: React.CSSProperties = {
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
padding: "6px 14px",
|
||||
borderRadius: 6,
|
||||
padding: "10px 16px",
|
||||
borderRadius: 8,
|
||||
border: "1px solid var(--color-border)",
|
||||
background: "var(--color-surface)",
|
||||
color: "var(--color-text-muted)",
|
||||
fontSize: "1rem",
|
||||
lineHeight: 1,
|
||||
textDecoration: "none",
|
||||
minWidth: 44,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user