diff --git a/components/BottomSheet.tsx b/components/BottomSheet.tsx new file mode 100644 index 0000000..a9fa6f2 --- /dev/null +++ b/components/BottomSheet.tsx @@ -0,0 +1,70 @@ +'use client'; + +import { useEffect, useState } from 'react'; +import { createPortal } from 'react-dom'; +import { X } from 'lucide-react'; + +interface BottomSheetProps { + title: string; + subtitle?: string; + onClose: () => void; + children: React.ReactNode; +} + +// Full-width panel that slides up from the bottom of the screen. +// +// Replaces the small popovers on the compact rows: those were 256px +// wide and pinned to a button in the middle of the row, so on a phone +// they ran off the left edge. Rendered into
through a portal so +// no parent's stacking context or overflow can clip it, and it sits +// above the BottomNav. +export default function BottomSheet({ title, subtitle, onClose, children }: BottomSheetProps) { + const [mounted, setMounted] = useState(false); + useEffect(() => setMounted(true), []); + + useEffect(() => { + const onKey = (e: KeyboardEvent) => { + if (e.key === 'Escape') onClose(); + }; + document.addEventListener('keydown', onKey); + return () => document.removeEventListener('keydown', onKey); + }, [onClose]); + + if (!mounted) return null; + + return createPortal( +{title}
+ {subtitle && ( +{subtitle}
+ )} ++ {item.description || 'Unknown item'} +
+ {item.problem_flag && ( + + {problemBadgeLabel(item)} + + )} +Purchase Order
- -No PO attached
- -Buyer Notes
- -- {item.notes} -
- {hasProblemNotes && ( -- Problem: {item.problem_notes} -
- )} - > - ) : hasProblemNotes ? ( -- {item.problem_notes} -
- ) : ( -No notes
- )} -{item.description}
+ {po && ( ++ {item.notes} +
+ )} + {hasProblemNotes && ( ++ Problem: {item.problem_notes} +
+ )} +