diff --git a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/analytics/tables/page-client.tsx b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/analytics/tables/page-client.tsx index 9bd9490c0..a360dfb28 100644 --- a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/analytics/tables/page-client.tsx +++ b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/analytics/tables/page-client.tsx @@ -27,6 +27,8 @@ type TableConfig = { }; type TableId = string; +const ANALYTICS_TABLES_STICKY_TOP = "var(--analytics-tables-sticky-top)"; +const ANALYTICS_TABLES_SIDEBAR_HEIGHT = "var(--analytics-tables-sidebar-height)"; const AVAILABLE_TABLES = new Map([ [ @@ -198,9 +200,7 @@ function TableContent({ tableId }: { tableId: TableId }) { ); return ( - // fillHeight grid owns its own scrollport below the page header, so rows never - // paint under the sticky translucent header (the dark-mode seam bug). -
+
- {/* containedHeight: page fills the shell under the header and scrolls internally, - so table rows cannot travel behind the floating dark-mode header. */} - -
-
- + + +
+ {/* Left sidebar — hidden on mobile */} +
+
+ + Tables + +
+ {[...AVAILABLE_TABLES.entries()].map(([id, config]) => ( + + ))} +
+ + + + Queries + +
- {/* Match the primary nav's dark:rounded-2xl so the gap junction mirrors - the same radius on both sides (nav top-right ↔ tables top-left). */} -
- {/* Use the same surface treatment as the primary sidebar so equal radii render - identically. Omit the right border to keep the sidebar/grid junction divider-free. */} -
-
-
- - Tables - -
- {[...AVAILABLE_TABLES.entries()].map(([id, config]) => ( - - ))} -
- - - - Queries - -
+ {/* Right content — flush to card edge; companion gap is on
in sidebar-layout */} +
div:first-child>div]:pt-3", + "[&_[role=grid]_.sticky>div:first-child>div]:pb-2.5", + "[&_[role=grid]_.sticky>div:first-child>div]:pr-0", + "[&_[role=grid]_.sticky>div:first-child>div]:pl-2.5", + )} + > + {selectedTable ? ( + + ) : ( +
+ + Select a table to view its contents +
-
- - {/* Right content — grid fills remaining height and scrolls internally */} -
div:first-child>div]:pt-3", - "[&_[role=grid]_.sticky>div:first-child>div]:pb-2.5", - "[&_[role=grid]_.sticky>div:first-child>div]:pr-0", - "[&_[role=grid]_.sticky>div:first-child>div]:pl-2.5", - )} - style={{ - // Outer top-right corner of the block. Same clip-path trick as the - // sidebar: the grid's sticky chrome is its own composited layer and - // paints square over the parent's rounded overflow clip without this. - borderTopRightRadius: "1rem", - clipPath: "inset(0 round 0 1rem 0 0)", - }} - > - {selectedTable ? ( - - ) : ( -
- - Select a table to view its contents - -
- )} -
+ )}
diff --git a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/analytics/tables/query-data-grid.tsx b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/analytics/tables/query-data-grid.tsx index 72d60146b..6b1141158 100644 --- a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/analytics/tables/query-data-grid.tsx +++ b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/analytics/tables/query-data-grid.tsx @@ -133,8 +133,6 @@ export type QueryDataGridProps = { fillHeight?: boolean, /** Sticky top offset forwarded to the underlying DataGrid. */ stickyTop?: number | string, - /** Where the horizontal scrollbar is shown when columns overflow. */ - horizontalScrollbarPosition?: "top" | "bottom", }; export type QueryDataGridHandle = { @@ -331,7 +329,6 @@ export const QueryDataGrid = forwardRef footer = false, fillHeight = true, stickyTop, - horizontalScrollbarPosition, }, ref, ) { @@ -657,7 +654,6 @@ export const QueryDataGrid = forwardRef selectionMode="none" fillHeight={fillHeight} stickyTop={stickyTop} - horizontalScrollbarPosition={horizontalScrollbarPosition} toolbar={resolvedToolbar} toolbarExtra={resolvedToolbarExtra} footer={footer ? undefined : false} diff --git a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx index f9de99020..9e2cf81ce 100644 --- a/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx +++ b/apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx @@ -731,13 +731,6 @@ export default function SidebarLayout(props: { children?: React.ReactNode }) { WebkitMaskImage: 'linear-gradient(to bottom, black 50%, transparent 100%)', }} /> - {/* Opaque underlay for dark mode. Table/page content scrolls under this sticky - header; without a solid base, the translucent fill + backdrop-filter composite - a bright seam along the bottom edge whenever rows pass behind it. */} -
{/* Left section: Logo + Menu + Project Switcher */}
diff --git a/apps/dashboard/src/components/cmdk-search.tsx b/apps/dashboard/src/components/cmdk-search.tsx index 22b98ccbd..300098eb3 100644 --- a/apps/dashboard/src/components/cmdk-search.tsx +++ b/apps/dashboard/src/components/cmdk-search.tsx @@ -1005,21 +1005,20 @@ export function CmdKSearch({ // Trigger button component that can be placed in the header export function CmdKTrigger() { const mouseCursorRef = useRef(null); + const mouseCursorParentRef = useRef(null); const modifierKeyLabel = getShortcutModifierKeyLabel(); - const handleMouseMove = useCallback((event: React.MouseEvent) => { - const cursor = mouseCursorRef.current; - if (cursor == null) { - return; - } - - // Keep this glow local to the trigger. A document-level mousemove listener used to - // reposition a blurred layer under the translucent header on every cursor move across - // the page, continuously recompositing the sticky header while table rows scrolled - // behind it and making the header's bottom edge flicker. - const rect = event.currentTarget.getBoundingClientRect(); - cursor.style.left = `${event.clientX - rect.left}px`; - cursor.style.top = `${event.clientY - rect.top}px`; + useEffect(() => { + const handleMouseMove = (e: MouseEvent) => { + if (mouseCursorRef.current && mouseCursorParentRef.current) { + const rect = mouseCursorParentRef.current.getBoundingClientRect(); + mouseCursorRef.current.style.left = `${e.clientX - rect.left}px`; + mouseCursorRef.current.style.top = `${e.clientY - rect.top}px`; + mouseCursorRef.current.style.display = "block"; + } + }; + document.addEventListener("mousemove", handleMouseMove); + return () => document.removeEventListener("mousemove", handleMouseMove); }, []); return ( @@ -1027,7 +1026,6 @@ export function CmdKTrigger() {