Feature/v2/all tools sidebar (#4151)

# Description of Changes

- Added the all tools sidebar
- Added a TextFit component that shrinks text to fit containers
- Added a TopToolIcon on the nav, that animates down to give users
feedback on what tool is selected
- Added the baseToolRegistry, to replace the old pattern of listing
tools, allowing us to clean up the ToolRegistry code
- Fixed Mantine light/dark theme race condition 
- General styling tweaks

---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing)
for more details.
This commit is contained in:
EthanHealy01
2025-08-19 13:31:09 +01:00
committed by GitHub
parent c1b7911518
commit 8f32082145
40 changed files with 2617 additions and 451 deletions
+17 -26
View File
@@ -5,9 +5,8 @@
import React, { createContext, useContext, useReducer, useCallback, useMemo } from 'react';
import { useToolManagement } from '../hooks/useToolManagement';
import { useToolUrlRouting } from '../hooks/useToolUrlRouting';
import { Tool } from '../types/tool';
import { PageEditorFunctions } from '../types/pageEditor';
import { ToolRegistryEntry } from '../data/toolsTaxonomy';
// State interface
interface ToolWorkflowState {
@@ -70,9 +69,9 @@ function toolWorkflowReducer(state: ToolWorkflowState, action: ToolWorkflowActio
interface ToolWorkflowContextValue extends ToolWorkflowState {
// Tool management (from hook)
selectedToolKey: string | null;
selectedTool: Tool | null;
selectedTool: ToolRegistryEntry | null;
toolRegistry: any; // From useToolManagement
// UI Actions
setSidebarsVisible: (visible: boolean) => void;
setLeftPanelView: (view: 'toolPicker' | 'toolContent') => void;
@@ -91,7 +90,7 @@ interface ToolWorkflowContextValue extends ToolWorkflowState {
handleReaderToggle: () => void;
// Computed values
filteredTools: [string, any][]; // Filtered by search
filteredTools: [string, ToolRegistryEntry][]; // Filtered by search
isPanelVisible: boolean;
}
@@ -143,11 +142,22 @@ export function ToolWorkflowProvider({ children, onViewChange }: ToolWorkflowPro
// Workflow actions (compound actions that coordinate multiple state changes)
const handleToolSelect = useCallback((toolId: string) => {
// Special-case: if tool is a dedicated reader tool, enter reader mode and do not go to toolContent
if (toolId === 'read' || toolId === 'view-pdf') {
setReaderMode(true);
setLeftPanelView('toolPicker');
clearToolSelection();
setSearchQuery('');
return;
}
selectTool(toolId);
onViewChange?.('fileEditor');
setLeftPanelView('toolContent');
setReaderMode(false);
}, [selectTool, onViewChange, setLeftPanelView, setReaderMode]);
// Clear search so the tool content becomes visible immediately
setSearchQuery('');
}, [selectTool, onViewChange, setLeftPanelView, setReaderMode, setSearchQuery, clearToolSelection]);
const handleBackToTools = useCallback(() => {
setLeftPanelView('toolPicker');
@@ -159,20 +169,6 @@ export function ToolWorkflowProvider({ children, onViewChange }: ToolWorkflowPro
setReaderMode(true);
}, [setReaderMode]);
// URL routing functionality
const { getToolUrlSlug, getToolKeyFromSlug } = useToolUrlRouting({
selectedToolKey,
toolRegistry,
selectTool,
clearToolSelection,
// During initial load, we want the full UI side-effects (like before):
onInitSelect: handleToolSelect,
// For back/forward nav, keep it lightweight like before (selection only):
onPopStateSelect: selectTool,
// If your app serves under a subpath, provide basePath here (e.g., '/app')
// basePath: ''
});
// Filter tools based on search query
const filteredTools = useMemo(() => {
if (!toolRegistry) return [];
@@ -228,9 +224,4 @@ export function useToolWorkflow(): ToolWorkflowContextValue {
throw new Error('useToolWorkflow must be used within a ToolWorkflowProvider');
}
return context;
}
// Convenience exports for specific use cases (optional - components can use useToolWorkflow directly)
export const useToolSelection = useToolWorkflow;
export const useToolPanelState = useToolWorkflow;
export const useWorkbenchState = useToolWorkflow;
}