Skip to content

Instantly share code, notes, and snippets.

@tuoxiansp
Created July 30, 2020 21:05
Show Gist options
  • Save tuoxiansp/fc30b163d9b322fb91e88cc1f16b779e to your computer and use it in GitHub Desktop.
Save tuoxiansp/fc30b163d9b322fb91e88cc1f16b779e to your computer and use it in GitHub Desktop.
import create from 'zustand'
import {useState} from 'react'
const [useStore] = create(set => {
return {
idx: 0,
todos: [],
filterType: 'all',
filter: (filterType) => {
set(state => {
return {
filterType
}
})
},
add: (todo) => set(state => {
const id = state.idx
return {
idx: id + 1,
todos: [...state.todos, {...todo, id}]
}
}),
toggle: (id) => set(state => {
const i = state.totos.findIndex(t => t.id === id)
if (i !== -1) {
const todo = state.todos[i]
const nextTodos = [...state.todos]
nextTodos.splice(i, 1, {...todo, active: !todo.active})
return {
todos: [...nextTodos]
}
}
}),
remove: id => set(state => {
const i = state.todos.findIndex(t => t.id === id)
if (i !== -1) {
const nextTodos = [...state.todos]
nextTodos.splice(i, 1)
return {
todos: [...nextTodos]
}
}
}),
allComplete: () => set(state => {
const nextTodos = state.todos.map(t => {
return {
...t,
active: false
}
})
return {todos: nextTodos}
}),
allInComplete: () => set(state => {
const nextTodos = state.todos.filter(t => t.active)
return {
todos: nextTodos
}
}),
clearCompleted: () => {
set(state => {
const nextTodos = state.todos.filter(t => t.active)
return {
todos: nextTodos
}
})
}
}
})
const useFilteredTodos = () => {
const {todos, filterType} = useStore(state => state)
if (filterType === 'all') {
return todos
}
if (filterType === 'active') {
return todos.filter(t => t.active)
}
return todos.filter(t => !t.active)
}
const useIsAllCompleted = () => {
const todos = useStore(state => state.todos)
for (let t of todos) {
if (t.active) {
return false
}
}
return true
}
const useLeftCount = () => {
const todos = useStore(state => state.todos)
return todos.filter(t => t.active).length
}
export default {
Filter: () => {
const filterType = useStore(state => state.filterType)
const filter = useStore(state => state.filter)
return [
{
onAll: () => filter('all'),
onActive: () => filter('active'),
onCompleted: () => filter('completed')
},
filterType
]
},
TodoItem: ({label, onToggle, isActive, onRemove}) => {
const [hideClose, setHideClose] = useState(true)
return [
{
label,
onToggle,
closeOpacity: hideClose ? 0: 100,
onRemove,
onMouseEnter: () => {
setHideClose(false)
},
onMouseLeave: () => {
setHideClose(true)
}
},
isActive ? 'active' : 'inactive'
]
},
List: () => {
const todos = useFilteredTodos()
const {toggle, remove} = useStore(state => state)
return [
{
todos: todos.map(t => {
return {
label: t.label,
onToggle: () => toggle(t.id),
isActive: t.active,
onRemove: () => remove(t.id)
}
})
},
'state0'
]
},
Input2: () => {
const [value, setValue] = useState('')
const {add, allComplete, allInComplete} = useStore(state => state)
const allCompleted = useIsAllCompleted()
return [
{
value,
onChange: (e) => {
setValue(e.target.value)
},
onSubmit: (e) => {
if (e.key === 'Enter') {
if (value) {
add({label: value,
active: true})
}
setValue("")
}
},
onAllComplete: () => {
allCompleted ? allInComplete() : allComplete()
}
},
allCompleted ? 'fll' : 'all'
]
},
ToolBar: () => {
const leftCount = useLeftCount()
const clearCompleted = useStore(state => state.clearCompleted)
return [
{
count: leftCount + '',
onClearCompleted: () => clearCompleted()
},
'state0'
]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment