error validation, allow scrolling on overflow, dont apply changes on blur and make the selected pages container look less like a text-input

This commit is contained in:
EthanHealy01 2025-09-05 15:36:29 +01:00
parent 5ceac64553
commit bb13c24776
2 changed files with 53 additions and 7 deletions

View File

@ -146,9 +146,9 @@
.selectedList { .selectedList {
max-height: 8rem; max-height: 8rem;
overflow: auto; overflow: auto;
border: 0.0625rem solid var(--mantine-color-gray-3); background-color: var(--mantine-color-gray-0);
border-radius: 0.25rem; border-radius: 0.5rem;
padding: 0.5rem; padding: 0.5rem 0.75rem;
margin-top: 0.5rem; margin-top: 0.5rem;
min-width: 24rem; min-width: 24rem;
} }
@ -232,3 +232,30 @@
flex-shrink: 0; flex-shrink: 0;
} }
/* Error helper text above the input */
.errorText {
margin-top: 0.25rem;
color: var(--mantine-color-red-6);
}
/* Dark-mode adjustments */
::global([data-mantine-color-scheme='dark']) .selectedList {
background-color: var(--mantine-color-dark-6);
}
/* Small screens: allow the section to shrink instead of enforcing a large min width */
@media (max-width: 480px) {
.panelGroup,
.selectedList,
.advancedSection,
.panelContainer {
min-width: 0;
}
}
/* Outermost panel container scrolling */
.panelContainer {
max-height: 95vh;
overflow: auto;
}

View File

@ -1,9 +1,10 @@
import { useState } from 'react'; import { useState, useEffect } from 'react';
import { Group, TextInput, Button, Text, NumberInput, Flex } from '@mantine/core'; import { Group, TextInput, Button, Text, NumberInput, Flex } from '@mantine/core';
import LocalIcon from '../shared/LocalIcon'; import LocalIcon from '../shared/LocalIcon';
import { Tooltip } from '../shared/Tooltip'; import { Tooltip } from '../shared/Tooltip';
import { usePageSelectionTips } from '../tooltips/usePageSelectionTips'; import { usePageSelectionTips } from '../tooltips/usePageSelectionTips';
import classes from './BulkSelectionPanel.module.css'; import classes from './BulkSelectionPanel.module.css';
import { parseSelectionWithDiagnostics } from '../../utils/bulkselection/parseSelection';
import { import {
appendExpression, appendExpression,
insertOperatorSmart, insertOperatorSmart,
@ -38,10 +39,26 @@ const BulkSelectionPanel = ({
const [firstNError, setFirstNError] = useState<string | null>(null); const [firstNError, setFirstNError] = useState<string | null>(null);
const [lastNError, setLastNError] = useState<string | null>(null); const [lastNError, setLastNError] = useState<string | null>(null);
const [rangeError, setRangeError] = useState<string | null>(null); const [rangeError, setRangeError] = useState<string | null>(null);
const [syntaxError, setSyntaxError] = useState<string | null>(null);
const maxPages = displayDocument?.pages?.length ?? 0; const maxPages = displayDocument?.pages?.length ?? 0;
// Validate input syntax and show lightweight feedback
useEffect(() => {
const text = (csvInput || '').trim();
if (!text) {
setSyntaxError(null);
return;
}
try {
const { warning } = parseSelectionWithDiagnostics(text, maxPages);
setSyntaxError(warning ? 'There is a syntax issue. See Page Selection tips for help.' : null);
} catch {
setSyntaxError('There is a syntax issue. See Page Selection tips for help.');
}
}, [csvInput, maxPages]);
const applyExpression = (expr: string) => { const applyExpression = (expr: string) => {
const nextInput = appendExpression(csvInput, expr); const nextInput = appendExpression(csvInput, expr);
setCsvInput(nextInput); setCsvInput(nextInput);
@ -62,7 +79,10 @@ const BulkSelectionPanel = ({
}; };
return ( return (
<> <div className={classes.panelContainer}>
{syntaxError && (
<Text size="xs" className={classes.errorText}>{syntaxError}</Text>
)}
<Group className={classes.panelGroup}> <Group className={classes.panelGroup}>
<TextInput <TextInput
value={csvInput} value={csvInput}
@ -106,7 +126,6 @@ const BulkSelectionPanel = ({
</Flex> </Flex>
</Tooltip> </Tooltip>
} }
onBlur={() => onUpdatePagesFromCSV()}
onKeyDown={(e) => e.key === 'Enter' && onUpdatePagesFromCSV()} onKeyDown={(e) => e.key === 'Enter' && onUpdatePagesFromCSV()}
className={classes.textInput} className={classes.textInput}
/> />
@ -364,7 +383,7 @@ const BulkSelectionPanel = ({
</div> </div>
</div> </div>
)} )}
</> </div>
); );
}; };