use rem styling, make navbar scrollable on overflow, extrapolate styling to be re-usable and remove redundant nav item colors, rely on tailwind theme instead

This commit is contained in:
EthanHealy01 2025-07-22 16:48:11 +01:00
parent 7d09bf9e45
commit 3a76d13097
6 changed files with 94 additions and 69 deletions

View File

@ -3,7 +3,6 @@
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,700,0,0" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#000000" />
<meta

View File

@ -27,6 +27,7 @@
"i18next-browser-languagedetector": "^8.1.0",
"i18next-http-backend": "^3.0.2",
"jszip": "^3.10.1",
"material-symbols": "^0.33.0",
"pdf-lib": "^1.17.1",
"pdfjs-dist": "^3.11.174",
"react": "^19.1.0",
@ -4175,6 +4176,12 @@
"semver": "bin/semver.js"
}
},
"node_modules/material-symbols": {
"version": "0.33.0",
"resolved": "https://registry.npmjs.org/material-symbols/-/material-symbols-0.33.0.tgz",
"integrity": "sha512-t9/Gz+14fClRgN7oVOt5CBuwsjFLxSNP9BRDyMrI5el3IZNvoD94IDGJha0YYivyAow24rCS0WOkAv4Dp+YjNg==",
"license": "Apache-2.0"
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",

View File

@ -23,6 +23,7 @@
"i18next-browser-languagedetector": "^8.1.0",
"i18next-http-backend": "^3.0.2",
"jszip": "^3.10.1",
"material-symbols": "^0.33.0",
"pdf-lib": "^1.17.1",
"pdfjs-dist": "^3.11.174",
"react": "^19.1.0",

View File

@ -12,16 +12,38 @@
height: 32px;
}
.fallbackDivider {
width: 60px;
height: 1px;
background-color: var(--color-gray-300);
margin: 8px 0;
border-radius: 1px;
/* Scrollable navbar styling - scrollbars only show when scrolling */
.quick-access-bar {
overflow-x: auto;
overflow-y: hidden;
scrollbar-gutter: stable both-edges;
-webkit-overflow-scrolling: touch;
}
.mantineDivider {
width: 60px;
margin: 8px 0;
border-color: var(--color-gray-300);
/* Hide scrollbar by default, show on scroll (Webkit browsers - Chrome, Safari, Edge) */
.quick-access-bar::-webkit-scrollbar {
width: 8px;
height: 8px;
background: transparent;
}
.quick-access-bar:hover::-webkit-scrollbar,
.quick-access-bar:active::-webkit-scrollbar,
.quick-access-bar:focus::-webkit-scrollbar {
background: rgba(0, 0, 0, 0.1);
}
.quick-access-bar::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.2);
border-radius: 4px;
}
.quick-access-bar::-webkit-scrollbar-track {
background: transparent;
}
/* Firefox scrollbar styling */
.quick-access-bar {
scrollbar-width: auto;
scrollbar-color: rgba(0, 0, 0, 0.2) transparent;
}

View File

@ -26,45 +26,39 @@ interface ButtonConfig {
name: string;
icon: React.ReactNode;
tooltip: string;
color: string;
isRound?: boolean;
size?: 'sm' | 'md' | 'lg' | 'xl';
onClick: () => void;
}
const actionIconStyle = {
backgroundColor: 'var(--icon-user-bg)',
color: 'var(--icon-user-color)',
borderRadius: '50%',
width: '1.5rem',
height: '1.5rem',
};
function NavHeader() {
return (
<>
<div className="flex flex-row items-center justify-center mb-0">
<div className="flex flex-row items-center justify-center mb-0" style={{ gap: '0.5rem' }}>
<Tooltip label="User Profile" position="right">
<ActionIcon
size="md"
variant="subtle"
style={{
backgroundColor: 'var(--icon-user-bg)',
color: 'var(--icon-user-color)',
borderRadius: '50%',
width: '24px',
height: '24px',
marginRight: '8px'
}}
style={actionIconStyle}
>
<PersonIcon sx={{ fontSize: 16 }} />
<PersonIcon sx={{ fontSize: "1rem" }} />
</ActionIcon>
</Tooltip>
<Tooltip label="Notifications" position="right">
<ActionIcon
size="md"
variant="subtle"
style={{
backgroundColor: 'var(--icon-notifications-bg)',
color: 'var(--icon-notifications-color)',
borderRadius: '50%',
width: '24px',
height: '24px'
}}
style={actionIconStyle}
>
<NotificationsIcon sx={{ fontSize: 16 }} />
<NotificationsIcon sx={{ fontSize: "1rem" }} />
</ActionIcon>
</Tooltip>
</div>
@ -72,7 +66,7 @@ function NavHeader() {
<Divider
size="xs"
style={{
width: '60px',
width: '3.75rem',
borderColor: 'var(--color-gray-300)'
}}
/>
@ -98,8 +92,8 @@ const QuickAccessBar = ({
name: 'All Tools',
icon: <AppsIcon sx={{ fontSize: 26 }} />,
tooltip: 'View all available tools',
color: '#1E88E5',
size: 'lg',
isRound: false,
onClick: () => {
setActiveButton('tools');
onReaderToggle();
@ -111,8 +105,8 @@ const QuickAccessBar = ({
name: 'Read',
icon: <MenuBookIcon sx={{ fontSize: 20 }} />,
tooltip: 'Read documents',
color: '#4CAF50',
size: 'lg',
isRound: false,
onClick: () => {
setActiveButton('read');
onReaderToggle();
@ -122,12 +116,12 @@ const QuickAccessBar = ({
id: 'sign',
name: 'Sign',
icon:
<span className="material-symbols-outlined" style={{ fontSize: 20 }}>
<span className="material-symbols-rounded" style={{ fontSize: 20 }}>
signature
</span>,
tooltip: 'Sign your document',
color: '#3BA99C',
size: 'lg',
isRound: false,
onClick: () => setActiveButton('sign')
},
{
@ -135,8 +129,8 @@ const QuickAccessBar = ({
name: 'Automate',
icon: <AutoAwesomeIcon sx={{ fontSize: 20 }} />,
tooltip: 'Automate workflows',
color: '#A576E3',
size: 'lg',
isRound: false,
onClick: () => setActiveButton('automate')
},
{
@ -144,34 +138,18 @@ const QuickAccessBar = ({
name: 'Files',
icon: <FolderIcon sx={{ fontSize: 20 }} />,
tooltip: 'Manage files',
color: '', // the round icons are blue always, this logic lives in getButtonStyle
isRound: true,
size: 'lg',
onClick: () => setActiveButton('files')
},
/* Access isn't going to be available yet */
/*
{
id: 'access',
name: 'Access',
icon: <GroupIcon sx={{ fontSize: 20 }} />,
tooltip: 'Manage access and permissions',
color: '#00BCD4',
isRound: true,
size: 'lg',
onClick: () => setActiveButton('access')
},
*/
{
id: 'activity',
name: 'Activity',
icon:
<span className="material-symbols-outlined" style={{ fontSize: 20 }}>
<span className="material-symbols-rounded" style={{ fontSize: 20 }}>
vital_signs
</span>,
tooltip: 'View activity and analytics',
color: '',
isRound: true,
size: 'lg',
onClick: () => setActiveButton('activity')
@ -181,7 +159,6 @@ const QuickAccessBar = ({
name: 'Config',
icon: <SettingsIcon sx={{ fontSize: 16 }} />,
tooltip: 'Configure settings',
color: '#9CA3AF',
size: 'lg',
onClick: () => {
setConfigModalOpen(true);
@ -189,6 +166,13 @@ const QuickAccessBar = ({
}
];
const ROUND_BORDER_RADIUS = '50%';
const NOT_ROUND_BORDER_RADIUS = '8px';
const getBorderRadius = (config: ButtonConfig): string => {
return config.isRound ? ROUND_BORDER_RADIUS : NOT_ROUND_BORDER_RADIUS;
};
const getButtonStyle = (config: ButtonConfig) => {
const isActive = activeButton === config.id;
@ -199,7 +183,7 @@ const QuickAccessBar = ({
backgroundColor: 'var(--icon-tools-bg)',
color: 'var(--icon-tools-color)',
border: 'none',
borderRadius: config.isRound ? '50%' : '8px',
borderRadius: getBorderRadius(config),
};
}
if (config.id === 'read') {
@ -207,7 +191,7 @@ const QuickAccessBar = ({
backgroundColor: 'var(--icon-read-bg)',
color: 'var(--icon-read-color)',
border: 'none',
borderRadius: config.isRound ? '50%' : '8px',
borderRadius: getBorderRadius(config),
};
}
if (config.id === 'sign') {
@ -215,7 +199,7 @@ const QuickAccessBar = ({
backgroundColor: 'var(--icon-sign-bg)',
color: 'var(--icon-sign-color)',
border: 'none',
borderRadius: config.isRound ? '50%' : '8px',
borderRadius: getBorderRadius(config),
};
}
if (config.id === 'automate') {
@ -223,21 +207,21 @@ const QuickAccessBar = ({
backgroundColor: 'var(--icon-automate-bg)',
color: 'var(--icon-automate-color)',
border: 'none',
borderRadius: config.isRound ? '50%' : '8px',
borderRadius: getBorderRadius(config),
};
}
if (config.id === 'files') {
return {
backgroundColor: 'var(--icon-files-bg)',
color: 'var(--icon-files-color)',
borderRadius: '50%',
borderRadius: ROUND_BORDER_RADIUS,
};
}
if (config.id === 'activity') {
return {
backgroundColor: 'var(--icon-activity-bg)',
color: 'var(--icon-activity-color)',
borderRadius: '50%',
borderRadius: ROUND_BORDER_RADIUS,
};
}
if (config.id === 'config') {
@ -245,7 +229,7 @@ const QuickAccessBar = ({
backgroundColor: 'var(--icon-config-bg)',
color: 'var(--icon-config-color)',
border: 'none',
borderRadius: config.isRound ? '50%' : '8px',
borderRadius: getBorderRadius(config),
};
}
}
@ -255,15 +239,15 @@ const QuickAccessBar = ({
backgroundColor: 'var(--icon-inactive-bg)',
color: 'var(--icon-inactive-color)',
border: 'none',
borderRadius: config.isRound ? '50%' : '8px',
borderRadius: getBorderRadius(config),
};
};
const getTextStyle = (config: ButtonConfig) => {
const isActive = activeButton === config.id;
return {
marginTop: '12px',
fontSize: '12px',
marginTop: '0.75rem',
fontSize: '0.75rem',
color: isActive ? 'var(--text-primary)' : 'var(--color-gray-700)',
fontWeight: isActive ? 'bold' : 'normal',
textRendering: 'optimizeLegibility' as const,
@ -273,13 +257,19 @@ const QuickAccessBar = ({
return (
<div
className={`h-screen flex flex-col w-20 ${isRainbowMode ? rainbowStyles.rainbowPaper : ''}`}
className={`h-screen flex flex-col w-20 quick-access-bar ${isRainbowMode ? rainbowStyles.rainbowPaper : ''}`}
style={{
padding: '1rem 0.5rem',
backgroundColor: 'var(--bg-muted)',
width: '80px',
minWidth: '80px',
maxWidth: '80px'
width: '5rem',
minWidth: '5rem',
maxWidth: '5rem',
position: 'relative',
zIndex: 10
}}
onWheel={(e) => {
// Prevent the wheel event from bubbling up to parent containers
e.stopPropagation();
}}
>
<Stack gap="lg" align="center" className="flex-1">
@ -310,7 +300,7 @@ const QuickAccessBar = ({
<Divider
size="xs"
style={{
width: '60px',
width: '3.75rem',
borderColor: 'var(--color-gray-300)'
}}
/>

View File

@ -1,3 +1,9 @@
@import 'material-symbols/rounded.css';
.material-symbols-rounded {
font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',