From bfea08a3c86934defff3018d65e5981a4772a5b3 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 26 Jun 2025 14:55:39 +0000 Subject: [PATCH 01/33] feat: Enhance mobile readiness and UX This commit enhances the mobile experience by: - Implementing an accessible search interface in the header for mobile devices, with a toggle icon and dedicated search view. - Making homepage chart annotations (title and value text) responsive to screen size for better readability on small devices. - Improving touch targets and appearance for TagChips, including an always-visible copy icon. - Converting CopyToClipboard to use an IconButton for improved tap targets. - General structural improvements for responsive layouts were part of the initial commit, including drawer navigation and scrollable tables. --- src/app/HomePage.tsx | 24 +- src/app/entity/[slug]/ProcessPage.tsx | 15 +- src/components/AsyncTable.tsx | 7 +- src/components/Charts/AreaChart.tsx | 11 +- src/components/Charts/defaultOptions.ts | 9 +- src/components/CopyToClipboard.tsx | 58 ++-- src/components/Header.tsx | 352 ++++++++++++++---------- src/components/TagChip.tsx | 66 +++-- 8 files changed, 317 insertions(+), 225 deletions(-) diff --git a/src/app/HomePage.tsx b/src/app/HomePage.tsx index 94bc34a..60deef5 100644 --- a/src/app/HomePage.tsx +++ b/src/app/HomePage.tsx @@ -67,40 +67,40 @@ export default function HomePage() { ) return ( - + {!stats ? ( - - + + - + - + - + ) : ( - - + + - + - + - + )} - + {/* Adjust negative margin for mobile */} diff --git a/src/app/entity/[slug]/ProcessPage.tsx b/src/app/entity/[slug]/ProcessPage.tsx index 49ca655..8a5ac95 100644 --- a/src/app/entity/[slug]/ProcessPage.tsx +++ b/src/app/entity/[slug]/ProcessPage.tsx @@ -118,12 +118,19 @@ export function ProcessPage(props: ProcessPageProps) { }, [outgoingMessages, entities]) return ( - + } /> - - + + {graphData === null ? ( @@ -187,7 +194,7 @@ export function ProcessPage(props: ProcessPageProps) { - + {/* Adjust negative margin for mobile */} - - - + +
{/* Ensure some minWidth for table if desired */} + + {headerCells.map((cell, index) => ( { + const isSmallChart = useMediaQuery(theme.breakpoints.down("sm")) // Use sm breakpoint for "small" variant + const options: HighchartOptions = createOptionsForStat( titleText, - 150, - undefined, + 150, // Chart height remains fixed for these stat charts + undefined, // Chart width is responsive by default data, overrideValue, + false, // exportServer + isSmallChart ? "small" : "normal", // Pass sizeVariant ) return diff --git a/src/components/Charts/defaultOptions.ts b/src/components/Charts/defaultOptions.ts index 762bc5e..99f58f7 100644 --- a/src/components/Charts/defaultOptions.ts +++ b/src/components/Charts/defaultOptions.ts @@ -134,15 +134,18 @@ export function createOptionsForStat( data: HighchartAreaData[], overrideValue: number | undefined, exportServer = false, + sizeVariant: "normal" | "small" = "normal", // New parameter ): HighchartOptions { const fontColor = exportServer ? "rgb(255, 255, 255)" : "var(--mui-palette-text-primary)" const backgroundColor = exportServer ? "#252424" : "transparent" const fontSizes = { - title: exportServer ? "36px" : "12px", - value: exportServer ? "96px" : "32px", + title: exportServer ? "36px" : (sizeVariant === "small" ? "11px" : "12px"), // Slightly smaller title for small + value: exportServer ? "96px" : (sizeVariant === "small" ? "24px" : "32px"), // Adjusted value font size } + const valueYPosition = exportServer ? 208 : (sizeVariant === "small" ? 98 : 104); // Adjust Y position slightly for smaller font + return { title: { align: "left", @@ -190,7 +193,7 @@ export function createOptionsForStat( { point: { x: 0, - y: exportServer ? 208 : 104, + y: valueYPosition, // Use the calculated Y position xAxis: null, yAxis: null, }, diff --git a/src/components/CopyToClipboard.tsx b/src/components/CopyToClipboard.tsx index 79b76a6..f917d68 100644 --- a/src/components/CopyToClipboard.tsx +++ b/src/components/CopyToClipboard.tsx @@ -16,32 +16,38 @@ export function CopyToClipboard(props: CopyToClipboardProps) { if (!value) return null return ( - - { - event.stopPropagation() - navigator.clipboard.writeText(value) - - setCopied(true) - - setTimeout(() => { - setCopied(false) - }, 1000) - }} - > - {copied ? ( - - ) : ( - - )} - + + {/* Wrap with a span to ensure Tooltip has a valid child when IconButton is disabled (though not used here) */} + + { + event.stopPropagation() + navigator.clipboard.writeText(value) + setCopied(true) + setTimeout(() => { + setCopied(false) + }, 1500) // Increased timeout slightly + }} + sx={{ + // marginLeft: 0.5, // IconButton often has some inherent padding, adjust if needed + // p: 0.25, // IconButton has its own padding, fine-tune if necessary + "&:hover": { + // color: "var(--mui-palette-text-primary)", // Ensure icon color changes on hover if desired + }, + "& .MuiSvgIcon-root": { // If Phosphor icons are treated as SvgIcon by sx + fontSize: 18, // Slightly larger icon + } + }} + aria-label="Copy to clipboard" + > + {copied ? ( + // Use theme color for success + ) : ( + + )} + + ) } diff --git a/src/components/Header.tsx b/src/components/Header.tsx index f869092..e9f0512 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -12,27 +12,33 @@ import { Link as MuiLink, useScrollTrigger, Box, + useMediaQuery, + Drawer, + List, + ListItem, + ListItemButton, + ListItemText, + ListItemIcon, + InputAdornment, + TextField, } from "@mui/material" -import { Moon, Sun } from "@phosphor-icons/react" - -import { Link } from "react-router-dom" +import { Moon, Sun, List as MenuIcon, XCircle, MagnifyingGlass, ArrowLeft } from "@phosphor-icons/react" // Added MagnifyingGlass, ArrowLeft +import { Link, useNavigate } from "react-router-dom" +import { useState } from "react" import { Logo } from "./Logo" import { MainFontFF } from "./RootLayout/fonts" import SearchBar from "@/app/SearchBar" import { usePrimaryArnsName } from "@/hooks/usePrimaryArnsName" import { useArnsLogo } from "@/hooks/useArnsLogo" +import { theme } from "./RootLayout/theme" // Import theme for breakpoints const ProfileButton = () => { const activeAddress = useActiveAddress() const { data: arnsName, isLoading: isLoadingName } = usePrimaryArnsName(activeAddress || "") const { data: logoTxId, isLoading: isLoadingLogo } = useArnsLogo(arnsName || "") - // Debug logging - console.log("Profile Debug:", { activeAddress, arnsName, logoTxId, isLoadingName, isLoadingLogo }) - const handleProfileClick = () => { - // Find and click the hidden ConnectButton to trigger its modal const connectButton = document.getElementById('hidden-connect-button') if (connectButton) { connectButton.click() @@ -134,8 +140,19 @@ const ProfileButton = () => { ) } +const navItems = [ + { label: "PROCESSES", path: "/processes" }, + { label: "MODULES", path: "/modules" }, + { label: "BLOCKS", path: "/blocks" }, + { label: "ARNS", path: "/arns" }, +] + const Header = () => { const { mode = "dark", setMode } = useColorScheme() + const navigate = useNavigate() + const [drawerOpen, setDrawerOpen] = useState(false) + const [mobileSearchActive, setMobileSearchActive] = useState(false) // State for mobile search visibility + const isMobile = useMediaQuery(theme.breakpoints.down("md")) const elevated = useScrollTrigger({ disableHysteresis: true, @@ -143,153 +160,186 @@ const Header = () => { target: typeof window !== "undefined" ? window : undefined, }) - return ( - (event: React.KeyboardEvent | React.MouseEvent) => { + if ( + event.type === "keydown" && + ((event as React.KeyboardEvent).key === "Tab" || (event as React.KeyboardEvent).key === "Shift") + ) { + return + } + setDrawerOpen(open) + } + + const drawerContent = ( + - - - - - - - PROCESSES - - - MODULES - - - BLOCKS - - - ARNS - - - - - button > div": { - height: "fit-content", - padding: 0, - }, - "&.MuiBox-root button": { - height: "100%", - borderRadius: 1, - border: "1px solid var(--mui-palette-divider)", - paddingX: 2.5, - paddingY: 1, - color: "var(--mui-palette-primary-main)", - background: "none", - }, - "&.MuiBox-root button:active": { - transform: "scale(0.98) !important", - }, - "& button:hover": { - transform: "none !important", - boxShadow: "none !important", - }, - "& button > *": { - fontWeight: 500, - fontFamily: MainFontFF, - textTransform: "none", - lineHeight: 1, - fontSize: "0.8125rem", - padding: 0, - }, - "& button svg": { - marginY: -1, - }, - }} - > - - - { - const nextMode = mode === "dark" ? "light" : "dark" - setMode(nextMode) - }} + + + + + + + {navItems.map((item) => ( + + navigate(item.path)}> + + + + ))} + + + ) + + return ( + <> + + + + {isMobile && mobileSearchActive ? ( + + setMobileSearchActive(false)} color="inherit" sx={{ mr: 1 }}> + + + + + + + ) : ( + - {mode === "dark" ? : } - + + + {!isMobile && ( + + {navItems.map((item) => ( + + {item.label} + + ))} + + )} + + {/* Reduced gap for mobile icons */} + {!isMobile && } + {isMobile && ( + <> + setMobileSearchActive(true)} + > + + + + + + + )} + + { + const nextMode = mode === "dark" ? "light" : "dark" + setMode(nextMode) + }} + > + {mode === "dark" ? : } + + - - - - + + + + + {drawerContent} + + ) } diff --git a/src/components/TagChip.tsx b/src/components/TagChip.tsx index 8192a7e..6d122fe 100644 --- a/src/components/TagChip.tsx +++ b/src/components/TagChip.tsx @@ -15,29 +15,49 @@ export function TagChip(props: TypographyProps & { name: string; value: string } return ( theme.spacing(0.75, 1.25), // Increased padding: 6px top/bottom, 10px left/right color: "black", background: getColorFromText(name), + borderRadius: '16px', // Give it a chip-like appearance + overflow: 'hidden', // Ensure content fits + textOverflow: 'ellipsis', // Add ellipsis for long text + whiteSpace: 'nowrap', // Prevent wrapping of name:value + maxWidth: '100%', // Ensure it doesn't overflow its container in flex layouts }} variant="caption" fontFamily={MonoFontFF} > - {valuesIsArweaveAddress ? ( - - {name}:{value} - - ) : ( - - {name}:{value} - - )} + + {valuesIsArweaveAddress ? ( + e.stopPropagation()} // Prevent Typography's potential event handlers + > + {name}:{value} + + ) : ( + + {name}:{value} + + )} + { e.stopPropagation() navigator.clipboard.writeText(value) @@ -45,19 +65,17 @@ export function TagChip(props: TypographyProps & { name: string; value: string } setTimeout(() => setCopied(false), 2000) }} sx={{ - width: 0, - overflow: "hidden", - p: 0, - transition: "width 0.3s, transform 0.3s", + ml: 0.5, // Margin left to space from text + p: 0.25, // Small padding for the icon button itself color: "black", - ".MuiTypography-root:hover &": { - width: "auto", - ml: 1, - transform: "scale(1.2)", + // Basic visual feedback on tap for mobile + "&:active": { + transform: "scale(0.9)", }, }} + aria-label={`Copy value for ${name}`} > - {copied ? : } + {copied ? : } ) From 87eb3683b2fee2e6cb2df55a61113bd81411b3cc Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 26 Jun 2025 15:02:31 +0000 Subject: [PATCH 02/33] fix: Address build errors and apply lint suggestions - Fixed JSX syntax error (unclosed Box) in AsyncTable.tsx. - Attempted to resolve TS1005 error in Header.tsx by simplifying a complex sx prop. - Aligned copy feedback duration to 1500ms in TagChip.tsx for consistency. - Optimized toggleDrawer in Header.tsx with useCallback. This commit amends the previous 'feat: Enhance mobile readiness and UX' commit. --- src/components/AsyncTable.tsx | 1 + src/components/Header.tsx | 11 ++++++----- src/components/TagChip.tsx | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/AsyncTable.tsx b/src/components/AsyncTable.tsx index d0b0307..d50a93c 100644 --- a/src/components/AsyncTable.tsx +++ b/src/components/AsyncTable.tsx @@ -190,6 +190,7 @@ export function AsyncTable(props: AsyncTableProps) { )}
+
{/* Close the Box component that wraps the Table */} {!endReached && data.length > 0 && ( { target: typeof window !== "undefined" ? window : undefined, }) - const toggleDrawer = (open: boolean) => (event: React.KeyboardEvent | React.MouseEvent) => { + const toggleDrawer = useCallback((open: boolean) => (event: React.KeyboardEvent | React.MouseEvent) => { if ( event.type === "keydown" && ((event as React.KeyboardEvent).key === "Tab" || (event as React.KeyboardEvent).key === "Shift") @@ -168,7 +168,7 @@ const Header = () => { return } setDrawerOpen(open) - } + }, [setDrawerOpen]) // Added setDrawerOpen to dependency array, though empty [] might also work if setDrawerOpen is guaranteed stable const drawerContent = ( {
-
+ )} diff --git a/src/components/RootLayout/RootLayoutUI.tsx b/src/components/RootLayout/RootLayoutUI.tsx index 5d041ae..0b61c4a 100644 --- a/src/components/RootLayout/RootLayoutUI.tsx +++ b/src/components/RootLayout/RootLayoutUI.tsx @@ -24,7 +24,13 @@ export default function RootLayoutUI({ children }: { children: React.ReactNode }
- + {children}