Sketch Lustre
In case you’re here and don’t know Sketch, take a look at
sketch
package!
This readme is a carbon-copy of the Sketch Lustre section in
sketch
readme.
Setup
Sketch focuses on the concept of generating CSS in a performant way. To do it, Sketch needs to use a cache. The cache allows to avoid repeating unneeded computations, and ensure consistency across repaints. Because the browser likes static CSS, using a cache make sure the browser will not undergo unneeded computations to recompute styles at every repaint.
If you’re using Lustre (which is strongly recommended), sketch_lustre
got you.
sketch_lustre
exposes one entrypoint, sketch/lustre
, containing everything
needed to get started.
// main.gleam
import lustre
import sketch
import sketch/lustre as sketch_lustre
pub fn main() {
// Initialise the cache. Two strategies can be used in browser, only one
// on server-side.
let assert Ok(cache) = sketch.cache(strategy: sketch.Ephemeral)
// Select the output of the generated stylesheet.
sketch_lustre.node()
// Add the sketch CSS generation "view middleware".
|> sketch_lustre.compose(view, cache)
// Give the new view function to lustre runtime!
|> lustre.simple(init, update, _)
// And voilà!
|> lustre.start("#app", Nil)
}
Usage
sketch_lustre
exposes two modules to help you build your site, similarly to
Lustre: sketch/lustre/element
and sketch/lustre/element/html
. The first one
let you use raw element generation and exposes the Sketch Lustre Element(msg)
type, that can be used (almost) interchangeably with Lustre, and element
helpers, i.e. element
, fragment
, or even keyed
.
Because a sketch_lustre
view function expects an
sketch/lustre/element.Element(msg)
to paint, you should now write all your
view functions to return Sketch elements. All Sketch elements can be
instanciated with element
, or with the corresponding
sketch/lustre/element/html.element
. An element accepts the same thing as a
Lustre element, but includes a sketch.Class
value as first argument. That
class will be applied to the final generated element.
NB: all elements can be generated using the correct function, or using its “underscored” version. In the second case, Sketch Lustre behaves exactly like Lustre, and will not add another class. This is helpful when you want to use a simple node, without any class linked on it.
import sketch
import sketch/lustre/element
import sketch/lustre/element/html
import sketch/size.{px}
fn main_style() {
sketch.class([
sketch.background("red"),
sketch.font_size(px(16)),
])
}
fn view(model: Int) {
html.div(main_style(), [], [
html.div_([], [h.text(int.to_string(model)]),
])
}
And you’re done! Enjoy your Lustre app, Sketch-enhanced!
Final notes
On Sketch Lustre Element
A Sketch Element(msg)
is extremely similar to a Lustre Element(msg)
,
excepted it carries styles information on top. Going from a
sketch/lustre/element.Element(msg)
to a lustre/element.Element(msg)
is
straightforward, by using sketch/lustre/element.unstyled
. The opposite (going
from a Lustre element to a Sketch Lustre element) is also possible by using
sketch/lustre/element.styled
!
Usage with Shadow DOM
In browser, Sketch can work with a Shadow DOM, in order to hide the compiled
styles from the rest of the application. To do it, you can use
plinth
. This allows to create a
ShadowRoot
, to use
sketch/options.shadow_root()
.
In the same way you can initialize the cache to render in document or in a
style
node, you can now use a Shadow Root to paint styles in your application!