Skip to content

Commit

Permalink
[DataEntry] Don't auto-highlight gloss spelling suggestions (#2567)
Browse files Browse the repository at this point in the history
This prevents having to press enter twice (unless the user intentionally makes a selection from the suggestions).
Also, change `handleEnterAndTab` to `handleEnter` and remove unnecessary Tab handling.
  • Loading branch information
imnasnainaec authored Sep 21, 2023
1 parent e75fe85 commit 40bfc19
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 57 deletions.
2 changes: 1 addition & 1 deletion src/components/DataEntry/DataEntryHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default function DataEntryHeader(
color="primary"
style={{ paddingTop: "8px" }}
disabled={!domain.questions.length}
onKeyPress={(e) => {
onKeyDown={(e) => {
if (e.key === Key.Enter) {
props.setQuestionVisibility(!props.questionsVisible);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ interface GlossWithSuggestionsProps {
isNew?: boolean;
isDisabled?: boolean;
gloss: string;
glossInput?: React.RefObject<HTMLDivElement>;
glossInput?: React.RefObject<HTMLInputElement>;
updateGlossField: (newValue: string) => void;
handleEnterAndTab: (e: React.KeyboardEvent) => void;
handleEnter: () => void;
onBlur?: () => void;
analysisLang: WritingSystem;
textFieldId: string;
Expand All @@ -39,13 +39,16 @@ export default function GlossWithSuggestions(
<Autocomplete
id={props.textFieldId}
disabled={props.isDisabled}
filterOptions={(options: unknown[]) =>
filterOptions={(options: string[]) =>
options.length <= maxSuggestions
? options
: options.slice(0, maxSuggestions)
}
// freeSolo allows use of a typed entry not available as a drop-down option
freeSolo
includeInputInList
// option-never-equals-value prevents automatic option highlighting
isOptionEqualToValue={() => false}
options={spellChecker.getSpellingSuggestions(props.gloss)}
value={props.gloss}
onBlur={() => {
Expand All @@ -54,11 +57,12 @@ export default function GlossWithSuggestions(
}
}}
onChange={(_e, newValue) => {
const newText = newValue ? (newValue as string) : "";
props.updateGlossField(newText);
// onChange is triggered when an option is selected
props.updateGlossField(newValue ?? "");
}}
inputValue={props.gloss}
onInputChange={(_e, newInputValue) => {
// onInputChange is triggered by typing
props.updateGlossField(newInputValue);
}}
renderInput={(params) => (
Expand All @@ -73,9 +77,8 @@ export default function GlossWithSuggestions(
/>
)}
onKeyPress={(e: React.KeyboardEvent) => {
if (e.key === Key.Enter || e.key === Key.Tab) {
e.preventDefault();
props.handleEnterAndTab(e);
if (e.key === Key.Enter) {
props.handleEnter();
}
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ interface VernWithSuggestionsProps {
isNew?: boolean;
isDisabled?: boolean;
vernacular: string;
vernInput?: React.RefObject<HTMLDivElement>;
vernInput?: React.RefObject<HTMLInputElement>;
updateVernField: (newValue: string, openDialog?: boolean) => void;
onBlur: () => void;
onClose?: (e: React.ChangeEvent<{}>, reason: AutocompleteCloseReason) => void;
suggestedVerns?: string[];
handleEnterAndTab: (e: React.KeyboardEvent) => void;
handleEnter: () => void;
vernacularLang: WritingSystem;
textFieldId: string;
onUpdate?: () => void;
Expand Down Expand Up @@ -50,9 +50,8 @@ export default function VernWithSuggestions(
props.updateVernField(value);
}}
onKeyPress={(e: React.KeyboardEvent) => {
if (e.key === Key.Enter || e.key === Key.Tab) {
e.preventDefault();
props.handleEnterAndTab(e);
if (e.key === Key.Enter) {
props.handleEnter();
}
}}
onClose={props.onClose}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ describe("GlossWithSuggestions", () => {
renderer.create(
<GlossWithSuggestions
gloss={"gloss"}
glossInput={React.createRef<HTMLDivElement>()}
glossInput={React.createRef<HTMLInputElement>()}
updateGlossField={jest.fn()}
handleEnterAndTab={jest.fn()}
handleEnter={jest.fn()}
analysisLang={newWritingSystem()}
textFieldId={"test-gloss"}
/>
Expand All @@ -36,9 +36,9 @@ describe("GlossWithSuggestions", () => {
<GlossWithSuggestions
isNew
gloss={""}
glossInput={React.createRef<HTMLDivElement>()}
glossInput={React.createRef<HTMLInputElement>()}
updateGlossField={jest.fn()}
handleEnterAndTab={jest.fn()}
handleEnter={jest.fn()}
analysisLang={newWritingSystem()}
textFieldId={"test-gloss-new"}
/>
Expand All @@ -52,9 +52,9 @@ describe("GlossWithSuggestions", () => {
<GlossWithSuggestions
isDisabled
gloss={""}
glossInput={React.createRef<HTMLDivElement>()}
glossInput={React.createRef<HTMLInputElement>()}
updateGlossField={jest.fn()}
handleEnterAndTab={jest.fn()}
handleEnter={jest.fn()}
analysisLang={newWritingSystem()}
textFieldId={"test-gloss-disabled"}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ describe("VernWithSuggestions", () => {
renderer.create(
<VernWithSuggestions
vernacular={"vern"}
vernInput={React.createRef<HTMLDivElement>()}
vernInput={React.createRef<HTMLInputElement>()}
updateVernField={jest.fn()}
handleEnterAndTab={jest.fn()}
handleEnter={jest.fn()}
onBlur={jest.fn()}
vernacularLang={newWritingSystem()}
textFieldId={"test-vern"}
Expand All @@ -37,9 +37,9 @@ describe("VernWithSuggestions", () => {
<VernWithSuggestions
isNew
vernacular={""}
vernInput={React.createRef<HTMLDivElement>()}
vernInput={React.createRef<HTMLInputElement>()}
updateVernField={jest.fn()}
handleEnterAndTab={jest.fn()}
handleEnter={jest.fn()}
onBlur={jest.fn()}
vernacularLang={newWritingSystem()}
textFieldId={"test-vern-new"}
Expand All @@ -54,9 +54,9 @@ describe("VernWithSuggestions", () => {
<VernWithSuggestions
isDisabled
vernacular={""}
vernInput={React.createRef<HTMLDivElement>()}
vernInput={React.createRef<HTMLInputElement>()}
updateVernField={jest.fn()}
handleEnterAndTab={jest.fn()}
handleEnter={jest.fn()}
onBlur={jest.fn()}
vernacularLang={newWritingSystem()}
textFieldId={"test-vern-disabled"}
Expand Down
35 changes: 14 additions & 21 deletions src/components/DataEntry/DataEntryTable/NewEntry/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { AutocompleteCloseReason, Grid, Typography } from "@mui/material";
import {
CSSProperties,
KeyboardEvent,
ReactElement,
RefObject,
useCallback,
Expand All @@ -11,7 +10,6 @@ import {
} from "react";
import { useTranslation } from "react-i18next";
import { useSelector } from "react-redux";
import { Key } from "ts-key-enum";

import { Word, WritingSystem } from "api/models";
import { focusInput } from "components/DataEntry/DataEntryTable";
Expand Down Expand Up @@ -56,7 +54,7 @@ interface NewEntryProps {
setNewNote: (note: string) => void;
newVern: string;
setNewVern: (vern: string) => void;
vernInput: RefObject<HTMLDivElement>;
vernInput: RefObject<HTMLInputElement>;
// Parent component handles vern suggestion state:
selectedDup?: Word;
setSelectedDup: (id?: string) => void;
Expand Down Expand Up @@ -101,7 +99,7 @@ export default function NewEntry(props: NewEntryProps): ReactElement {
const [vernOpen, setVernOpen] = useState(false);
const [wasTreeClosed, setWasTreeClosed] = useState(false);

const glossInput = useRef<HTMLDivElement>(null);
const glossInput = useRef<HTMLInputElement>(null);

const focus = useCallback(
(target: FocusTarget): void => {
Expand Down Expand Up @@ -183,23 +181,18 @@ export default function NewEntry(props: NewEntryProps): ReactElement {
}
};

const handleEnter = async (
e: KeyboardEvent,
checkGloss: boolean
): Promise<void> => {
if ((true || !vernOpen) && e.key === Key.Enter) {
// The user can never submit a new entry without a vernacular
if (newVern) {
// The user can conditionally submit a new entry without a gloss
if (newGloss || !checkGloss) {
await addOrUpdateWord();
focus(FocusTarget.Vernacular);
} else {
focus(FocusTarget.Gloss);
}
} else {
const handleEnter = async (checkGloss: boolean): Promise<void> => {
// The user can never submit a new entry without a vernacular
if (newVern) {
// The user can conditionally submit a new entry without a gloss
if (newGloss || !checkGloss) {
await addOrUpdateWord();
focus(FocusTarget.Vernacular);
} else {
focus(FocusTarget.Gloss);
}
} else {
focus(FocusTarget.Vernacular);
}
};

Expand Down Expand Up @@ -251,7 +244,7 @@ export default function NewEntry(props: NewEntryProps): ReactElement {
suggestedVerns={suggestedVerns}
// To prevent unintentional no-gloss submissions:
// If enter pressed from the vern field, check whether gloss is empty
handleEnterAndTab={(e: KeyboardEvent) => handleEnter(e, true)}
handleEnter={() => handleEnter(true)}
vernacularLang={vernacularLang}
textFieldId={`${idAffix}-vernacular`}
onUpdate={() => conditionalFocus(FocusTarget.Vernacular)}
Expand Down Expand Up @@ -280,7 +273,7 @@ export default function NewEntry(props: NewEntryProps): ReactElement {
updateGlossField={setNewGloss}
// To allow intentional no-gloss submissions:
// If enter pressed from the gloss field, don't check whether gloss is empty
handleEnterAndTab={(e: KeyboardEvent) => handleEnter(e, false)}
handleEnter={() => handleEnter(false)}
analysisLang={analysisLang}
textFieldId={`${idAffix}-gloss`}
onUpdate={() => conditionalFocus(FocusTarget.Gloss)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe("NewEntry", () => {
setNewNote={jest.fn()}
newVern={""}
setNewVern={jest.fn()}
vernInput={createRef<HTMLDivElement>()}
vernInput={createRef<HTMLInputElement>()}
// Parent component handles vern suggestion state:
setSelectedDup={jest.fn()}
suggestedVerns={[]}
Expand Down
12 changes: 4 additions & 8 deletions src/components/DataEntry/DataEntryTable/RecentEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,8 @@ export default function RecentEntry(props: RecentEntryProps): ReactElement {
isDisabled={props.disabled || props.entry.senses.length > 1}
updateVernField={setVernacular}
onBlur={() => conditionallyUpdateVern()}
handleEnterAndTab={() => {
if (vernacular) {
props.focusNewEntry();
}
handleEnter={() => {
vernacular && props.focusNewEntry();
}}
vernacularLang={props.vernacularLang}
textFieldId={`${idAffix}-${props.rowIndex}-vernacular`}
Expand All @@ -97,10 +95,8 @@ export default function RecentEntry(props: RecentEntryProps): ReactElement {
isDisabled={props.disabled}
updateGlossField={setGloss}
onBlur={() => conditionallyUpdateGloss()}
handleEnterAndTab={() => {
if (gloss) {
props.focusNewEntry();
}
handleEnter={() => {
gloss && props.focusNewEntry();
}}
analysisLang={props.analysisLang}
textFieldId={`${idAffix}-${props.rowIndex}-gloss`}
Expand Down
2 changes: 1 addition & 1 deletion src/components/DataEntry/DataEntryTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ export default function DataEntryTable(
});

const levDist = useMemo(() => new LevenshteinDistance(), []);
const newVernInput = useRef<HTMLDivElement>(null);
const newVernInput = useRef<HTMLInputElement>(null);
const spellChecker = useContext(SpellCheckerContext);
useEffect(() => {
spellChecker.updateLang(analysisLang.bcp47);
Expand Down

0 comments on commit 40bfc19

Please sign in to comment.