Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 94 additions & 37 deletions src/components/Todo/common/Todo/Item/index.tsx
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 {
Expand Down Expand Up @@ -81,6 +87,91 @@ export const Item: FC<Props> = ({
setItemText(items[itemIndex].name);
}, [changeFocus, focus, itemIndex, items]);

useEffect(() => {
Copy link
Contributor

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?

setItemText(items[itemIndex].name);
}, [items[itemIndex].name]);

const handleDelete = () => {
items.splice(itemIndex, 1);
Copy link
Contributor

Choose a reason for hiding this comment

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

const itemsCopy = [...items];
itemsCopy.splice(itemIndex, 1);
setItemsCallback([...itemsCopy]);

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);
Copy link
Contributor

Choose a reason for hiding this comment

The 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);
Copy link
Contributor

Choose a reason for hiding this comment

The 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
Expand Down Expand Up @@ -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>
);
Expand Down