2019-01-23 03:04:37 +08:00
|
|
|
|
// @flow
|
|
|
|
|
|
|
2019-02-28 05:05:43 +08:00
|
|
|
|
import React, { Fragment, useCallback, useState } from 'react';
|
2019-01-23 03:04:37 +08:00
|
|
|
|
import ListItem from './ListItem';
|
|
|
|
|
|
import styles from './List.css';
|
|
|
|
|
|
|
|
|
|
|
|
export type Item = {|
|
|
|
|
|
|
id: number,
|
|
|
|
|
|
isComplete: boolean,
|
|
|
|
|
|
text: string,
|
|
|
|
|
|
|};
|
|
|
|
|
|
|
|
|
|
|
|
type Props = {||};
|
|
|
|
|
|
|
2019-01-24 00:45:19 +08:00
|
|
|
|
export default function List(props: Props) {
|
2019-01-23 03:04:37 +08:00
|
|
|
|
const [newItemText, setNewItemText] = useState<string>('');
|
|
|
|
|
|
const [items, setItems] = useState<Array<Item>>([
|
2019-01-24 00:45:19 +08:00
|
|
|
|
{ id: 1, isComplete: true, text: 'First' },
|
|
|
|
|
|
{ id: 2, isComplete: true, text: 'Second' },
|
|
|
|
|
|
{ id: 3, isComplete: false, text: 'Third' },
|
2019-01-23 03:04:37 +08:00
|
|
|
|
]);
|
|
|
|
|
|
const [uid, setUID] = useState<number>(4);
|
|
|
|
|
|
|
|
|
|
|
|
const handleClick = useCallback(() => {
|
|
|
|
|
|
if (newItemText !== '') {
|
2019-03-25 00:21:37 +08:00
|
|
|
|
setItems([
|
|
|
|
|
|
...items,
|
|
|
|
|
|
{
|
|
|
|
|
|
id: uid,
|
|
|
|
|
|
isComplete: false,
|
|
|
|
|
|
text: newItemText,
|
|
|
|
|
|
},
|
|
|
|
|
|
]);
|
|
|
|
|
|
setUID(uid + 1);
|
|
|
|
|
|
setNewItemText('');
|
2019-01-23 03:04:37 +08:00
|
|
|
|
}
|
2019-02-20 05:15:57 +08:00
|
|
|
|
}, [newItemText, items, uid]);
|
2019-01-23 03:04:37 +08:00
|
|
|
|
|
2019-01-24 00:45:19 +08:00
|
|
|
|
const handleKeyPress = useCallback(
|
|
|
|
|
|
event => {
|
|
|
|
|
|
if (event.key === 'Enter') {
|
|
|
|
|
|
handleClick();
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
[handleClick]
|
|
|
|
|
|
);
|
2019-01-23 03:04:37 +08:00
|
|
|
|
|
2019-01-24 00:45:19 +08:00
|
|
|
|
const handleChange = useCallback(
|
|
|
|
|
|
event => {
|
|
|
|
|
|
setNewItemText(event.currentTarget.value);
|
|
|
|
|
|
},
|
|
|
|
|
|
[setNewItemText]
|
|
|
|
|
|
);
|
2019-01-23 03:04:37 +08:00
|
|
|
|
|
2019-01-24 00:45:19 +08:00
|
|
|
|
const removeItem = useCallback(
|
2019-03-25 00:21:37 +08:00
|
|
|
|
itemToRemove => setItems(items.filter(item => item !== itemToRemove)),
|
2019-01-24 00:45:19 +08:00
|
|
|
|
[items]
|
|
|
|
|
|
);
|
2019-01-23 03:04:37 +08:00
|
|
|
|
|
2019-01-24 00:45:19 +08:00
|
|
|
|
const toggleItem = useCallback(
|
|
|
|
|
|
itemToToggle => {
|
2019-03-25 00:21:37 +08:00
|
|
|
|
const index = items.indexOf(itemToToggle);
|
2019-01-23 03:04:37 +08:00
|
|
|
|
|
2019-03-25 00:21:37 +08:00
|
|
|
|
setItems(
|
|
|
|
|
|
items
|
|
|
|
|
|
.slice(0, index)
|
|
|
|
|
|
.concat({
|
|
|
|
|
|
...itemToToggle,
|
|
|
|
|
|
isComplete: !itemToToggle.isComplete,
|
|
|
|
|
|
})
|
|
|
|
|
|
.concat(items.slice(index + 1))
|
|
|
|
|
|
);
|
2019-01-24 00:45:19 +08:00
|
|
|
|
},
|
|
|
|
|
|
[items]
|
|
|
|
|
|
);
|
2019-01-23 03:04:37 +08:00
|
|
|
|
|
|
|
|
|
|
return (
|
2019-02-28 05:05:43 +08:00
|
|
|
|
<Fragment>
|
|
|
|
|
|
<h1>List</h1>
|
2019-01-23 03:04:37 +08:00
|
|
|
|
<input
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
placeholder="New list item..."
|
|
|
|
|
|
className={styles.Input}
|
|
|
|
|
|
value={newItemText}
|
|
|
|
|
|
onChange={handleChange}
|
|
|
|
|
|
onKeyPress={handleKeyPress}
|
|
|
|
|
|
/>
|
|
|
|
|
|
<button
|
|
|
|
|
|
className={styles.IconButton}
|
|
|
|
|
|
disabled={newItemText === ''}
|
|
|
|
|
|
onClick={handleClick}
|
2019-01-24 00:45:19 +08:00
|
|
|
|
>
|
|
|
|
|
|
<span role="img" aria-label="Add item">
|
|
|
|
|
|
➕
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</button>
|
2019-01-23 03:04:37 +08:00
|
|
|
|
<ul className={styles.List}>
|
|
|
|
|
|
{items.map(item => (
|
|
|
|
|
|
<ListItem
|
|
|
|
|
|
key={item.id}
|
|
|
|
|
|
item={item}
|
|
|
|
|
|
removeItem={removeItem}
|
|
|
|
|
|
toggleItem={toggleItem}
|
|
|
|
|
|
/>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</ul>
|
2019-02-28 05:05:43 +08:00
|
|
|
|
</Fragment>
|
2019-01-23 03:04:37 +08:00
|
|
|
|
);
|
2019-01-24 00:45:19 +08:00
|
|
|
|
}
|