refactor(frontend): remove unused React default imports (#4529)

## Description of Changes

- Removed unused `React` default imports across multiple frontend
components.
- Updated imports to only include required React hooks and types (e.g.,
`useState`, `useEffect`, `Suspense`, `createContext`).
- Ensured consistency with React 17+ JSX transform, where default
`React` import is no longer required.
- This cleanup reduces bundle size slightly and aligns code with modern
React best practices.

---

## 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.

Co-authored-by: Reece Browne <74901996+reecebrowne@users.noreply.github.com>
This commit is contained in:
Ludy 2025-09-29 14:01:09 +02:00 committed by GitHub
parent d4985f57d4
commit 02189a67bd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
44 changed files with 90 additions and 113 deletions

View File

@ -1,4 +1,4 @@
import React, { Suspense } from "react"; import { Suspense } from "react";
import { RainbowThemeProvider } from "./components/shared/RainbowThemeProvider"; import { RainbowThemeProvider } from "./components/shared/RainbowThemeProvider";
import { FileContextProvider } from "./contexts/FileContext"; import { FileContextProvider } from "./contexts/FileContext";
import { NavigationProvider } from "./contexts/NavigationContext"; import { NavigationProvider } from "./contexts/NavigationContext";

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { import {
Modal, Modal,
Text, Text,

View File

@ -1,4 +1,4 @@
import React, { useRef } from "react"; import { useRef } from "react";
import { FileButton, Button } from "@mantine/core"; import { FileButton, Button } from "@mantine/core";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";

View File

@ -1,5 +1,4 @@
import { Flex } from '@mantine/core'; import { Flex } from '@mantine/core';
import React from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useCookieConsent } from '../../hooks/useCookieConsent'; import { useCookieConsent } from '../../hooks/useCookieConsent';

View File

@ -1,4 +1,3 @@
import React from "react";
import { Box, Group, Text, Button } from "@mantine/core"; import { Box, Group, Text, Button } from "@mantine/core";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@ -37,7 +36,7 @@ const MultiSelectControls = ({
> >
{t("fileManager.clearSelection", "Clear Selection")} {t("fileManager.clearSelection", "Clear Selection")}
</Button> </Button>
{onAddToUpload && ( {onAddToUpload && (
<Button <Button
size="xs" size="xs"
@ -47,7 +46,7 @@ const MultiSelectControls = ({
{t("fileManager.addToUpload", "Add to Upload")} {t("fileManager.addToUpload", "Add to Upload")}
</Button> </Button>
)} )}
{onOpenInFileEditor && ( {onOpenInFileEditor && (
<Button <Button
size="xs" size="xs"
@ -58,7 +57,7 @@ const MultiSelectControls = ({
{t("fileManager.openInFileEditor", "Open in File Editor")} {t("fileManager.openInFileEditor", "Open in File Editor")}
</Button> </Button>
)} )}
{onOpenInPageEditor && ( {onOpenInPageEditor && (
<Button <Button
size="xs" size="xs"
@ -69,7 +68,7 @@ const MultiSelectControls = ({
{t("fileManager.openInPageEditor", "Open in Page Editor")} {t("fileManager.openInPageEditor", "Open in Page Editor")}
</Button> </Button>
)} )}
{onDeleteAll && ( {onDeleteAll && (
<Button <Button
size="xs" size="xs"
@ -85,4 +84,4 @@ const MultiSelectControls = ({
); );
}; };
export default MultiSelectControls; export default MultiSelectControls;

View File

@ -1,4 +1,3 @@
import React from 'react';
import { Modal, Text, Button, Group, Stack } from '@mantine/core'; import { Modal, Text, Button, Group, Stack } from '@mantine/core';
import { useNavigationGuard } from '../../contexts/NavigationContext'; import { useNavigationGuard } from '../../contexts/NavigationContext';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';

View File

@ -1,4 +1,4 @@
import React, { createContext, useContext, ReactNode } from 'react'; import { createContext, useContext, ReactNode } from 'react';
import { MantineProvider } from '@mantine/core'; import { MantineProvider } from '@mantine/core';
import { useRainbowTheme } from '../../hooks/useRainbowTheme'; import { useRainbowTheme } from '../../hooks/useRainbowTheme';
import { mantineTheme } from '../../theme/mantineTheme'; import { mantineTheme } from '../../theme/mantineTheme';

View File

@ -1,4 +1,3 @@
import React from 'react';
import { useToast } from './ToastContext'; import { useToast } from './ToastContext';
import { ToastInstance, ToastLocation } from './types'; import { ToastInstance, ToastLocation } from './types';
import { LocalIcon } from '../shared/LocalIcon'; import { LocalIcon } from '../shared/LocalIcon';
@ -66,7 +65,7 @@ export default function ToastRenderer() {
<LocalIcon icon={`material-symbols:${getDefaultIconName(t)}`} width={20} height={20} /> <LocalIcon icon={`material-symbols:${getDefaultIconName(t)}`} width={20} height={20} />
)} )}
</div> </div>
{/* Title + count badge */} {/* Title + count badge */}
<div className="toast-title-container"> <div className="toast-title-container">
<span>{t.title}</span> <span>{t.title}</span>
@ -74,7 +73,7 @@ export default function ToastRenderer() {
<span className="toast-count-badge">{t.count}</span> <span className="toast-count-badge">{t.count}</span>
)} )}
</div> </div>
{/* Controls */} {/* Controls */}
<div className="toast-controls"> <div className="toast-controls">
{t.expandable && ( {t.expandable && (
@ -101,20 +100,20 @@ export default function ToastRenderer() {
{/* Progress bar - always show when present */} {/* Progress bar - always show when present */}
{typeof t.progress === 'number' && ( {typeof t.progress === 'number' && (
<div className="toast-progress-container"> <div className="toast-progress-container">
<div <div
className={getProgressBarClass(t)} className={getProgressBarClass(t)}
style={{ width: `${t.progress}%` }} style={{ width: `${t.progress}%` }}
/> />
</div> </div>
)} )}
{/* Body content - only show when expanded */} {/* Body content - only show when expanded */}
{(t.isExpanded || !t.expandable) && ( {(t.isExpanded || !t.expandable) && (
<div className="toast-body"> <div className="toast-body">
{t.body} {t.body}
</div> </div>
)} )}
{/* Button - always show when present, positioned below body */} {/* Button - always show when present, positioned below body */}
{t.buttonText && t.buttonCallback && ( {t.buttonText && t.buttonCallback && (
<div className="toast-action-container"> <div className="toast-action-container">

View File

@ -1,4 +1,4 @@
import React, { Suspense } from "react"; import { Suspense } from "react";
import { useToolWorkflow } from "../../contexts/ToolWorkflowContext"; import { useToolWorkflow } from "../../contexts/ToolWorkflowContext";
import { BaseToolProps } from "../../types/tool"; import { BaseToolProps } from "../../types/tool";
import ToolLoadingFallback from "./ToolLoadingFallback"; import ToolLoadingFallback from "./ToolLoadingFallback";
@ -26,7 +26,7 @@ const ToolRenderer = ({
// Wrap lazy-loaded component with Suspense // Wrap lazy-loaded component with Suspense
return ( return (
<Suspense fallback={<ToolLoadingFallback toolName={selectedTool.name} />}> <Suspense fallback={<ToolLoadingFallback toolName={selectedTool.name} />}>
<ToolComponent <ToolComponent
onPreviewFile={onPreviewFile} onPreviewFile={onPreviewFile}
onComplete={onComplete} onComplete={onComplete}

View File

@ -1,12 +1,11 @@
/** /**
* AddWatermarkSingleStepSettings - Used for automation only * AddWatermarkSingleStepSettings - Used for automation only
* *
* This component combines all watermark settings into a single step interface * This component combines all watermark settings into a single step interface
* for use in the automation system. It includes type selection and all relevant * for use in the automation system. It includes type selection and all relevant
* settings in one unified component. * settings in one unified component.
*/ */
import React from "react";
import { Stack } from "@mantine/core"; import { Stack } from "@mantine/core";
import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters"; import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters";
import WatermarkTypeSettings from "./WatermarkTypeSettings"; import WatermarkTypeSettings from "./WatermarkTypeSettings";
@ -67,4 +66,4 @@ const AddWatermarkSingleStepSettings = ({ parameters, onParameterChange, disable
); );
}; };
export default AddWatermarkSingleStepSettings; export default AddWatermarkSingleStepSettings;

View File

@ -1,4 +1,3 @@
import React from "react";
import { Stack, Checkbox, Group } from "@mantine/core"; import { Stack, Checkbox, Group } from "@mantine/core";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters"; import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters";
@ -80,4 +79,4 @@ const WatermarkFormatting = ({ parameters, onParameterChange, disabled = false }
); );
}; };
export default WatermarkFormatting; export default WatermarkFormatting;

View File

@ -1,4 +1,3 @@
import React from "react";
import { Stack } from "@mantine/core"; import { Stack } from "@mantine/core";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters"; import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters";

View File

@ -1,4 +1,3 @@
import React from "react";
import { Stack, Text, NumberInput } from "@mantine/core"; import { Stack, Text, NumberInput } from "@mantine/core";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters"; import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters";
@ -60,4 +59,4 @@ const WatermarkStyleSettings = ({ parameters, onParameterChange, disabled = fals
); );
}; };
export default WatermarkStyleSettings; export default WatermarkStyleSettings;

View File

@ -1,4 +1,3 @@
import React from "react";
import { Stack, Text, Select, ColorInput } from "@mantine/core"; import { Stack, Text, Select, ColorInput } from "@mantine/core";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters"; import { AddWatermarkParameters } from "../../../hooks/tools/addWatermark/useAddWatermarkParameters";
@ -27,7 +26,7 @@ const WatermarkTextStyle = ({ parameters, onParameterChange, disabled = false }:
format="hex" format="hex"
/> />
</Stack> </Stack>
<Stack gap="xs"> <Stack gap="xs">
<Text size="xs" fw={500}> <Text size="xs" fw={500}>
{t("watermark.settings.alphabet", "Alphabet")} {t("watermark.settings.alphabet", "Alphabet")}

View File

@ -1,4 +1,3 @@
import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Title, Stack, Divider } from "@mantine/core"; import { Title, Stack, Divider } from "@mantine/core";
import AddCircleOutline from "@mui/icons-material/AddCircleOutline"; import AddCircleOutline from "@mui/icons-material/AddCircleOutline";
@ -19,11 +18,11 @@ interface AutomationSelectionProps {
toolRegistry: Record<string, ToolRegistryEntry>; toolRegistry: Record<string, ToolRegistryEntry>;
} }
export default function AutomationSelection({ export default function AutomationSelection({
savedAutomations, savedAutomations,
onCreateNew, onCreateNew,
onRun, onRun,
onEdit, onEdit,
onDelete, onDelete,
onCopyFromSuggested, onCopyFromSuggested,
toolRegistry toolRegistry

View File

@ -1,4 +1,4 @@
import React, { useState } from "react"; import { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Stack, Text, Divider, Collapse, Button, NumberInput } from "@mantine/core"; import { Stack, Text, Divider, Collapse, Button, NumberInput } from "@mantine/core";
import { BookletImpositionParameters } from "../../../hooks/tools/bookletImposition/useBookletImpositionParameters"; import { BookletImpositionParameters } from "../../../hooks/tools/bookletImposition/useBookletImpositionParameters";
@ -176,4 +176,4 @@ const BookletImpositionSettings = ({ parameters, onParameterChange, disabled = f
); );
}; };
export default BookletImpositionSettings; export default BookletImpositionSettings;

View File

@ -1,4 +1,4 @@
import React, { useState } from "react"; import { useState } from "react";
import { Stack, Text, NumberInput, Select, Divider } from "@mantine/core"; import { Stack, Text, NumberInput, Select, Divider } from "@mantine/core";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { CompressParameters } from "../../../hooks/tools/compress/useCompressParameters"; import { CompressParameters } from "../../../hooks/tools/compress/useCompressParameters";

View File

@ -1,4 +1,3 @@
import React from 'react';
import { Stack, Text, NumberInput, Checkbox } from '@mantine/core'; import { Stack, Text, NumberInput, Checkbox } from '@mantine/core';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { ConvertParameters } from '../../../hooks/tools/convert/useConvertParameters'; import { ConvertParameters } from '../../../hooks/tools/convert/useConvertParameters';

View File

@ -1,4 +1,3 @@
import React from "react";
import { Stack, Text, Select, Switch } from "@mantine/core"; import { Stack, Text, Select, Switch } from "@mantine/core";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { COLOR_TYPES, FIT_OPTIONS } from "../../../constants/convertConstants"; import { COLOR_TYPES, FIT_OPTIONS } from "../../../constants/convertConstants";

View File

@ -1,4 +1,3 @@
import React from 'react';
import { Stack, Text, NumberInput, Slider } from '@mantine/core'; import { Stack, Text, NumberInput, Slider } from '@mantine/core';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { ConvertParameters } from '../../../hooks/tools/convert/useConvertParameters'; import { ConvertParameters } from '../../../hooks/tools/convert/useConvertParameters';

View File

@ -1,4 +1,4 @@
import React, { useMemo } from "react"; import { useMemo } from "react";
import { Stack, Text, Group, Divider, UnstyledButton, useMantineTheme, useMantineColorScheme } from "@mantine/core"; import { Stack, Text, Group, Divider, UnstyledButton, useMantineTheme, useMantineColorScheme } from "@mantine/core";
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";

View File

@ -1,4 +1,3 @@
import React from "react";
import { Stack, Text, Select, NumberInput, Group } from "@mantine/core"; import { Stack, Text, Select, NumberInput, Group } from "@mantine/core";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { COLOR_TYPES, OUTPUT_OPTIONS } from "../../../constants/convertConstants"; import { COLOR_TYPES, OUTPUT_OPTIONS } from "../../../constants/convertConstants";

View File

@ -1,4 +1,3 @@
import React from 'react';
import { Stack, Text, Select, Alert } from '@mantine/core'; import { Stack, Text, Select, Alert } from '@mantine/core';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { ConvertParameters } from '../../../hooks/tools/convert/useConvertParameters'; import { ConvertParameters } from '../../../hooks/tools/convert/useConvertParameters';

View File

@ -1,4 +1,4 @@
import React, { useState, useMemo } from "react"; import { useState, useMemo } from "react";
import { Stack, Text, Group, Button, Box, Popover, UnstyledButton, useMantineTheme, useMantineColorScheme } from "@mantine/core"; import { Stack, Text, Group, Button, Box, Popover, UnstyledButton, useMantineTheme, useMantineColorScheme } from "@mantine/core";
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
@ -34,14 +34,14 @@ const GroupedFormatDropdown = ({
const groupedOptions = useMemo(() => { const groupedOptions = useMemo(() => {
const groups: Record<string, FormatOption[]> = {}; const groups: Record<string, FormatOption[]> = {};
options.forEach(option => { options.forEach(option => {
if (!groups[option.group]) { if (!groups[option.group]) {
groups[option.group] = []; groups[option.group] = [];
} }
groups[option.group].push(option); groups[option.group].push(option);
}); });
return groups; return groups;
}, [options]); }, [options]);
@ -77,14 +77,14 @@ const GroupedFormatDropdown = ({
padding: '0.5rem 0.75rem', padding: '0.5rem 0.75rem',
border: `0.0625rem solid ${theme.colors.gray[4]}`, border: `0.0625rem solid ${theme.colors.gray[4]}`,
borderRadius: theme.radius.sm, borderRadius: theme.radius.sm,
backgroundColor: disabled backgroundColor: disabled
? theme.colors.gray[1] ? theme.colors.gray[1]
: colorScheme === 'dark' : colorScheme === 'dark'
? theme.colors.dark[6] ? theme.colors.dark[6]
: theme.white, : theme.white,
cursor: disabled ? 'not-allowed' : 'pointer', cursor: disabled ? 'not-allowed' : 'pointer',
width: '100%', width: '100%',
color: disabled color: disabled
? colorScheme === 'dark' ? theme.colors.dark[1] : theme.colors.dark[7] ? colorScheme === 'dark' ? theme.colors.dark[1] : theme.colors.dark[7]
: colorScheme === 'dark' ? theme.colors.dark[0] : theme.colors.dark[9] : colorScheme === 'dark' ? theme.colors.dark[0] : theme.colors.dark[9]
}} }}
@ -93,19 +93,19 @@ const GroupedFormatDropdown = ({
<Text size="sm" c={value ? undefined : 'dimmed'}> <Text size="sm" c={value ? undefined : 'dimmed'}>
{selectedLabel} {selectedLabel}
</Text> </Text>
<KeyboardArrowDownIcon <KeyboardArrowDownIcon
style={{ style={{
fontSize: '1rem', fontSize: '1rem',
transform: dropdownOpened ? 'rotate(180deg)' : 'rotate(0deg)', transform: dropdownOpened ? 'rotate(180deg)' : 'rotate(0deg)',
transition: 'transform 0.2s ease', transition: 'transform 0.2s ease',
color: colorScheme === 'dark' ? theme.colors.dark[2] : theme.colors.gray[6] color: colorScheme === 'dark' ? theme.colors.dark[2] : theme.colors.gray[6]
}} }}
/> />
</Group> </Group>
</UnstyledButton> </UnstyledButton>
</Popover.Target> </Popover.Target>
<Popover.Dropdown <Popover.Dropdown
style={{ style={{
minWidth: Math.min(350, parseInt(minWidth.replace('rem', '')) * 16), minWidth: Math.min(350, parseInt(minWidth.replace('rem', '')) * 16),
maxWidth: '90vw', maxWidth: '90vw',
maxHeight: '40vh', maxHeight: '40vh',
@ -117,10 +117,10 @@ const GroupedFormatDropdown = ({
<Stack gap="md"> <Stack gap="md">
{Object.entries(groupedOptions).map(([groupName, groupOptions]) => ( {Object.entries(groupedOptions).map(([groupName, groupOptions]) => (
<Box key={groupName}> <Box key={groupName}>
<Text <Text
size="sm" size="sm"
fw={600} fw={600}
c={colorScheme === 'dark' ? 'dark.2' : 'gray.6'} c={colorScheme === 'dark' ? 'dark.2' : 'gray.6'}
mb="xs" mb="xs"
> >
{groupName} {groupName}
@ -153,4 +153,4 @@ const GroupedFormatDropdown = ({
); );
}; };
export default GroupedFormatDropdown; export default GroupedFormatDropdown;

View File

@ -1,4 +1,3 @@
import React from 'react';
import { Divider, Select, Stack, Switch } from '@mantine/core'; import { Divider, Select, Stack, Switch } from '@mantine/core';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { PageLayoutParameters } from '../../../hooks/tools/pageLayout/usePageLayoutParameters'; import { PageLayoutParameters } from '../../../hooks/tools/pageLayout/usePageLayoutParameters';

View File

@ -1,4 +1,3 @@
import React from 'react';
import { Divider, Select, Stack, TextInput } from '@mantine/core'; import { Divider, Select, Stack, TextInput } from '@mantine/core';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { ReorganizePagesParameters } from '../../../hooks/tools/reorganizePages/useReorganizePagesParameters'; import { ReorganizePagesParameters } from '../../../hooks/tools/reorganizePages/useReorganizePagesParameters';
@ -31,7 +30,7 @@ export default function ReorganizePagesSettings({
disabled={disabled} disabled={disabled}
/> />
{selectedMode && ( {selectedMode && (
<div <div
style={{ style={{
backgroundColor: 'var(--information-text-bg)', backgroundColor: 'var(--information-text-bg)',
color: 'var(--information-text-color)', color: 'var(--information-text-color)',

View File

@ -1,4 +1,3 @@
import React from "react";
import { Stack, Text, Select, ColorInput } from "@mantine/core"; import { Stack, Text, Select, ColorInput } from "@mantine/core";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { ReplaceColorParameters } from "../../../hooks/tools/replaceColor/useReplaceColorParameters"; import { ReplaceColorParameters } from "../../../hooks/tools/replaceColor/useReplaceColorParameters";
@ -105,4 +104,4 @@ const ReplaceColorSettings = ({ parameters, onParameterChange, disabled = false
); );
}; };
export default ReplaceColorSettings; export default ReplaceColorSettings;

View File

@ -1,4 +1,3 @@
import React from 'react';
import { Stack, Text } from '@mantine/core'; import { Stack, Text } from '@mantine/core';
import { formatFileSize, getFileDate } from '../../../utils/fileUtils'; import { formatFileSize, getFileDate } from '../../../utils/fileUtils';
@ -24,4 +23,4 @@ const FileMetadata = ({ file }: FileMetadataProps) => {
); );
}; };
export default FileMetadata; export default FileMetadata;

View File

@ -1,4 +1,3 @@
import React from 'react';
import { Stack, Group, ActionIcon, Text } from '@mantine/core'; import { Stack, Group, ActionIcon, Text } from '@mantine/core';
import ChevronLeftIcon from '@mui/icons-material/ChevronLeft'; import ChevronLeftIcon from '@mui/icons-material/ChevronLeft';
import ChevronRightIcon from '@mui/icons-material/ChevronRight'; import ChevronRightIcon from '@mui/icons-material/ChevronRight';

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { Stack, Text, NumberInput } from "@mantine/core"; import { Stack, Text, NumberInput } from "@mantine/core";
interface NumberInputWithUnitProps { interface NumberInputWithUnitProps {
@ -11,14 +11,14 @@ interface NumberInputWithUnitProps {
disabled?: boolean; disabled?: boolean;
} }
const NumberInputWithUnit = ({ const NumberInputWithUnit = ({
label, label,
value, value,
onChange, onChange,
unit, unit,
min, min,
max, max,
disabled = false disabled = false
}: NumberInputWithUnitProps) => { }: NumberInputWithUnitProps) => {
const [localValue, setLocalValue] = useState<number | string>(value); const [localValue, setLocalValue] = useState<number | string>(value);
@ -54,4 +54,4 @@ const NumberInputWithUnit = ({
); );
}; };
export default NumberInputWithUnit; export default NumberInputWithUnit;

View File

@ -1,4 +1,3 @@
import React from 'react';
import { Button } from '@mantine/core'; import { Button } from '@mantine/core';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';

View File

@ -1,4 +1,4 @@
import React, { useState } from 'react'; import { useState } from 'react';
import { Box, Text, Loader, Stack, Center, Flex } from '@mantine/core'; import { Box, Text, Loader, Stack, Center, Flex } from '@mantine/core';
import FilePreview from '../../shared/FilePreview'; import FilePreview from '../../shared/FilePreview';
import FileMetadata from './FileMetadata'; import FileMetadata from './FileMetadata';

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Stack, Button, Text, Alert, Tabs } from '@mantine/core'; import { Stack, Button, Text, Alert, Tabs } from '@mantine/core';
import { SignParameters } from "../../../hooks/tools/sign/useSignParameters"; import { SignParameters } from "../../../hooks/tools/sign/useSignParameters";
@ -256,4 +256,4 @@ const SignSettings = ({
); );
}; };
export default SignSettings; export default SignSettings;

View File

@ -1,4 +1,4 @@
import React, { useState, useRef, useEffect, useMemo } from "react"; import { useState, useRef, useEffect, useMemo } from "react";
import { Stack, Button, Text } from "@mantine/core"; import { Stack, Button, Text } from "@mantine/core";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import LocalIcon from '../../shared/LocalIcon'; import LocalIcon from '../../shared/LocalIcon';

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect, useMemo } from 'react'; import { useState, useEffect, useMemo } from 'react';
import { useSearch } from '@embedpdf/plugin-search/react'; import { useSearch } from '@embedpdf/plugin-search/react';
import { useViewer } from '../../contexts/ViewerContext'; import { useViewer } from '../../contexts/ViewerContext';
import { SEARCH_CONSTANTS } from './constants/search'; import { SEARCH_CONSTANTS } from './constants/search';
@ -24,9 +24,9 @@ interface SearchResultState {
activeResultIndex?: number; activeResultIndex?: number;
} }
export function CustomSearchLayer({ export function CustomSearchLayer({
pageIndex, pageIndex,
scale, scale,
highlightColor = SEARCH_CONSTANTS.HIGHLIGHT_COLORS.BACKGROUND, highlightColor = SEARCH_CONSTANTS.HIGHLIGHT_COLORS.BACKGROUND,
activeHighlightColor = SEARCH_CONSTANTS.HIGHLIGHT_COLORS.ACTIVE_BACKGROUND, activeHighlightColor = SEARCH_CONSTANTS.HIGHLIGHT_COLORS.ACTIVE_BACKGROUND,
opacity = SEARCH_CONSTANTS.HIGHLIGHT_COLORS.OPACITY, opacity = SEARCH_CONSTANTS.HIGHLIGHT_COLORS.OPACITY,
@ -42,17 +42,17 @@ export function CustomSearchLayer({
if (!searchProvides) { if (!searchProvides) {
return; return;
} }
const unsubscribe = searchProvides.onSearchResultStateChange?.((state: SearchResultState) => { const unsubscribe = searchProvides.onSearchResultStateChange?.((state: SearchResultState) => {
// Auto-scroll to active search result // Auto-scroll to active search result
if (state?.results && state.activeResultIndex !== undefined && state.activeResultIndex >= 0) { if (state?.results && state.activeResultIndex !== undefined && state.activeResultIndex >= 0) {
const activeResult = state.results[state.activeResultIndex]; const activeResult = state.results[state.activeResultIndex];
if (activeResult) { if (activeResult) {
const pageNumber = activeResult.pageIndex + 1; // Convert to 1-based page number const pageNumber = activeResult.pageIndex + 1; // Convert to 1-based page number
scrollActions.scrollToPage(pageNumber); scrollActions.scrollToPage(pageNumber);
} }
} }
setSearchResultState(state); setSearchResultState(state);
}); });
@ -69,7 +69,7 @@ export function CustomSearchLayer({
const filtered = searchResultState.results const filtered = searchResultState.results
.map((result, originalIndex) => ({ result, originalIndex })) .map((result, originalIndex) => ({ result, originalIndex }))
.filter(({ result }) => result.pageIndex === pageIndex); .filter(({ result }) => result.pageIndex === pageIndex);
return filtered; return filtered;
}, [searchResultState, pageIndex]); }, [searchResultState, pageIndex]);
@ -78,7 +78,7 @@ export function CustomSearchLayer({
} }
return ( return (
<div style={{ <div style={{
position: 'absolute', position: 'absolute',
top: 0, top: 0,
left: 0, left: 0,
@ -117,4 +117,4 @@ export function CustomSearchLayer({
))} ))}
</div> </div>
); );
} }

View File

@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useState } from 'react'; import { useEffect, useMemo, useState } from 'react';
import { createPluginRegistration } from '@embedpdf/core'; import { createPluginRegistration } from '@embedpdf/core';
import { EmbedPDF } from '@embedpdf/core/react'; import { EmbedPDF } from '@embedpdf/core/react';
import { usePdfiumEngine } from '@embedpdf/engines/react'; import { usePdfiumEngine } from '@embedpdf/engines/react';
@ -312,4 +312,4 @@ export function LocalEmbedPDFWithAnnotations({
</EmbedPDF> </EmbedPDF>
</div> </div>
); );
} }

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { Button, Paper, Group, NumberInput } from '@mantine/core'; import { Button, Paper, Group, NumberInput } from '@mantine/core';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useViewer } from '../../contexts/ViewerContext'; import { useViewer } from '../../contexts/ViewerContext';
@ -14,11 +14,11 @@ interface PdfViewerToolbarProps {
currentPage?: number; currentPage?: number;
totalPages?: number; totalPages?: number;
onPageChange?: (page: number) => void; onPageChange?: (page: number) => void;
// Dual page toggle (placeholder for now) // Dual page toggle (placeholder for now)
dualPage?: boolean; dualPage?: boolean;
onDualPageToggle?: () => void; onDualPageToggle?: () => void;
// Zoom controls (connected via ViewerContext) // Zoom controls (connected via ViewerContext)
currentZoom?: number; currentZoom?: number;
} }
@ -33,7 +33,7 @@ export function PdfViewerToolbar({
}: PdfViewerToolbarProps) { }: PdfViewerToolbarProps) {
const { t } = useTranslation(); const { t } = useTranslation();
const { getScrollState, getZoomState, scrollActions, zoomActions, registerImmediateZoomUpdate, registerImmediateScrollUpdate } = useViewer(); const { getScrollState, getZoomState, scrollActions, zoomActions, registerImmediateZoomUpdate, registerImmediateScrollUpdate } = useViewer();
const scrollState = getScrollState(); const scrollState = getScrollState();
const zoomState = getZoomState(); const zoomState = getZoomState();
const [pageInput, setPageInput] = useState(scrollState.currentPage || currentPage); const [pageInput, setPageInput] = useState(scrollState.currentPage || currentPage);
@ -151,7 +151,7 @@ export function PdfViewerToolbar({
input: { width: 48, textAlign: "center", fontWeight: 500, fontSize: 16 }, input: { width: 48, textAlign: "center", fontWeight: 500, fontSize: 16 },
}} }}
/> />
<span style={{ fontWeight: 500, fontSize: 16 }}> <span style={{ fontWeight: 500, fontSize: 16 }}>
/ {scrollState.totalPages} / {scrollState.totalPages}
</span> </span>
@ -229,4 +229,4 @@ export function PdfViewerToolbar({
</Group> </Group>
</Paper> </Paper>
); );
} }

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { Box, ScrollArea } from '@mantine/core'; import { Box, ScrollArea } from '@mantine/core';
import { useViewer } from '../../contexts/ViewerContext'; import { useViewer } from '../../contexts/ViewerContext';

View File

@ -1,4 +1,3 @@
import React from 'react';
import EmbedPdfViewer from './EmbedPdfViewer'; import EmbedPdfViewer from './EmbedPdfViewer';
export interface ViewerProps { export interface ViewerProps {
@ -13,4 +12,4 @@ const Viewer = (props: ViewerProps) => {
return <EmbedPdfViewer {...props} />; return <EmbedPdfViewer {...props} />;
}; };
export default Viewer; export default Viewer;

View File

@ -12,7 +12,7 @@
* Memory management handled by FileLifecycleManager (PDF.js cleanup, blob URL revocation). * Memory management handled by FileLifecycleManager (PDF.js cleanup, blob URL revocation).
*/ */
import React, { useReducer, useCallback, useEffect, useRef, useMemo } from 'react'; import { useReducer, useCallback, useEffect, useRef, useMemo } from 'react';
import { import {
FileContextProviderProps, FileContextProviderProps,
FileContextSelectors, FileContextSelectors,

View File

@ -1,4 +1,4 @@
import React, { createContext, useContext, useState, useRef, useMemo } from 'react'; import { createContext, useContext, useState, useRef, useMemo } from 'react';
import { SidebarState, SidebarRefs, SidebarContextValue, SidebarProviderProps } from '../types/sidebar'; import { SidebarState, SidebarRefs, SidebarContextValue, SidebarProviderProps } from '../types/sidebar';
const SidebarContext = createContext<SidebarContextValue | undefined>(undefined); const SidebarContext = createContext<SidebarContextValue | undefined>(undefined);
@ -7,7 +7,7 @@ export function SidebarProvider({ children }: SidebarProviderProps) {
// All sidebar state management // All sidebar state management
const quickAccessRef = useRef<HTMLDivElement>(null); const quickAccessRef = useRef<HTMLDivElement>(null);
const toolPanelRef = useRef<HTMLDivElement>(null); const toolPanelRef = useRef<HTMLDivElement>(null);
const [sidebarsVisible, setSidebarsVisible] = useState(true); const [sidebarsVisible, setSidebarsVisible] = useState(true);
const [leftPanelView, setLeftPanelView] = useState<'toolPicker' | 'toolContent'>('toolPicker'); const [leftPanelView, setLeftPanelView] = useState<'toolPicker' | 'toolContent'>('toolPicker');
const [readerMode, setReaderMode] = useState(false); const [readerMode, setReaderMode] = useState(false);
@ -44,4 +44,4 @@ export function useSidebarContext(): SidebarContextValue {
throw new Error('useSidebarContext must be used within a SidebarProvider'); throw new Error('useSidebarContext must be used within a SidebarProvider');
} }
return context; return context;
} }

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useEndpointEnabled } from "../hooks/useEndpointConfig"; import { useEndpointEnabled } from "../hooks/useEndpointConfig";
import { useFileSelection } from "../contexts/FileContext"; import { useFileSelection } from "../contexts/FileContext";

View File

@ -1,4 +1,3 @@
import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { createToolFlow } from "../components/tools/shared/createToolFlow"; import { createToolFlow } from "../components/tools/shared/createToolFlow";
import { BaseToolProps, ToolComponent } from "../types/tool"; import { BaseToolProps, ToolComponent } from "../types/tool";

View File

@ -1,4 +1,4 @@
import React, { useEffect } from "react"; import { useEffect } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { createToolFlow } from "../components/tools/shared/createToolFlow"; import { createToolFlow } from "../components/tools/shared/createToolFlow";
import { BaseToolProps, ToolComponent } from "../types/tool"; import { BaseToolProps, ToolComponent } from "../types/tool";