ui improvement

This commit is contained in:
2026-09-17 17:57:21 +05:30
parent 2cd048e6f0
commit 115a06a02c
79 changed files with 3574 additions and 2186 deletions

View File

@@ -19,6 +19,15 @@ import './drawer.css';
* else. Content comes from `drawerKit`. A drawer that styles its own card or
* badge is the beginning of the drift this component exists to end.
*/
/**
* How many drawers are open right now.
*
* Module scope rather than component state, because the count has to be shared
* between separate instances that know nothing about each other — see the
* scroll lock in the component below.
*/
let openDrawers = 0;
export interface DrawerProps {
title: string;
/** One line under the title — a brand, an SKU, a store name. */
@@ -78,6 +87,31 @@ export function Drawer({
return () => window.removeEventListener('keydown', onKeyDown);
}, [onClose]);
/*
The page behind stops scrolling while this is open.
`overscroll-behavior: contain` on the body already stops a scroll that
reaches the end of the drawer from continuing into the page underneath. What
it does not stop is a wheel over the SCRIM, which is most of the screen — so
the list behind would scroll away under a drawer that stayed put, and closing
it left the operator somewhere they had not chosen to be.
No padding is added to compensate for the vanished scrollbar: `html` carries
`scrollbar-gutter: stable`, so the gutter is reserved whether or not a bar is
drawn there and the page does not jump sideways as this opens.
*/
useEffect(() => {
/* Counted, not a boolean. Drawers stack — the partner's rider list opens a
rider drawer on top of itself — and closing the inner one must not
unlock the page while the outer one is still covering it. */
openDrawers += 1;
document.body.style.overflow = 'hidden';
return () => {
openDrawers -= 1;
if (openDrawers === 0) document.body.style.overflow = '';
};
}, []);
return (
<div className="drawer-root" role="dialog" aria-modal="true" aria-label={title}>
<button type="button" className="drawer-scrim" aria-label="Close" onClick={onClose} />
@@ -105,7 +139,10 @@ export function Drawer({
{/* Beside the title, not beneath it. Stacked under the subtitle it was
a third line, and a third line is what made this header twice the
height of the nav bar it now matches. */}
height of the nav bar it now matches.
The badge here is the same badge the table row wears, in the same
colour — see the note on `Badge` in `drawerKit`. */}
{meta ? <div className="drawer-meta">{meta}</div> : null}
<button type="button" className="drawer-close" aria-label="Close" onClick={onClose}>
<X size={16} />