mirror of
https://github.com/leporello-js/leporello-js
synced 2026-01-13 13:04:30 -08:00
deploy: leporello-js/app@a6e3f1b36f
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
Example of a TODO app built using the Preact library
|
||||
*/
|
||||
|
||||
import React from 'https://esm.sh/preact/compat'
|
||||
import React from "preact/compat"
|
||||
|
||||
// Core
|
||||
|
||||
@@ -13,7 +13,7 @@ let state
|
||||
if (globalThis.leporello) {
|
||||
// Retrieve initial state from Leporello storage
|
||||
// See: https://github.com/leporello-js/leporello-js?tab=readme-ov-file#saving-state-between-page-reloads
|
||||
state = globalThis.leporello.storage.get('state')
|
||||
state = globalThis.leporello.storage.get("state")
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -21,14 +21,16 @@ if (globalThis.leporello) {
|
||||
This helper function wraps such a function so that its result updates the global state
|
||||
and can be used as an event handler.
|
||||
*/
|
||||
const handler = fn => (...args) => {
|
||||
state = fn(state, ...args)
|
||||
if (globalThis.leporello) {
|
||||
// Persist state to Leporello storage to restore it after page reloads
|
||||
globalThis.leporello.storage.set('state', state)
|
||||
const handler =
|
||||
fn =>
|
||||
(...args) => {
|
||||
state = fn(state, ...args)
|
||||
if (globalThis.leporello) {
|
||||
// Persist state to Leporello storage to restore it after page reloads
|
||||
globalThis.leporello.storage.set("state", state)
|
||||
}
|
||||
render()
|
||||
}
|
||||
render()
|
||||
}
|
||||
|
||||
// Higher-order function that injects the current state into a component
|
||||
const connect = comp => props => comp(props, state)
|
||||
@@ -39,12 +41,12 @@ const render = () => React.render(<App />, document.body)
|
||||
if (state == null) {
|
||||
state = {
|
||||
todos: [],
|
||||
text: '',
|
||||
filter: 'ALL',
|
||||
text: "",
|
||||
filter: "ALL",
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('load', render)
|
||||
window.addEventListener("load", render)
|
||||
|
||||
// Components
|
||||
|
||||
@@ -68,10 +70,10 @@ const Footer = () => (
|
||||
const FilterLink = connect(({ filter, children }, state) => {
|
||||
const disabled = state.filter == filter
|
||||
return (
|
||||
<button
|
||||
onClick={handler(changeFilter.bind(null, filter))}
|
||||
disabled={disabled}
|
||||
style={{ marginLeft: '4px' }}
|
||||
<button
|
||||
onClick={handler(changeFilter.bind(null, filter))}
|
||||
disabled={disabled}
|
||||
style={{ marginLeft: "4px" }}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
@@ -87,9 +89,9 @@ const TodoList = connect((_, state) => (
|
||||
))
|
||||
|
||||
const Todo = ({ todo }) => (
|
||||
<li
|
||||
onClick={handler(toggleTodo.bind(null, todo))}
|
||||
style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}
|
||||
<li
|
||||
onClick={handler(toggleTodo.bind(null, todo))}
|
||||
style={{ textDecoration: todo.completed ? "line-through" : "none" }}
|
||||
>
|
||||
{todo.text}
|
||||
</li>
|
||||
@@ -99,11 +101,7 @@ const AddTodo = connect((_, state) => {
|
||||
return (
|
||||
<div>
|
||||
<form onSubmit={handler(createTodo)}>
|
||||
<input
|
||||
value={state.text}
|
||||
onChange={handler(changeText)}
|
||||
autoFocus
|
||||
/>
|
||||
<input value={state.text} onChange={handler(changeText)} autoFocus />
|
||||
<button type="submit">Add Todo</button>
|
||||
</form>
|
||||
</div>
|
||||
@@ -114,14 +112,14 @@ const AddTodo = connect((_, state) => {
|
||||
|
||||
// Returns a filtered list of TODOs based on the current filter state
|
||||
function visibleTodos(state) {
|
||||
if (state.filter == 'ALL') {
|
||||
if (state.filter == "ALL") {
|
||||
return state.todos
|
||||
} else if (state.filter == 'ACTIVE') {
|
||||
} else if (state.filter == "ACTIVE") {
|
||||
return state.todos.filter(t => !t.completed)
|
||||
} else if (state.filter == 'COMPLETED') {
|
||||
} else if (state.filter == "COMPLETED") {
|
||||
return state.todos.filter(t => t.completed)
|
||||
} else {
|
||||
throw new Error('Unknown filter')
|
||||
throw new Error("Unknown filter")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,18 +144,18 @@ function createTodo(state, e) {
|
||||
}
|
||||
|
||||
return {
|
||||
...state,
|
||||
...state,
|
||||
todos: [...state.todos, { text: state.text }],
|
||||
text: '',
|
||||
text: "",
|
||||
}
|
||||
}
|
||||
|
||||
// Toggles the completion state of a TODO item
|
||||
function toggleTodo(todo, state) {
|
||||
return {
|
||||
...state,
|
||||
...state,
|
||||
todos: state.todos.map(t =>
|
||||
t == todo ? { ...todo, completed: !todo.completed } : t
|
||||
)
|
||||
t == todo ? { ...todo, completed: !todo.completed } : t,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user