type TodoItem = {
id: string;
txt: string;
}
type State = Record<string, TodoItem>;
enum ActionType {
ADD = 'add',
REMOVE = 'remove'
}
type ActionAdd = {
type: ActionType.ADD,
payload: Omit<TodoItem, 'id'>;
}
type ActionRemove = {
type: ActionType.REMOVE
payload: string;
}
type Actions = ActionAdd | ActionRemove
const reducer = (state: State, action: Actions) => {
switch(action) {
case ActionType.ADD:
return {
...state,
[generateId()]: action.payload
};
case ActionType.REMOVE:{
const next = {...state};
delete next[action.payload];
return next;
}
}
};
const TodoContext = React.createContext();
export const TodoListProvider = (
options: React.PropsWithChildren<{ initial: State }>
) => {
const [selected, setSelected] = useState<string|undefined>();
const state$ = useObservable(reducer, initial);
const add = useCallback((item: Emit<TodoItem, 'id'>) => {
state$.next({ type: ActionType.ADD, payload: item });
}, [state$]);
const remove = useCallback((id: string) => {
state$.next({ type: ActionType.REMOVE, payload: item });
}, [state$])
return (
<TodoContext.Provider value={ {state$, add, remove, selected, setSelected} }>
{ options.children }
</TodoContext.Provider>
);
}
const TodoDetail = () => {
const { state$, selected } = useContext(TodoContext);
const item = useObservableSelectorState(state$, selected)
return item ? (
<div>
<span>ID: {item.id}</span>
<span>TXT: {item.txt}</span>
</div>
) : null;
}
const AddTodo = () => {
const { add } = useContext(TodoContext);
const txtRef = useRef(null);
const onSubmit = useCallback(() => {
add({ txt: txtRef.current.value })
}, [add, txtRef]);
return (
<div>
<input ref={ txtRef } />
<button onClick={ onSubmit } />
</div>
);
};
const TodoList = () => {
const { state$, setSelected } = useContext(TodoContext);
const items = useObservableState(state$).next;
return (
<ul>
{ Object.entries(items).map(
([key,value]) => <li key={key} onClick={ () => setSelected(key) }>{value.txt}</li>
)}
</ul>
)
}
const App = () => {
return (
<TodoListProvider initial={ {} }>
<TodoDetail />
<TodoList />
<AddTodo />
</TodoListProvider>
)
}
@equinor/fusion-observable
8.4.3 • Public • PublishedVersions
Current Tags
Version | Downloads (Last 7 Days) | Tag |
---|---|---|
9.0.0-next-663bed8344cc2ca0111705b05045173328b3104d | 0 | next |
8.4.3 | 403 | latest |
Version History
Version | Downloads (Last 7 Days) | Published |
---|---|---|
8.4.3 | 403 | |
8.4.2 | 615 | |
9.0.0-next-663bed8344cc2ca0111705b05045173328b3104d | 0 | |
8.4.1 | 480 | |
8.4.0 | 32 | |
8.3.3 | 155 | |
8.3.2 | 19 | |
8.3.1 | 118 | |
8.3.0 | 8 | |
8.2.0 | 31 | |
8.1.5 | 178 | |
8.1.4 | 2 | |
8.1.3 | 1 | |
8.1.2 | 0 | |
0.0.0-next-20230915185612 | 0 | |
8.1.1 | 0 | |
8.1.0 | 0 | |
8.0.3 | 0 | |
8.0.2 | 0 | |
8.0.1 | 0 | |
8.0.0 | 0 | |
7.0.3 | 31 | |
7.0.2 | 0 | |
7.0.1 | 0 | |
7.0.0 | 0 | |
6.0.0 | 0 | |
4.0.1 | 0 | |
4.0.0 | 0 | |
3.0.4 | 0 | |
3.0.3 | 0 | |
3.0.2 | 0 | |
3.0.1 | 0 | |
3.0.0 | 0 | |
2.5.0 | 0 | |
2.4.2 | 0 | |
2.4.1 | 0 | |
2.4.0 | 0 | |
2.3.0 | 0 | |
2.2.0 | 0 | |
2.1.2 | 0 | |
2.1.0 | 0 | |
2.0.1 | 0 | |
1.5.1 | 0 | |
1.5.0 | 0 | |
1.4.1 | 0 | |
1.4.0 | 0 | |
1.3.1 | 0 | |
1.3.0 | 0 | |
1.2.1 | 0 | |
1.2.0 | 0 | |
1.1.0 | 0 | |
1.0.0 | 0 | |
0.4.0 | 0 | |
0.3.3 | 0 | |
0.3.2 | 0 | |
0.3.1 | 1 | |
0.3.0 | 0 | |
0.2.0 | 0 | |
0.1.12 | 0 | |
0.1.11 | 0 | |
0.1.10 | 0 | |
0.1.9 | 0 | |
0.1.8 | 0 | |
0.1.7 | 0 | |
0.1.6 | 0 | |
0.1.5 | 0 | |
0.1.4 | 0 | |
0.1.3 | 0 | |
0.1.2 | 0 | |
0.1.1 | 0 | |
0.1.0 | 0 | |
0.0.2 | 0 | |
0.0.1 | 0 |
Package Sidebar
Install
npm i @equinor/fusion-observable
Repository
Weekly Downloads
1,711
Version
8.4.3
License
ISC
Unpacked Size
177 kB
Total Files
97