Skip to content

Commit 35bca66

Browse files
authored
Merge pull request #15 from ghivert/feat/turn-js-transform-to-gleam
Feat/turn js transform to gleam
2 parents fd03372 + d15b304 commit 35bca66

23 files changed

+811
-190
lines changed

.prettierrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"semi": false,
3+
"printWidth": 80,
4+
"singleQuote": true,
5+
"proseWrap": "always"
6+
}

README.md

Lines changed: 109 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,35 @@
11
# Sketch
22

3-
Sketch is a small module providing CSS-in-Gleam in its simpler form.
4-
Sketch does not try to add complicated API on top of CSS. If you have CSS
5-
knowledge, you'll feel right at home, with all the niceties offered by
6-
Sketch, i.e. type-checking of sizes and push-to-browser stylesheets of your
7-
classes, as well as SSR support.
3+
Sketch is a module providing CSS-in-Gleam in its simpler form. Sketch does not
4+
try to add complicated API on top of CSS. If you have CSS knowledge, you'll feel
5+
right at home, with all the niceties offered by Sketch, i.e. type-checking of
6+
sizes and push-to-browser stylesheets of your classes, as well as SSR support.
87

98
Sketch has currently only one run mode: directly in your browser to leverage on
10-
all abilities of the JS runtime.
11-
It also allows you to build two types of CSS classes: dynamic ones, changing
12-
over time, and static ones, compiled once and for all, and reused during the
9+
all abilities of the JS runtime. It also allows you to build three types of CSS
10+
classes: dynamic ones, changing over time, static ones, compiled once at each
11+
render, and memoized ones, compiled once and for all, and reused during the
1312
entire lifetime of the application, just like classic CSS stylesheets.
1413

1514
Sketch is thought to interact nicely with [Lustre](https://hexdocs.pm/lustre/),
1615
but can also be used directly in your vanilla Gleam application or in your
1716
fully-featured application. This should probably only be considered to create
18-
custom framework or to integrate Sketch in your favorite framework, because Sketch
19-
has its own lifecycle to render styles. More informations can be found in the docs.
17+
custom framework or to integrate Sketch in your favorite framework, because
18+
Sketch has its own lifecycle to render styles. More informations can be found in
19+
the docs.
20+
21+
Sketch targets both the JS and the BEAM ecosystem. You can use it transparently
22+
no matter the target you're using. Sketch works in frontend, backend, SSR, SSG,
23+
with OTP actors or on Node. While sketch tries to be transparent, it does not
24+
compromise with performances, and tries to leverage on every abilities of the
25+
different platforms (and uses a custom renderer both for BEAM and JS, to ensures
26+
sparkling performances in your browser)!
27+
28+
The rest of this README will focus to get you started quickly with a lustre
29+
example, and some details on the available functions. If you want to know more
30+
on how sketch is working, how to use lustre with SSR or SSG, heads up to the
31+
documentation directly! Bonus: if you're using server components, just follow
32+
this guide, everything will be working directly!
2033

2134
## Installation
2235

@@ -30,18 +43,23 @@ gleam add sketch
3043
## Setup
3144

3245
If you're using Lustre (which is strongly recommended), you can just use the
33-
[`sketch/lustre.setup`](https://hexdocs.pm/sketch/sketch/lustre.html#setup) function
34-
and [`sketch/lustre.compose`](https://hexdocs.pm/sketch/sketch/lustre.html#compose) function.
35-
36-
Otherwise, you have to follow the lifecycle of Sketch, and use the three low-level
37-
functions [`create_cache`](https://hexdocs.pm/sketch/sketch.html#create_cache),
38-
[`prepare`](https://hexdocs.pm/sketch/sketch.html#prepare) and [`render`](https://hexdocs.pm/sketch/sketch.html#render).
39-
Create the cache with [`create_cache`](https://hexdocs.pm/sketch/sketch.html#create_cache)
40-
and before every repaint of your frontend, call [`prepare`](https://hexdocs.pm/sketch/sketch.html#prepare).
41-
After the repaint, synchronously, call [`render`](https://hexdocs.pm/sketch/sketch.html#render),
42-
and let the magic happen in your browser. Heads up in the docs for more details.
43-
44-
## Example with Lustre
46+
[`sketch/lustre.setup`](https://hexdocs.pm/sketch/sketch/lustre.html#setup)
47+
function and
48+
[`sketch/lustre.compose`](https://hexdocs.pm/sketch/sketch/lustre.html#compose)
49+
function.
50+
51+
Otherwise, you have to follow the lifecycle of Sketch, and use the three
52+
low-level functions
53+
[`create_cache`](https://hexdocs.pm/sketch/sketch.html#create_cache),
54+
[`prepare`](https://hexdocs.pm/sketch/sketch.html#prepare) and
55+
[`render`](https://hexdocs.pm/sketch/sketch.html#render). Create the cache with
56+
[`create_cache`](https://hexdocs.pm/sketch/sketch.html#create_cache) and before
57+
every repaint of your application, call
58+
[`prepare`](https://hexdocs.pm/sketch/sketch.html#prepare). After the repaint,
59+
synchronously, call [`render`](https://hexdocs.pm/sketch/sketch.html#render),
60+
and let the magic happen. Heads up in the docs for more details.
61+
62+
## Example with Lustre — Frontend
4563

4664
```gleam
4765
import gleam/int
@@ -126,11 +144,13 @@ fn view(model: Model) {
126144

127145
## Compiling static classes
128146

129-
Sketch exposes a single function [`class`](https://hexdocs.pm/sketch/sketch.html#class)
130-
allowing you to build your class. The first time your function is called, the
131-
corresponding styles will be compiled into CSS rules, and pushed in your browser
132-
or your SSR stylesheet. Every time you'll call the function in the future, no
133-
computation will be done, the class name will be returned, thanks to memoization.
147+
Sketch exposes a single function
148+
[`class`](https://hexdocs.pm/sketch/sketch.html#class) allowing you to build
149+
your class. The first time your function is called, the corresponding styles
150+
will be compiled into CSS rules, and pushed in your browser or your `<style>`
151+
stylesheet. Every time you'll call the function during the render, no
152+
computation will be done, the class name will be returned, thanks to virtual
153+
stylesheet.
134154

135155
```gleam
136156
import sketch
@@ -146,14 +166,23 @@ fn my_class() -> String {
146166

147167
## Compiling dynamic classes
148168

149-
Sketch exposes another function [`dynamic`](https://hexdocs.pm/sketch/sketch.html#dynamic)
150-
allowing you to build a dynamic class, changing over time. Each time the function
151-
is called, the properties in the declaration will be compiled into CSS, the previous
152-
class will be wiped from the browser, and the new one will pushed.
153-
154-
An ID *should be provided* at the moment, due to a limitation of the runtime, and
155-
the limitations of the compilation. Until a workaround is found, be careful to
156-
provide a unique id for your dynamic class, to avoid overlap with other classes.
169+
Sketch exposes another function
170+
[`dynamic`](https://hexdocs.pm/sketch/sketch.html#dynamic) allowing you to build
171+
a dynamic class, changing over time. The first time the function is called, the
172+
properties in the declaration will be compiled into CSS, and a class with the
173+
name of the ID will be pushed in the browser. When a class with the same ID is
174+
found once again during the render, it will be kept, and reused. `dynamic`
175+
allows you to build different dynamic classes, with different ID. When you're
176+
generating the ID, if it does not exists in the stylesheet, it will be pushed in
177+
it, and kept at least till the next render. While a `class` function generates
178+
_one_ class at every render, a `dynamic` function generates _multiple_ classes
179+
at every render.
180+
181+
An ID _should be provided_ at the moment, because the runtime is unable to
182+
distinguish between the dynamic classes, or at a high cost during computations:
183+
finding the ID of the new class to generate _is_ a hard task by itself. While a
184+
solution is awaited to be found, be careful to provide a unique id for your
185+
dynamic class.
157186

158187
```gleam
159188
import gleam/bool
@@ -173,11 +202,21 @@ fn my_dynamic_class(is_column: Bool) -> String {
173202
}
174203
```
175204

205+
## Memoizing a class
206+
207+
Sketch exposes a way to memoize a class:
208+
[`memo`](https://hexdocs.pm/sketch/sketch.html#memo). `memo` allows to keep a
209+
generated class _for ever_. When called on a class, sketch will preserves the
210+
class for ever, and will includes the class in every render, as long as the
211+
virtual stylesheet exists. This allows to skip all computations work for every
212+
class computations later, and to increase performances render. _Be careful, a
213+
class marked as `memo` will be then considered immutable and can never change._
214+
176215
## Using media queries and pseudo-selectors
177216

178-
Because we're in CSS-in-Gleam, we can leverage on the full CSS power,
179-
contrarily to inline styling. This mean we can use media queries and pseudo-selectors!
180-
You only need to call the proper functions, and sketch will take care of the rest.
217+
Because we're in CSS-in-Gleam, we can leverage on the full CSS power, contrarily
218+
to inline styling. This mean we can use media queries and pseudo-selectors! You
219+
only need to call the proper functions, and sketch will take care of the rest.
181220

182221
```gleam
183222
import sketch
@@ -230,19 +269,22 @@ The example above will be compiled to the following CSS.
230269
## Usage with Lustre — Details
231270

232271
[Lustre](https://hexdocs.pm/lustre/) is the recommended framework for frontend
233-
development in Gleam. Sketch tries to simplify as much the development with Lustre.
234-
That's why Sketch exposes a [`setup`](https://hexdocs.pm/sketch/sketch/lustre.html#setup)
235-
function. This function creates a cache, and returns it. Another function,
236-
[`compose`](https://hexdocs.pm/sketch/sketch/lustre.html#compose) allows to easily
237-
compose the cache with the view function of Lustre.
238-
It acts as a "hook" (lustre does not officially supports hooks right now): it setups
239-
the cache before the view, and render the stylesheet after the view has executed.
240-
It tries to be side-effect free in the `view` in order to have a predictable render
241-
in Lustre, and stick with the Elm architecture mindset.
242-
243-
Once setuped, you can use classes in your Lustre views: [`to_lustre()`](https://hexdocs.pm/sketch/sketch.html#to_lustre).
244-
Just use it in place of [`to_class_name()`](https://hexdocs.pm/sketch/sketch.html#to_class_name)
245-
to get a Lustre attribute and use it in your views.
272+
development in Gleam. Sketch tries to simplify as much the development with
273+
Lustre. That's why Sketch exposes a
274+
[`setup`](https://hexdocs.pm/sketch/sketch/lustre.html#setup) function. This
275+
function creates a cache, and returns it. Another function,
276+
[`compose`](https://hexdocs.pm/sketch/sketch/lustre.html#compose) allows to
277+
easily compose the cache with the view function of Lustre. It acts as a "hook"
278+
(lustre does not officially supports hooks right now): it setups the cache
279+
before the view, and render the stylesheet after the view has executed. It tries
280+
to be side-effect free in the `view` in order to have a predictable render in
281+
Lustre, and stick with the Elm architecture mindset.
282+
283+
Once setuped, you can use classes in your Lustre views:
284+
[`to_lustre()`](https://hexdocs.pm/sketch/sketch.html#to_lustre). Just use it in
285+
place of
286+
[`to_class_name()`](https://hexdocs.pm/sketch/sketch.html#to_class_name) to get
287+
a Lustre attribute and use it in your views.
246288

247289
```gleam
248290
import gleam/list
@@ -275,22 +317,23 @@ fn my_other_view(model: Bool) {
275317
## Use with Shadow DOM
276318

277319
Sketch can work with a Shadow DOM, in order to hide the compiled styles from the
278-
rest of the application. To do it, you can use [`plinth`](https://github.com/CrowdHailer/plinth).
279-
This allows to create a `ShadowRoot`, to use
320+
rest of the application. To do it, you can use
321+
[`plinth`](https://github.com/CrowdHailer/plinth). This allows to create a
322+
`ShadowRoot`, to use
280323
[`sketch/options.shadow_root()`](https://hexdocs.pm/sketch/sketch/options.html#shadow_root).
281-
In the same way you can initialize the cache to render in document or in a `style` node,
282-
you can now use a Shadow Root to paint styles in your application!
324+
In the same way you can initialize the cache to render in document or in a
325+
`style` node, you can now use a Shadow Root to paint styles in your application!
283326

284327
## Some opinions on properties
285328

286-
A lot of properties are accessible directly through the `sketch` package.
287-
But with time, some could be added, and new features for existing features
288-
can appear. That's why sketch will never try to be on your way: at any time
289-
you can access [`property()`](https://hexdocs.pm/sketch/sketch.html#property),
290-
which allows you to push any arbitrary property in a class. Another thing is ç
291-
that sketch will always let you access raw, low-level properties. If you're
292-
trying to use something like `sketch.width("auto")` and the property does not
293-
support String, look for a variant with an underscore (`_`), it should fullfill
294-
your needs, like `sketch.width_("auto")`!
295-
In case something is missing or a property does not have its underscore
296-
alternative, [open an issue — or better, a PR — on the repo!](https://github.com/ghivert/sketch)
329+
A lot of properties are accessible directly through the `sketch` package. But
330+
with time, some could be added, and new features for existing features can
331+
appear. That's why sketch will never try to be on your way: at any time you can
332+
access [`property()`](https://hexdocs.pm/sketch/sketch.html#property), which
333+
allows you to push any arbitrary property in a class. Another thing is ç that
334+
sketch will always let you access raw, low-level properties. If you're trying to
335+
use something like `sketch.width("auto")` and the property does not support
336+
String, look for a variant with an underscore (`_`), it should fullfill your
337+
needs, like `sketch.width_("auto")`! In case something is missing or a property
338+
does not have its underscore alternative,
339+
[open an issue — or better, a PR — on the repo!](https://github.com/ghivert/sketch)

0 commit comments

Comments
 (0)