Current section
Files
Jump to
Current section
Files
src/docs/components/counter.gleam
import gleam/io
import gleam/int
import gleam/string
import gleam/option.{None, Option}
import sprocket/socket.{Socket}
import sprocket/hooks.{WithDeps, dep}
import sprocket/component.{render}
import sprocket/hooks/reducer.{State, reducer}
import sprocket/hooks/effect.{effect}
import sprocket/hooks/callback.{callback}
import sprocket/internal/identifiable_callback.{CallbackFn}
import sprocket/html.{button, div, span, text}
import sprocket/html/attributes.{class, on_click}
type Model =
Int
type Msg {
UpdateCounter(Int)
}
fn update(_model: Model, msg: Msg) -> Model {
case msg {
UpdateCounter(count) -> {
count
}
}
}
pub type CounterProps {
CounterProps(initial: Option(Int))
}
pub fn counter(socket: Socket, props: CounterProps) {
let CounterProps(initial) = props
// Define a reducer to handle events and update the state
use socket, State(count, dispatch) <- reducer(
socket,
option.unwrap(initial, 0),
update,
)
// Example effect that runs every time count changes
use socket <- effect(
socket,
fn() {
io.println(string.append("Count: ", int.to_string(count)))
None
},
WithDeps([dep(count)]),
)
// Define event handlers
use socket, on_increment <- callback(
socket,
CallbackFn(fn() { dispatch(UpdateCounter(count + 1)) }),
WithDeps([dep(count)]),
)
use socket, on_decrement <- callback(
socket,
CallbackFn(fn() { dispatch(UpdateCounter(count - 1)) }),
WithDeps([dep(count)]),
)
render(
socket,
[
div(
[class("flex flex-row m-4")],
[
button(
[
class(
"p-1 px-2 border dark:border-gray-500 rounded-l bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 active:bg-gray-300 dark:active:bg-gray-600",
),
on_click(on_decrement),
],
[text("-")],
),
span(
[
class(
"p-1 px-2 w-10 border-t border-b dark:border-gray-500 align-center text-center",
),
],
[text(int.to_string(count))],
),
button(
[
class(
"p-1 px-2 border dark:border-gray-500 rounded-r bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 active:bg-gray-300 dark:active:bg-gray-600",
),
on_click(on_increment),
],
[text("+")],
),
],
),
],
)
}