Task #448: remove gap under Notes header by switching back to sticky
Task #446 made the Notes header `position: fixed` and added an aria-hidden spacer below it sized to the header's measured height (via ResizeObserver). The spacer was exactly the "big empty band" the user kept seeing between the header bar and the "اكتب ملاحظة..." composer — the page background gradient showed through the reserved space. Switched the header back to `sticky top-0 z-20`. Sticky keeps it pinned to the top of the viewport while the page scrolls, but it stays in document flow, so the composer renders immediately under the bar with no artificial gap. Removed the now-unused `headerRef`, `headerHeight` state, ResizeObserver effect, and the spacer div. Bumped composer wrapper padding from `pt-1` back to `pt-3` for a small breathing space (no longer competing with the spacer). No other changes; folders rail, composer behavior, RTL/LTR all untouched.
This commit is contained in:
@@ -295,28 +295,6 @@ export default function NotesPage() {
|
||||
const pinned = filteredNotes.filter((n) => n.isPinned);
|
||||
const others = filteredNotes.filter((n) => !n.isPinned);
|
||||
|
||||
// The header is rendered position:fixed so it stays pinned to the top
|
||||
// of the viewport even as the page scrolls. Because its height varies
|
||||
// (label chips wrap, the active tab can show or hide the grid/list
|
||||
// toggle, etc.), we measure it with a ResizeObserver and reserve the
|
||||
// same amount of vertical space below with a spacer div — that keeps
|
||||
// the first row of content from sliding under the bar.
|
||||
const headerRef = useRef<HTMLDivElement | null>(null);
|
||||
const [headerHeight, setHeaderHeight] = useState(0);
|
||||
useEffect(() => {
|
||||
const el = headerRef.current;
|
||||
if (!el) return;
|
||||
const update = () => setHeaderHeight(el.offsetHeight);
|
||||
update();
|
||||
const ro = new ResizeObserver(update);
|
||||
ro.observe(el);
|
||||
window.addEventListener("resize", update);
|
||||
return () => {
|
||||
ro.disconnect();
|
||||
window.removeEventListener("resize", update);
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Composer is rendered above the folders area so the user can capture
|
||||
// a quick note from anywhere on the active "My Notes" view without
|
||||
// first drilling into a folder. It is hidden on read-only / non-owner
|
||||
@@ -330,10 +308,7 @@ export default function NotesPage() {
|
||||
dir={isRtl ? "rtl" : "ltr"}
|
||||
data-testid="notes-page"
|
||||
>
|
||||
<div
|
||||
ref={headerRef}
|
||||
className="glass-panel border-b border-slate-200/70 px-4 py-3 fixed top-0 inset-x-0 z-30"
|
||||
>
|
||||
<div className="glass-panel border-b border-slate-200/70 px-4 py-3 sticky top-0 z-20">
|
||||
<div className="flex items-center gap-3 flex-wrap">
|
||||
<button
|
||||
onClick={() => setLocation("/")}
|
||||
@@ -488,13 +463,9 @@ export default function NotesPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Spacer reserves the same vertical space the fixed header occupies
|
||||
so the first row of content doesn't slide under it. */}
|
||||
<div aria-hidden style={{ height: headerHeight }} />
|
||||
|
||||
{showTopComposer && (
|
||||
<div
|
||||
className="px-4 pt-1 max-w-6xl w-full mx-auto"
|
||||
className="px-4 pt-3 max-w-6xl w-full mx-auto"
|
||||
data-testid="notes-top-composer"
|
||||
>
|
||||
<Composer
|
||||
|
||||
Reference in New Issue
Block a user