mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-08-22 04:09:22 +00:00
change the border radius of the nav items to match matts design and remove colored top tool icon
This commit is contained in:
parent
f6594144f9
commit
443e355774
@ -13,6 +13,11 @@ import './quickAccessBar/QuickAccessBar.css';
|
|||||||
import AllToolsNavButton from './AllToolsNavButton';
|
import AllToolsNavButton from './AllToolsNavButton';
|
||||||
import { Tooltip } from './Tooltip';
|
import { Tooltip } from './Tooltip';
|
||||||
import TopToolIndicator from './quickAccessBar/TopToolIndicator';
|
import TopToolIndicator from './quickAccessBar/TopToolIndicator';
|
||||||
|
import {
|
||||||
|
isNavButtonActive,
|
||||||
|
getNavButtonStyle,
|
||||||
|
getTargetNavButton
|
||||||
|
} from './quickAccessBar/QuickAccessBar';
|
||||||
|
|
||||||
const QuickAccessBar = forwardRef<HTMLDivElement>(({
|
const QuickAccessBar = forwardRef<HTMLDivElement>(({
|
||||||
}, ref) => {
|
}, ref) => {
|
||||||
@ -27,17 +32,16 @@ const QuickAccessBar = forwardRef<HTMLDivElement>(({
|
|||||||
// Sync left nav highlight with selected tool when appropriate
|
// Sync left nav highlight with selected tool when appropriate
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (leftPanelView === 'toolContent' && selectedTool) {
|
if (leftPanelView === 'toolContent' && selectedTool) {
|
||||||
let target: string | null = null;
|
const target = getTargetNavButton(selectedTool);
|
||||||
// Map tool.view to nav button ids
|
|
||||||
if (selectedTool.view === 'sign') target = 'sign';
|
|
||||||
if (selectedTool.view === 'view') target = 'read';
|
|
||||||
// Use subcategory to infer Automate group
|
|
||||||
if (!target && selectedTool.subcategory === 'Automation') target = 'automate';
|
|
||||||
|
|
||||||
if (target && activeButton !== target) {
|
if (target && activeButton !== target) {
|
||||||
setActiveButton(target);
|
setActiveButton(target);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// If tool doesn't map to a nav button, clear the highlight
|
||||||
|
if (!target && activeButton !== 'tools') {
|
||||||
|
setActiveButton('tools');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Revert highlight when no specific mapping applies
|
// Revert highlight when no specific mapping applies
|
||||||
if (leftPanelView !== 'toolContent') {
|
if (leftPanelView !== 'toolContent') {
|
||||||
@ -92,7 +96,7 @@ const QuickAccessBar = forwardRef<HTMLDivElement>(({
|
|||||||
{
|
{
|
||||||
id: 'files',
|
id: 'files',
|
||||||
name: 'Files',
|
name: 'Files',
|
||||||
icon: <FolderIcon sx={{ fontSize: "1.5rem" }} />,
|
icon: <FolderIcon sx={{ fontSize: "1.25rem" }} />,
|
||||||
tooltip: 'Manage files',
|
tooltip: 'Manage files',
|
||||||
isRound: true,
|
isRound: true,
|
||||||
size: 'lg',
|
size: 'lg',
|
||||||
@ -125,41 +129,7 @@ const QuickAccessBar = forwardRef<HTMLDivElement>(({
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const CIRCULAR_BORDER_RADIUS = '50%';
|
|
||||||
const ROUND_BORDER_RADIUS = '8px';
|
|
||||||
|
|
||||||
const getBorderRadius = (config: ButtonConfig): string => {
|
|
||||||
return config.isRound ? CIRCULAR_BORDER_RADIUS : ROUND_BORDER_RADIUS;
|
|
||||||
};
|
|
||||||
|
|
||||||
const isButtonActive = (config: ButtonConfig): boolean => {
|
|
||||||
return (
|
|
||||||
(config.type === 'navigation' && activeButton === config.id) ||
|
|
||||||
(config.type === 'modal' && config.id === 'files' && isFilesModalOpen) ||
|
|
||||||
(config.type === 'modal' && config.id === 'config' && configModalOpen)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const getButtonStyle = (config: ButtonConfig) => {
|
|
||||||
const isActive = isButtonActive(config);
|
|
||||||
|
|
||||||
if (isActive) {
|
|
||||||
return {
|
|
||||||
backgroundColor: `var(--icon-${config.id}-bg)`,
|
|
||||||
color: `var(--icon-${config.id}-color)`,
|
|
||||||
border: 'none',
|
|
||||||
borderRadius: getBorderRadius(config),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inactive state for all buttons
|
|
||||||
return {
|
|
||||||
backgroundColor: 'var(--icon-inactive-bg)',
|
|
||||||
color: 'var(--icon-inactive-color)',
|
|
||||||
border: 'none',
|
|
||||||
borderRadius: getBorderRadius(config),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -202,20 +172,20 @@ const QuickAccessBar = forwardRef<HTMLDivElement>(({
|
|||||||
<Tooltip content={config.tooltip} position="right" arrow containerStyle={{ marginTop: "-1rem" }} maxWidth={200}>
|
<Tooltip content={config.tooltip} position="right" arrow containerStyle={{ marginTop: "-1rem" }} maxWidth={200}>
|
||||||
<div className="flex flex-col items-center gap-1" style={{ marginTop: index === 0 ? '0.5rem' : "0rem" }}>
|
<div className="flex flex-col items-center gap-1" style={{ marginTop: index === 0 ? '0.5rem' : "0rem" }}>
|
||||||
<ActionIcon
|
<ActionIcon
|
||||||
size={isButtonActive(config) ? (config.size || 'xl') : 'lg'}
|
size={isNavButtonActive(config, activeButton, isFilesModalOpen, configModalOpen) ? (config.size || 'xl') : 'lg'}
|
||||||
variant="subtle"
|
variant="subtle"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
config.onClick();
|
config.onClick();
|
||||||
}}
|
}}
|
||||||
style={getButtonStyle(config)}
|
style={getNavButtonStyle(config, activeButton, isFilesModalOpen, configModalOpen)}
|
||||||
className={isButtonActive(config) ? 'activeIconScale' : ''}
|
className={isNavButtonActive(config, activeButton, isFilesModalOpen, configModalOpen) ? 'activeIconScale' : ''}
|
||||||
data-testid={`${config.id}-button`}
|
data-testid={`${config.id}-button`}
|
||||||
>
|
>
|
||||||
<span className="iconContainer">
|
<span className="iconContainer">
|
||||||
{config.icon}
|
{config.icon}
|
||||||
</span>
|
</span>
|
||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
<span className={`button-text ${isButtonActive(config) ? 'active' : 'inactive'}`}>
|
<span className={`button-text ${isNavButtonActive(config, activeButton, isFilesModalOpen, configModalOpen) ? 'active' : 'inactive'}`}>
|
||||||
{config.name}
|
{config.name}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@ -245,15 +215,15 @@ const QuickAccessBar = forwardRef<HTMLDivElement>(({
|
|||||||
size={config.size || 'lg'}
|
size={config.size || 'lg'}
|
||||||
variant="subtle"
|
variant="subtle"
|
||||||
onClick={config.onClick}
|
onClick={config.onClick}
|
||||||
style={getButtonStyle(config)}
|
style={getNavButtonStyle(config, activeButton, isFilesModalOpen, configModalOpen)}
|
||||||
className={isButtonActive(config) ? 'activeIconScale' : ''}
|
className={isNavButtonActive(config, activeButton, isFilesModalOpen, configModalOpen) ? 'activeIconScale' : ''}
|
||||||
data-testid={`${config.id}-button`}
|
data-testid={`${config.id}-button`}
|
||||||
>
|
>
|
||||||
<span className="iconContainer">
|
<span className="iconContainer">
|
||||||
{config.icon}
|
{config.icon}
|
||||||
</span>
|
</span>
|
||||||
</ActionIcon>
|
</ActionIcon>
|
||||||
<span className={`button-text ${isButtonActive(config) ? 'active' : 'inactive'}`}>
|
<span className={`button-text ${isNavButtonActive(config, activeButton, isFilesModalOpen, configModalOpen) ? 'active' : 'inactive'}`}>
|
||||||
{config.name}
|
{config.name}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -0,0 +1,71 @@
|
|||||||
|
import { ButtonConfig } from '../../../types/sidebar';
|
||||||
|
|
||||||
|
// Border radius constants
|
||||||
|
export const ROUND_BORDER_RADIUS = '0.5rem';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get border radius for a button based on its configuration
|
||||||
|
*/
|
||||||
|
export const getNavButtonBorderRadius = (config: ButtonConfig): string => {
|
||||||
|
return config.isRound ? ROUND_BORDER_RADIUS : ROUND_BORDER_RADIUS;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a navigation button is currently active
|
||||||
|
*/
|
||||||
|
export const isNavButtonActive = (
|
||||||
|
config: ButtonConfig,
|
||||||
|
activeButton: string,
|
||||||
|
isFilesModalOpen: boolean,
|
||||||
|
configModalOpen: boolean
|
||||||
|
): boolean => {
|
||||||
|
return (
|
||||||
|
(config.type === 'navigation' && activeButton === config.id) ||
|
||||||
|
(config.type === 'modal' && config.id === 'files' && isFilesModalOpen) ||
|
||||||
|
(config.type === 'modal' && config.id === 'config' && configModalOpen)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get button styles based on active state
|
||||||
|
*/
|
||||||
|
export const getNavButtonStyle = (
|
||||||
|
config: ButtonConfig,
|
||||||
|
activeButton: string,
|
||||||
|
isFilesModalOpen: boolean,
|
||||||
|
configModalOpen: boolean
|
||||||
|
) => {
|
||||||
|
const isActive = isNavButtonActive(config, activeButton, isFilesModalOpen, configModalOpen);
|
||||||
|
|
||||||
|
if (isActive) {
|
||||||
|
return {
|
||||||
|
backgroundColor: `var(--icon-${config.id}-bg)`,
|
||||||
|
color: `var(--icon-${config.id}-color)`,
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: getNavButtonBorderRadius(config),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inactive state for all buttons
|
||||||
|
return {
|
||||||
|
backgroundColor: 'var(--icon-inactive-bg)',
|
||||||
|
color: 'var(--icon-inactive-color)',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: getNavButtonBorderRadius(config),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine which nav button should be highlighted based on selected tool
|
||||||
|
*/
|
||||||
|
export const getTargetNavButton = (selectedTool: any): string | null => {
|
||||||
|
if (!selectedTool) return null;
|
||||||
|
|
||||||
|
// Map tool.view to nav button ids
|
||||||
|
if (selectedTool.view === 'sign') return 'sign';
|
||||||
|
if (selectedTool.view === 'view') return 'read';
|
||||||
|
// Use subcategory to infer Automate group
|
||||||
|
if (selectedTool.subcategory === 'Automation') return 'automate';
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
@ -1,25 +1,23 @@
|
|||||||
import React, { useEffect, useRef, useState, useMemo } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import { ActionIcon, Divider, useMantineColorScheme } from '@mantine/core';
|
import { ActionIcon, Divider } from '@mantine/core';
|
||||||
import ArrowBackRoundedIcon from '@mui/icons-material/ArrowBackRounded';
|
import ArrowBackRoundedIcon from '@mui/icons-material/ArrowBackRounded';
|
||||||
import { useToolWorkflow } from '../../../contexts/ToolWorkflowContext';
|
import { useToolWorkflow } from '../../../contexts/ToolWorkflowContext';
|
||||||
import FitText from '../FitText';
|
import FitText from '../FitText';
|
||||||
import { Tooltip } from '../Tooltip';
|
import { Tooltip } from '../Tooltip';
|
||||||
import { getSubcategoryColor } from '../../../data/toolRegistry';
|
|
||||||
|
|
||||||
interface TopToolIndicatorProps {
|
interface TopToolIndicatorProps {
|
||||||
activeButton: string;
|
activeButton: string;
|
||||||
setActiveButton: (id: string) => void;
|
setActiveButton: (id: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NAV_IDS = ['read','sign','automate','files','activity','config'];
|
const NAV_IDS = ['read','sign','automate'];
|
||||||
|
|
||||||
const TopToolIndicator: React.FC<TopToolIndicatorProps> = ({ activeButton, setActiveButton }) => {
|
const TopToolIndicator: React.FC<TopToolIndicatorProps> = ({ activeButton, setActiveButton }) => {
|
||||||
const { selectedTool, selectedToolKey, leftPanelView, handleBackToTools } = useToolWorkflow();
|
const { selectedTool, selectedToolKey, leftPanelView, handleBackToTools } = useToolWorkflow();
|
||||||
const { colorScheme } = useMantineColorScheme();
|
|
||||||
|
|
||||||
// Determine if the indicator should be visible
|
// Determine if the indicator should be visible
|
||||||
const indicatorShouldShow = Boolean(
|
const indicatorShouldShow = Boolean(
|
||||||
selectedToolKey && selectedTool && activeButton === 'tools' && leftPanelView === 'toolContent' && !NAV_IDS.includes(selectedToolKey)
|
selectedToolKey && selectedTool && leftPanelView === 'toolContent' && !NAV_IDS.includes(selectedToolKey)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Local animation and hover state
|
// Local animation and hover state
|
||||||
@ -64,11 +62,6 @@ const TopToolIndicator: React.FC<TopToolIndicatorProps> = ({ activeButton, setAc
|
|||||||
}
|
}
|
||||||
}, [indicatorShouldShow, selectedTool, selectedToolKey]);
|
}, [indicatorShouldShow, selectedTool, selectedToolKey]);
|
||||||
|
|
||||||
const lightModeBg = useMemo(() => {
|
|
||||||
if (!indicatorTool) return undefined;
|
|
||||||
return getSubcategoryColor(indicatorTool.subcategory || undefined);
|
|
||||||
}, [indicatorTool]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div style={{overflow:'visible'}} className={`current-tool-slot ${indicatorVisible ? 'visible' : ''} ${replayAnim ? 'replay' : ''}`}>
|
<div style={{overflow:'visible'}} className={`current-tool-slot ${indicatorVisible ? 'visible' : ''} ${replayAnim ? 'replay' : ''}`}>
|
||||||
@ -87,12 +80,8 @@ const TopToolIndicator: React.FC<TopToolIndicatorProps> = ({ activeButton, setAc
|
|||||||
}}
|
}}
|
||||||
aria-label={isBackHover ? 'Back to all tools' : indicatorTool.name}
|
aria-label={isBackHover ? 'Back to all tools' : indicatorTool.name}
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: isBackHover
|
backgroundColor: isBackHover ? '#9CA3AF' : 'var(--icon-tools-bg)',
|
||||||
? '#9CA3AF'
|
color: isBackHover ? '#fff' : 'var(--icon-tools-color)',
|
||||||
: (colorScheme === 'light' ? lightModeBg : 'var(--icon-tools-bg)'),
|
|
||||||
color: isBackHover
|
|
||||||
? '#fff'
|
|
||||||
: (colorScheme === 'light' ? '#fff' : 'var(--icon-tools-color)'),
|
|
||||||
border: 'none',
|
border: 'none',
|
||||||
borderRadius: '8px',
|
borderRadius: '8px',
|
||||||
cursor: 'pointer'
|
cursor: 'pointer'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user