Skip to content

Commit e611372

Browse files
authored
Merge pull request #44 from upnotes-io/controlled-focus
Controlled focus
2 parents 4f05f65 + cf8bc81 commit e611372

File tree

3 files changed

+32
-11
lines changed

3 files changed

+32
-11
lines changed

src/components/Todo/Todo.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from "react";
1+
import React, { useCallback, useState } from "react";
22
import { Reorder } from "framer-motion";
33
import { Container } from "@material-ui/core";
44

@@ -15,11 +15,13 @@ export interface TodoAppProps {
1515
function TodoApp(props: TodoAppProps) {
1616
const { defaultItems = [], onChange } = props;
1717
const [items, setItems] = useState<TodoItem[]>(defaultItems);
18+
const [focus, setFocus] = useState(-1);
1819

1920
const setItemsCallback = (updatedItems: TodoItem[]) => {
2021
setItems(updatedItems);
2122
onChange(updatedItems);
2223
};
24+
2325
const addItem = (item: TodoItem | TodoItem[]) => {
2426
const itemsCopy = [...items];
2527
if (Array.isArray(item)) {
@@ -32,6 +34,11 @@ function TodoApp(props: TodoAppProps) {
3234
setItemsCallback([...itemsCopy]);
3335
}
3436
};
37+
38+
const changeFocus = useCallback((focusIndex: number) => {
39+
setFocus(focusIndex);
40+
},[])
41+
3542
const completedItems = items.filter((item: TodoItem) => item.isComplete);
3643
const todoItems = items.filter((item: TodoItem) => !item.isComplete);
3744

@@ -51,7 +58,7 @@ function TodoApp(props: TodoAppProps) {
5158

5259
return (
5360
<Container>
54-
<Form addItem={addItem} />
61+
<Form addItem={addItem} changeFocus={changeFocus} />
5562
<Reorder.Group
5663
axis="y"
5764
values={items.map((item) => item.uuid)}
@@ -65,6 +72,8 @@ function TodoApp(props: TodoAppProps) {
6572
addItem={addItem}
6673
itemIndex={index}
6774
setItemsCallback={setItemsCallback}
75+
changeFocus={changeFocus}
76+
focus={focus}
6877
/>
6978
);
7079
})}

src/components/Todo/common/Todo/Form/index.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { TodoItem } from '../../types';
1212

1313
export interface AddProps {
1414
addItem: (item: TodoItem | TodoItem[]) => void;
15+
changeFocus: (focusIndex: number) => void;
1516
}
1617

1718
const useStyles = makeStyles({
@@ -26,7 +27,7 @@ const useStyles = makeStyles({
2627

2728
export const Form = (props: AddProps) => {
2829
const classes = useStyles();
29-
const { addItem } = props;
30+
const { addItem, changeFocus } = props;
3031
const [itemName, setItemName] = useState('');
3132
const inputRef = useRef<HTMLInputElement>(null);
3233

@@ -54,14 +55,16 @@ export const Form = (props: AddProps) => {
5455
return { name, uuid: uuid(), isComplete: false };
5556
});
5657
addItem(items);
58+
changeFocus(items.length-1);
5759
}}
5860
onChange={(e) => {
5961
addItem({
6062
name: e.target.value,
6163
uuid: uuid(),
6264
isComplete: false,
6365
});
64-
setItemName('');
66+
changeFocus(0)
67+
setItemName("");
6568
}}
6669
placeholder='Add item.'
6770
value={itemName}

src/components/Todo/common/Todo/Item/index.tsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,17 @@ interface Props {
5252
itemIndex: number;
5353
addItem: (item: TodoItem | TodoItem[]) => void;
5454
setItemsCallback: (updatedItems: TodoItem[]) => void;
55+
changeFocus: (focusIndex: number) => void;
56+
focus: number;
5557
}
5658

5759
export const Item: FC<Props> = ({
5860
items,
5961
itemIndex,
6062
setItemsCallback,
6163
addItem,
62-
// handleArrowUpDown,
64+
changeFocus,
65+
focus
6366
}) => {
6467
const inputRef = useRef<HTMLInputElement>(null);
6568
const y = useMotionValue(0);
@@ -70,11 +73,13 @@ export const Item: FC<Props> = ({
7073
const [draggable, setDraggable] = useState(false);
7174

7275
useEffect(() => {
73-
items[itemIndex].name.length < 2 &&
76+
if(focus === itemIndex){
7477
inputRef.current &&
7578
inputRef.current.focus();
79+
changeFocus(-1);
80+
}
7681
setItemText(items[itemIndex].name);
77-
}, []);
82+
}, [changeFocus, focus, itemIndex, items]);
7883

7984
if (!items[itemIndex].isComplete) {
8085
return (
@@ -122,6 +127,7 @@ export const Item: FC<Props> = ({
122127
return { name, uuid: uuid(), isComplete: false };
123128
});
124129
addItem(items);
130+
changeFocus(-1);
125131
}}
126132
onChange={(e) => {
127133
items[itemIndex].name = e.target.value;
@@ -130,10 +136,13 @@ export const Item: FC<Props> = ({
130136
onBlur={() => {
131137
setItemsCallback([...items]);
132138
}}
133-
onKeyPress={(e) =>
134-
e.key === 'Enter' &&
135-
itemIndex < 1 &&
136-
addItem({ name: '', uuid: uuid(), isComplete: false })
139+
onKeyPress={
140+
(e) => {
141+
e.key === "Enter" &&
142+
itemIndex < 1 &&
143+
addItem({ name: "", uuid: uuid(), isComplete: false })
144+
changeFocus(-1)
145+
}
137146
}
138147
onKeyDown={(e) => {
139148
const inputs = document.querySelectorAll("input[type='text']");

0 commit comments

Comments
 (0)