mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-21 22:46:32 +00:00
125649ce1b
The base-layer pill sits in the map's bottom-left corner on purpose. The place inspector, a tour's detail and the day panel are centred between the sidebars and were assumed never to reach that corner, but with both sidebars open in a 1280 window they do, and the pill covered "Remove from Day" and Edit. These cards now keep their left edge clear of the pill: a narrow map moves the card right of it, a wide map keeps it centred as before. The pill itself does not move, and the phone sheets are unchanged. The Bookings tab showed "Book" at every width, which read as cut off. The short form now only shows where the bar is tight; from xl up the tab shows its full name. Refs #2604
74 lines
2.5 KiB
TypeScript
74 lines
2.5 KiB
TypeScript
import type { ReactNode } from 'react'
|
|
import { X } from 'lucide-react'
|
|
import { NEUTRAL_TINT } from './DialogShell'
|
|
import { Tooltip } from './Tooltip'
|
|
import { centredMapCardBox } from '../Map/centredMapCard'
|
|
|
|
interface DetailShellProps {
|
|
header: ReactNode
|
|
children: ReactNode
|
|
footer?: ReactNode
|
|
onClose: () => void
|
|
closeLabel: string
|
|
leftWidth?: number
|
|
rightWidth?: number
|
|
/** Over the desktop map: keep clear of the base-layer pill in its bottom-left corner. */
|
|
clearMapPill?: boolean
|
|
/** The head band's background; the neutral accent wash when left out. */
|
|
tint?: string
|
|
closeButtonClassName?: string
|
|
testId?: string
|
|
}
|
|
|
|
/**
|
|
* The card a selected item opens over the map, in the place inspector's frame:
|
|
* centred between the planner panels, a tinted head band with the close button,
|
|
* a body that scrolls and a footer that stays in reach.
|
|
*/
|
|
export default function DetailShell({
|
|
header,
|
|
children,
|
|
footer,
|
|
onClose,
|
|
closeLabel,
|
|
leftWidth = 0,
|
|
rightWidth = 0,
|
|
clearMapPill = false,
|
|
tint = NEUTRAL_TINT,
|
|
closeButtonClassName = '',
|
|
testId,
|
|
}: DetailShellProps) {
|
|
return (
|
|
<div
|
|
style={{
|
|
position: 'absolute',
|
|
bottom: 20,
|
|
...centredMapCardBox(leftWidth, rightWidth, { clearPill: clearMapPill }),
|
|
transform: 'translateX(-50%)',
|
|
zIndex: 50,
|
|
fontFamily: 'var(--font-system)',
|
|
}}
|
|
>
|
|
<div className="flex max-h-[60vh] flex-col overflow-hidden rounded-[20px] border border-edge-faint bg-surface-elevated text-content shadow-popover backdrop-blur-[40px] backdrop-saturate-[1.8]">
|
|
<header className="flex flex-none items-start gap-3.5 border-b border-edge-faint px-4 pb-3 pt-3.5" style={{ background: tint }}>
|
|
{header}
|
|
<Tooltip label={closeLabel}>
|
|
<button type="button" onClick={onClose} aria-label={closeLabel}
|
|
className={`grid h-8 w-8 flex-none place-items-center rounded-full bg-surface-card text-content-muted shadow-sm transition-colors hover:text-content ${closeButtonClassName}`}>
|
|
<X size={15} strokeWidth={2.2} />
|
|
</button>
|
|
</Tooltip>
|
|
</header>
|
|
<div data-testid={testId} className="flex min-h-0 flex-1 flex-col gap-3.5 overflow-y-auto overscroll-contain px-4 py-3.5">
|
|
{children}
|
|
</div>
|
|
{footer && (
|
|
<footer className="flex flex-none flex-wrap items-center gap-2 border-t border-edge-faint px-4 py-2.5">
|
|
{footer}
|
|
</footer>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|