diff options
author | Hayleigh Thompson <me@hayleigh.dev> | 2023-11-04 13:23:15 +0000 |
---|---|---|
committer | Hayleigh Thompson <me@hayleigh.dev> | 2023-11-04 13:23:15 +0000 |
commit | 2fa8731d3e31763ba4dbaf074157a0ed6862bc1e (patch) | |
tree | de3b4c0acdbd6b324630cb34065e362ddff88b1e | |
parent | e0155c7be10901ceb4d11cb5333f92bc272b5499 (diff) | |
download | lustre-2fa8731d3e31763ba4dbaf074157a0ed6862bc1e.tar.gz lustre-2fa8731d3e31763ba4dbaf074157a0ed6862bc1e.zip |
:sparkles: Add the 'effect.event' constructor and use it for 'event.emit'.
-rw-r--r-- | src/lustre.ffi.mjs | 7 | ||||
-rw-r--r-- | src/lustre/effect.gleam | 15 | ||||
-rw-r--r-- | src/lustre/event.gleam | 5 |
3 files changed, 15 insertions, 12 deletions
diff --git a/src/lustre.ffi.mjs b/src/lustre.ffi.mjs index 95770e4..918f7e2 100644 --- a/src/lustre.ffi.mjs +++ b/src/lustre.ffi.mjs @@ -125,13 +125,6 @@ export const setup = (init, update, render) => new App(init, update, render); export const start = (app, selector, flags) => app.start(selector, flags); export const destroy = (app) => app.destroy(); -export const emit = (name, data) => - // Normal `Effect`s constructed in Gleam from `effect.from` don't get told - // about the second argument, but it's there 👀. - from((_, emit) => { - emit(name, data); - }); - // HTML EVENTS ----------------------------------------------------------------- export const prevent_default = (e) => e.preventDefault?.(); diff --git a/src/lustre/effect.gleam b/src/lustre/effect.gleam index ea20c3a..19378da 100644 --- a/src/lustre/effect.gleam +++ b/src/lustre/effect.gleam @@ -3,6 +3,7 @@ // IMPORTS --------------------------------------------------------------------- +import gleam/dynamic.{type Dynamic} import gleam/list import gleam/function @@ -10,7 +11,7 @@ import gleam/function /// pub opaque type Effect(msg) { - Effect(all: List(fn(fn(msg) -> Nil, fn(msg) -> Nil) -> Nil)) + Effect(all: List(fn(fn(msg) -> Nil, fn(String, Dynamic) -> Nil) -> Nil)) } // CONSTRUCTORS ---------------------------------------------------------------- @@ -23,6 +24,17 @@ pub fn from(effect: fn(fn(msg) -> Nil) -> Nil) -> Effect(msg) { Effect([fn(dispatch, _) { effect(dispatch) }]) } +/// Emit a custom event from a component as an effect. Parents can listen to these +/// events in their `view` function like any other HTML event. +/// +/// You *probably* don't need to use this type of effect if you're not making use +/// of Lustre's components, but in rare cases it may be useful to emit custom +/// events from the DOM node that your Lustre application is mounted to. +/// +pub fn event(name: String, data: data) -> Effect(msg) { + Effect([fn(_, emit) { emit(name, dynamic.from(data)) }]) +} + /// Typically our app's `update` function needs to return a tuple of /// `#(model, Effect(msg))`. When we don't need to perform any side effects we /// can just return `none()`! @@ -48,7 +60,6 @@ pub fn map(effect: Effect(a), f: fn(a) -> b) -> Effect(b) { fn(dispatch, emit) { let dispatch = function.compose(f, dispatch) - let emit = function.compose(f, emit) effect(dispatch, emit) } diff --git a/src/lustre/event.gleam b/src/lustre/event.gleam index a19ec3a..3c101d1 100644 --- a/src/lustre/event.gleam +++ b/src/lustre/event.gleam @@ -16,9 +16,8 @@ type Decoded(a) = // EFFECTS --------------------------------------------------------------------- /// -@external(javascript, "../lustre.ffi.mjs", "emit") -pub fn emit(_event: String, _data: any) -> Effect(msg) { - effect.none() +pub fn emit(event: String, data: any) -> Effect(msg) { + effect.event(event, data) } // CUSTOM EVENTS --------------------------------------------------------------- |