-
Couldn't load subscription status.
- Fork 39
Handled Backspace at the beginning of the TODO element. #46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,10 @@ | ||
| import React, { FC, useEffect, useRef, useState } from 'react'; | ||
| import React, { | ||
| FC, | ||
| KeyboardEventHandler, | ||
| useEffect, | ||
| useRef, | ||
| useState, | ||
| } from "react"; | ||
|
|
||
| import uuid from 'react-uuid'; | ||
| import { | ||
|
|
@@ -81,6 +87,91 @@ export const Item: FC<Props> = ({ | |
| setItemText(items[itemIndex].name); | ||
| }, [changeFocus, focus, itemIndex, items]); | ||
|
|
||
| useEffect(() => { | ||
| setItemText(items[itemIndex].name); | ||
| }, [items[itemIndex].name]); | ||
|
|
||
| const handleDelete = () => { | ||
| items.splice(itemIndex, 1); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Before changing the items array. Create a copy of items to avoid reference changes directly. You can do something like this. |
||
| setItemsCallback([...items]); | ||
| }; | ||
|
|
||
| const getNthTodoElement = (n: number) => { | ||
| return ( | ||
| document.querySelector<HTMLInputElement>( | ||
| `.${classes.reorderItem}:has(${classes.textFeild}):nth-of-type(${ | ||
| n + 1 | ||
| }) .${classes.textFeild} input` | ||
| ) ?? | ||
| document.querySelectorAll<HTMLInputElement>( | ||
| `.${classes.textFeild} input` | ||
| )[n] | ||
| ); | ||
| }; | ||
|
|
||
| const handleBackspace = () => { | ||
| if (!itemIndex) return; // Do nothing, for first TODO | ||
|
|
||
| if (inputRef.current!.selectionStart) return; // Do nothing if cursor isn't at start. | ||
|
|
||
| let previousItemElement = getNthTodoElement(itemIndex - 1); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can use the predefined setFocus function to focus the element. If you need a selection as well you can add one more method to setSelection. That you can do in different PR if needed. |
||
|
|
||
| const previousItem = items.at(itemIndex - 1)!; | ||
| const previousItemName = previousItem.name; | ||
|
|
||
| if (itemText) { | ||
| previousItem.name = `${previousItemName}${previousItemName ? " " : ""}${itemText}`; | ||
| } | ||
|
|
||
| previousItemElement.focus(); | ||
|
|
||
| // Focusing the element takes a bit time, so if selection is set synchronously the selection is unset. | ||
| setTimeout(() => { | ||
| // Set the cursor position just before the current item name | ||
| const cursorPos = previousItemName?.length! + Number(!!previousItemName); | ||
| previousItemElement.setSelectionRange(cursorPos, cursorPos); | ||
| }, 0); | ||
|
|
||
| handleDelete(); | ||
| return true; | ||
| }; | ||
|
|
||
| const handleKeyDown: KeyboardEventHandler<HTMLDivElement> = (e) => { | ||
| if (e.key === 'Backspace') { | ||
| if (handleBackspace()) e.preventDefault(); | ||
| } | ||
| handleArrowKey(e) | ||
| }; | ||
|
|
||
| const handleArrowKey : KeyboardEventHandler<HTMLDivElement> = (e) => { | ||
| const inputs = document.querySelectorAll("input[type='text']"); | ||
| const inputsArray = Array.from(inputs); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again try to do the same using the setFocus method. |
||
| const index = inputsArray.indexOf( | ||
| inputRef.current as HTMLInputElement | ||
| ); | ||
|
|
||
| if (inputRef.current) { | ||
| if (e.key === 'ArrowUp') { | ||
| // Move cursor to the previous item | ||
| // Checks if the focused item is at the top | ||
| if (index >= 0) { | ||
| const nextInputElement = inputsArray[ | ||
| index - 1 | ||
| ] as HTMLInputElement; | ||
| nextInputElement.focus(); | ||
| } | ||
| } else if (e.key === 'ArrowDown') { | ||
| // Move cursor to the next item | ||
| // Checks if the focused item is at the bottom | ||
| if (index < inputsArray.length - 1) { | ||
| const nextInputElement = inputsArray[ | ||
| index + 1 | ||
| ] as HTMLInputElement; | ||
| nextInputElement.focus(); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| if (!items[itemIndex].isComplete) { | ||
| return ( | ||
| <Reorder.Item | ||
|
|
@@ -144,44 +235,10 @@ export const Item: FC<Props> = ({ | |
| changeFocus(-1) | ||
| } | ||
| } | ||
| onKeyDown={(e) => { | ||
| const inputs = document.querySelectorAll("input[type='text']"); | ||
| const inputsArray = Array.from(inputs); | ||
| const index = inputsArray.indexOf( | ||
| inputRef.current as HTMLInputElement | ||
| ); | ||
|
|
||
| if (inputRef.current) { | ||
| if (e.key === 'ArrowUp') { | ||
| // Move cursor to the previous item | ||
| // Checks if the focused item is at the top | ||
| if (index >= 0) { | ||
| const nextInputElement = inputsArray[ | ||
| index - 1 | ||
| ] as HTMLInputElement; | ||
| nextInputElement.focus(); | ||
| } | ||
| } else if (e.key === 'ArrowDown') { | ||
| // Move cursor to the next item | ||
| // Checks if the focused item is at the bottom | ||
| if (index < inputsArray.length - 1) { | ||
| const nextInputElement = inputsArray[ | ||
| index + 1 | ||
| ] as HTMLInputElement; | ||
| nextInputElement.focus(); | ||
| } | ||
| } | ||
| } | ||
| }} | ||
| onKeyDown={handleKeyDown} | ||
| /> | ||
| </FormControl> | ||
| <CloseIcon | ||
| className={classes.closeIcon} | ||
| onClick={() => { | ||
| items.splice(itemIndex, 1); | ||
| setItemsCallback([...items]); | ||
| }} | ||
| /> | ||
| <CloseIcon className={classes.closeIcon} onClick={handleDelete} /> | ||
| </Container> | ||
| </Reorder.Item> | ||
| ); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One useEffect above already doing the same. Can you remove it?