Skip to content

Instantly share code, notes, and snippets.

@cambiata
Last active May 30, 2024 18:29
Show Gist options
  • Save cambiata/8b5c834a7c071ca7c11c8b936f45c9c7 to your computer and use it in GitHub Desktop.
Save cambiata/8b5c834a7c071ca7c11c8b936f45c9c7 to your computer and use it in GitHub Desktop.
Displays a way to deal with discriminated union types in Solid-js, jsx view as well as store
import styles from './App.module.css';
import { For, Match, Switch, type Component } from 'solid-js';
import { createStore, SetStoreFunction } from 'solid-js/store';
type Todo = { id: number, text: string, done: boolean };
type TodosStateItems = { s: "Todos", todos: Todo[] };
type TodosState =
| { s: 'Empty' }
| { s: 'Loading' }
| TodosStateItems;
const [state, setState] = createStore<TodosState>({ s: 'Empty' });
const setStateItems = setState as SetStoreFunction<TodosStateItems>; // <- setState retyped to use fields from TodosStateItems
const toggleTodo = (id: number) => {
if (state.s !== 'Todos') return;
setStateItems('todos', item => item.id === id, 'done', done => !done); // <- using the retyped setState here!
};
const loadTodos = () => {
setState({ s: 'Loading' });
setTimeout(() => {
setState({ s: 'Todos', todos: [{ id: 1, text: 'Item 1', done: false }, { id: 2, text: 'Item 2', done: true }] });
}, 1000);
}
const App: Component = () => {
return <div class={styles.App}>
<header class={styles.header}>
<pre>{JSON.stringify(state)}</pre>
<button onClick={loadTodos}>Load Items</button>
<Switch>
<Match when={state.s === 'Empty'}>
<h3>Empty - no items</h3>
</Match>
<Match when={state.s === 'Loading'}>
<h3>Loading items...</h3>
</Match>
<Match when={state.s === 'Todos' && state}>
{state => <>
<h3>{state().todos.length} Items </h3>
<ul>
<For each={state().todos}>
{todo => <li style={{ cursor: 'pointer' }} onClick={() => toggleTodo(todo.id)}>{todo.text} {JSON.stringify(todo.done)}</li>}
</For>
</ul>
</>}
</Match>
</Switch>
</header>
</div>
};
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment