diff --git a/frontend/src/components/shared/FitText.tsx b/frontend/src/components/shared/FitText.tsx index bea17ddef..0a5e2711b 100644 --- a/frontend/src/components/shared/FitText.tsx +++ b/frontend/src/components/shared/FitText.tsx @@ -63,7 +63,8 @@ const FitText: React.FC = ({ wordBreak: lines > 1 ? ('keep-all' as any) : ('normal' as any), overflowWrap: 'normal', hyphens: 'manual', - fontSize: fontSize ? `${fontSize}px` : undefined, + // fontSize expects rem values (e.g., 1.2, 0.9) to scale with global font size + fontSize: fontSize ? `${fontSize}rem` : undefined, }; return ( diff --git a/frontend/src/components/shared/QuickAccessBar.tsx b/frontend/src/components/shared/QuickAccessBar.tsx index ad731652f..11b60f3c8 100644 --- a/frontend/src/components/shared/QuickAccessBar.tsx +++ b/frontend/src/components/shared/QuickAccessBar.tsx @@ -16,7 +16,7 @@ import TopToolIndicator from './quickAccessBar/TopToolIndicator'; import { isNavButtonActive, getNavButtonStyle, - getTargetNavButton + getActiveNavButton } from './quickAccessBar/QuickAccessBar'; const QuickAccessBar = forwardRef(({ @@ -24,36 +24,21 @@ const QuickAccessBar = forwardRef(({ const { t } = useTranslation(); const { isRainbowMode } = useRainbowThemeContext(); const { openFilesModal, isFilesModalOpen } = useFilesModalContext(); - const { handleReaderToggle, selectedTool, selectedToolKey, leftPanelView } = useToolWorkflow(); + const { handleReaderToggle, handleBackToTools, selectedTool, selectedToolKey, leftPanelView } = useToolWorkflow(); const [configModalOpen, setConfigModalOpen] = useState(false); const [activeButton, setActiveButton] = useState('tools'); const scrollableRef = useRef(null); const isOverflow = useIsOverflowing(scrollableRef); - // Sync left nav highlight with selected tool when appropriate useEffect(() => { - if (leftPanelView === 'toolContent' && selectedTool) { - const target = getTargetNavButton(selectedTool, selectedToolKey); - - if (target && activeButton !== target) { - setActiveButton(target); - 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 - if (leftPanelView !== 'toolContent') { - setActiveButton('tools'); - } + setActiveButton(getActiveNavButton(leftPanelView, selectedTool, selectedToolKey)); }, [leftPanelView, selectedTool, selectedToolKey]); const handleFilesButtonClick = () => { openFilesModal(); }; + const buttonConfigs: ButtonConfig[] = [ { id: 'read', @@ -64,6 +49,9 @@ const QuickAccessBar = forwardRef(({ type: 'navigation', onClick: () => { setActiveButton('read'); + // Clear any selected tool and return to picker so the top tool indicator hides + handleBackToTools(); + // Then enter reader mode handleReaderToggle(); } }, @@ -77,7 +65,11 @@ const QuickAccessBar = forwardRef(({ size: 'lg', isRound: false, type: 'navigation', - onClick: () => setActiveButton('sign') + onClick: () => { + setActiveButton('sign'); + // Ensure any previously selected tool is cleared so indicator hides + handleBackToTools(); + } }, { id: 'automate', @@ -89,7 +81,11 @@ const QuickAccessBar = forwardRef(({ size: 'lg', isRound: false, type: 'navigation', - onClick: () => setActiveButton('automate') + onClick: () => { + setActiveButton('automate'); + // Ensure any previously selected tool is cleared so indicator hides + handleBackToTools(); + } }, { id: 'files', diff --git a/frontend/src/components/shared/fitText/FitText.README.md b/frontend/src/components/shared/fitText/FitText.README.md index 8b28a1b03..827ab5d8f 100644 --- a/frontend/src/components/shared/fitText/FitText.README.md +++ b/frontend/src/components/shared/fitText/FitText.README.md @@ -34,7 +34,7 @@ export function CardTitle({ title }: { title: string }) { | Prop | Type | Default | Description | |------|------|---------|-------------| | `text` | `string` | — | The string to render and fit | -| `fontSize` | `number` | computed | Maximum starting font size in px | +| `fontSize` | `number` | computed | Maximum starting font size in rem (e.g., 1.2, 0.9) | | `minimumFontScale` | `number` | `0.8` | Smallest scale relative to the max (0..1) | | `lines` | `number` | `1` | Maximum number of lines to display and fit | | `className` | `string` | — | Optional class on the rendered element | @@ -67,7 +67,7 @@ Notes: ### Explicit starting size ```tsx - + ``` ### Render as a div @@ -107,5 +107,6 @@ export function CustomFit() { - For predictable measurements, ensure the container has a fixed width (or stable layout) when fitting occurs. - Avoid animating width while fitting; update after animation completes for best results. - When you need more control of typography, pass `fontSize` to define the starting ceiling. +- **Important**: The `fontSize` prop expects `rem` values (e.g., 1.2, 0.9) to ensure text scales with global font size changes. diff --git a/frontend/src/components/shared/quickAccessBar/QuickAccessBar.ts b/frontend/src/components/shared/quickAccessBar/QuickAccessBar.ts index be9b75ec6..cafd99278 100644 --- a/frontend/src/components/shared/quickAccessBar/QuickAccessBar.ts +++ b/frontend/src/components/shared/quickAccessBar/QuickAccessBar.ts @@ -1,15 +1,9 @@ import { ButtonConfig } from '../../../types/sidebar'; +import { useFlatToolRegistry } from '../../../data/toolRegistry'; // 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 */ @@ -42,7 +36,7 @@ export const getNavButtonStyle = ( backgroundColor: `var(--icon-${config.id}-bg)`, color: `var(--icon-${config.id}-color)`, border: 'none', - borderRadius: getNavButtonBorderRadius(config), + borderRadius: ROUND_BORDER_RADIUS, }; } @@ -51,23 +45,38 @@ export const getNavButtonStyle = ( backgroundColor: 'var(--icon-inactive-bg)', color: 'var(--icon-inactive-color)', border: 'none', - borderRadius: getNavButtonBorderRadius(config), + borderRadius: ROUND_BORDER_RADIUS, }; }; /** - * Determine which nav button should be highlighted based on selected tool + * Determine which nav button should be highlighted based on the tool registry. + * Uses the tool's `view` property to map to the nav button id. */ -export const getTargetNavButton = (selectedTool: any, selectedToolKey: string | null): string | null => { - if (!selectedTool || !selectedToolKey) return null; - - // Map specific tool keys to nav button ids - if (selectedToolKey === 'sign') return 'sign'; - if (selectedToolKey === 'read') return 'read'; - if (selectedToolKey === 'automate') return 'automate'; - - // Fallback: use subcategory for automation tools - if (selectedTool.subcategory === 'Automation') return 'automate'; - - return null; +export const getTargetNavButton = ( + selectedToolKey: string | null, + registry: ReturnType +): string | null => { + if (!selectedToolKey) return null; + + const toolEntry = registry[selectedToolKey]; + if (!toolEntry) return null; + + // Use the tool's view as the nav button id + return toolEntry.view || null; +}; + +/** + * Determine the active nav button based on current tool state and registry + */ +export const getActiveNavButton = ( + leftPanelView: 'toolPicker' | 'toolContent', + selectedToolKey: string | null, + registry: ReturnType +): string => { + if (leftPanelView !== 'toolContent' || !selectedToolKey) { + return 'tools'; + } + + return getTargetNavButton(selectedToolKey, registry) || 'tools'; };