Current section
Files
Jump to
Current section
Files
src/pream/hooks.gleam
import pream/dom.{type Native}
import pream/signal
// ── Signal hooks (moved from pream.gleam) ──────────────
/// Creates a reactive signal scoped to a component.
/// Returns the same `Signal` type as `signal.new`,
/// composable with `signal.value`, `signal.set`,
/// `signal.map`, etc.
@external(javascript, "@preact/signals", "useSignal")
pub fn use_signal(initial: a) -> signal.Signal(a)
/// Runs a reactive effect scoped to a component.
/// The effect runs after every render where any signal
/// read inside the effect has changed.
@external(javascript, "@preact/signals", "useSignalEffect")
pub fn use_signal_effect(run: fn() -> Nil) -> Nil
/// Returns a read-only computed signal scoped to
/// a component — same semantics as `signal.computed`
@external(javascript, "@preact/signals", "useComputed")
pub fn use_computed(compute: fn() -> a) -> signal.Signal(a)
// ── Effect hooks (basic — no cleanup) ──────────────────
/// Runs a side effect after render. The effect re-runs when
/// any value in `deps` changes. Pass `[]` to run once on mount.
/// Pass a list of dependencies like `[dom.to_native(signal.value(sig))]`
/// to re-run when those values change.
///
/// # Examples
///
/// ```gleam
/// // Run once on mount
/// use_effect(fn() { console.log("mounted") }, [])
///
/// // Re-run when a signal changes
/// use_effect(
/// fn() { console.log("count changed") },
/// [dom.to_native(signal.value(count))],
/// )
/// ```
@external(javascript, "./hooks_ffi.mjs", "use_effect")
pub fn use_effect(run: fn() -> Nil, deps: List(Native)) -> Nil
/// Like `use_effect` but runs synchronously after DOM mutations,
/// before the browser paints. Use for measuring layout or other
/// synchronous DOM reads.
@external(javascript, "./hooks_ffi.mjs", "use_layout_effect")
pub fn use_layout_effect(run: fn() -> Nil, deps: List(Native)) -> Nil
// ── Effect hooks (cleanup variant) ─────────────────────
/// Like `use_effect` but the callback returns a cleanup function
/// that runs before the next effect invocation and on unmount.
///
/// # Examples
///
/// ```gleam
/// use_effect_cleanup(fn() {
/// let interval_id = set_interval(fn() { ... }, 1000)
/// fn() { clearInterval(interval_id) }
/// }, [])
/// ```
@external(javascript, "./hooks_ffi.mjs", "use_effect_cleanup")
pub fn use_effect_cleanup(run: fn() -> fn() -> Nil, deps: List(Native)) -> Nil
/// Like `use_layout_effect` but with cleanup support.
@external(javascript, "./hooks_ffi.mjs", "use_layout_effect_cleanup")
pub fn use_layout_effect_cleanup(
run: fn() -> fn() -> Nil,
deps: List(Native),
) -> Nil
// ── Memoization hooks ──────────────────────────────────
/// Memoizes a computed value. Only recomputes when a dep in
/// `deps` changes. Useful for expensive calculations.
@external(javascript, "./hooks_ffi.mjs", "use_memo")
pub fn use_memo(compute: fn() -> a, deps: List(Native)) -> a
/// Memoizes a callback function. Only returns a new function
/// reference when a dep in `deps` changes. Useful for passing
/// stable callbacks to child components.
@external(javascript, "./hooks_ffi.mjs", "use_callback")
pub fn use_callback(callback: fn() -> a, deps: List(Native)) -> fn() -> a
// ── Ref hooks ──────────────────────────────────────────
/// A mutable reference object whose `.current` field persists
/// across renders. At the JavaScript level, `Ref(current: x)`
/// compiles to `{ current: x }`.
///
/// # Examples
///
/// ```gleam
/// let input_ref = use_ref("")
/// // In FFI or event handler: input_ref.current = "new value"
/// ```
pub type Ref(a) {
Ref(current: a)
}
/// Creates a `Ref` that persists for the lifetime of the component.
@external(javascript, "./hooks_ffi.mjs", "use_ref")
pub fn use_ref(initial: a) -> Ref(a)
@external(javascript, "./hooks_ffi.mjs", "set_ref")
pub fn set_ref(ref: Ref(a), to: a) -> Ref(a)
/// Customizes the instance value exposed through a ref.
/// Typically used with `forwardRef` in component libraries.
@external(javascript, "./hooks_ffi.mjs", "use_imperative_handle")
pub fn use_imperative_handle(
ref: Ref(a),
create_handle: fn() -> a,
deps: List(Native),
) -> Nil
// ── Misc hooks ─────────────────────────────────────────
/// Returns a unique ID string for use in accessibility
/// attributes (`id`, `for`, `aria-labelledby`, etc.).
@external(javascript, "./hooks_ffi.mjs", "use_id")
pub fn use_id() -> String
/// Displays a custom label for a hook in the Preact devtools panel.
@external(javascript, "./hooks_ffi.mjs", "use_debug_value")
pub fn use_debug_value(value: a) -> Nil
// ── QoL hooks ──────────────────────────────────────────
/// Runs `run` once on component mount. Equivalent to
/// `use_effect(run, [])`.
pub fn use_mount(run: fn() -> Nil) -> Nil {
use_effect(run, [])
}
/// Runs `run` once on component unmount. Equivalent to
/// `use_effect_cleanup(fn() { fn() { run() } }, [])`.
pub fn use_unmount(run: fn() -> Nil) -> Nil {
use_effect_cleanup(fn() { fn() { run() } }, [])
}