Skip to content

Commit

Permalink
Merge pull request #11 from melange-re/styling-with-css
Browse files Browse the repository at this point in the history
Add 'styling with css' chapter
  • Loading branch information
feihong authored Jan 2, 2024
2 parents aff82e0 + 41945e1 commit f3166ab
Show file tree
Hide file tree
Showing 15 changed files with 556 additions and 3 deletions.
1 change: 1 addition & 0 deletions docs/.vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export default defineConfig({
{ text: 'Celsius Converter using Option', link: '/celsius-converter-option/' },
{ text: 'Introduction to Dune', link: '/intro-to-dune/' },
{ text: 'Order Confirmation', link: '/order-confirmation/' },
{ text: 'Styling with CSS', link: '/styling-with-css/' },
]
}
],
Expand Down
2 changes: 1 addition & 1 deletion docs/counter/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ We're going build the classic frontend starter app, the counter, using
[melange-for-react-devs-template](https://github.com/melange-re/melange-for-react-devs-template)
project
1. Run `make watch` to start the Melange compiler in watch mode.
1. In another terminal window, start the webpack dev server by running `make
1. In another terminal window, start the Webpack dev server by running `make
serve`. As a side effect, it will open a browser tab pointed to
<a href="http://localhost:8080/" target="_blank" rel="noreferrer
noopener">http://localhost:8080/</a>.
Expand Down
4 changes: 2 additions & 2 deletions docs/intro-to-dune/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ contains:
- `Index.re` to render the app to the DOM

<<< @/../src/counter/Index.re
- `Makefile` to serve the app using webpack dev server
- `Makefile` to serve the app using Webpack dev server

<<< @/../src/counter/Makefile{make}

Expand Down Expand Up @@ -202,7 +202,7 @@ use
./_build/default/src/$(app)/output/src/$(app)/Index.js
```
This means that the entry script served by webpack dev server depends on the
This means that the entry script served by Webpack dev server depends on the
`app` environment variable, which is provided by `src/counter/Makefile`.
You're now ready to run the new Counter app you created! Go into the
Expand Down
1 change: 1 addition & 0 deletions docs/intro/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ teaches the language from the ground up and goes much deeper into its features.
| Celsius Converter using Option | The same component from the last chapter but replacing exception handling with Option | Option, `Option.map`, `when` guard |
| Introduction to Dune | A introduction to the Dune build system | `dune-project` file, `dune` file, `melange.emit` stanza, `Makefile`, monorepo structure |
| Order Confirmation | An order confirmation for a restaurant website | variant type, primary type of module (`t`), wildcard (`_`) in switch, `fun` syntax, `Js.Array` functions, `React.array`, type transformation functions |
| Styling with CSS | Styling the order confirmation using CSS | `mel.raw` extension node, `runtime_deps` field, `glob_files` term, `external`, `mel.module` attribute |

...and much more to come!

Expand Down
102 changes: 102 additions & 0 deletions docs/styling-with-css/Order.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
module Item = {
type t =
| Sandwich
| Burger
| Hotdog;

let toPrice =
fun
| Sandwich => 10.
| Burger => 15.
| Hotdog => 5.;

let toEmoji =
fun
| Sandwich => {js|🥪|js}
| Burger => {js|🍔|js}
| Hotdog => {js|🌭|js};
};

module Format = {
let currency = _value => React.null;
};

// #region order-item
module OrderItem = {
[@react.component]
let make = (~item: Item.t) =>
<tr className="item">
<td className="emoji"> {item |> Item.toEmoji |> React.string} </td>
<td className="price"> {item |> Item.toPrice |> Format.currency} </td>
</tr>;
};
// #endregion order-item

type t = array(Item.t);

// #region order-make
[@react.component]
let make = (~items: t) => {
let total =
items |> Js.Array.reduce((acc, order) => acc +. Item.toPrice(order), 0.);

<table className="order">
<tbody>
{items
|> Js.Array.mapi((item, index) =>
<OrderItem key={"item-" ++ string_of_int(index)} item />
)
|> React.array}
<tr className="total">
<td> {React.string("Total")} </td>
<td> {total |> Format.currency} </td>
</tr>
</tbody>
</table>;
};
// #endregion order-make

module OrderItemV2 = {
// #region order-item-css
module OrderItem = {
[@mel.module "./order-item.module.css"]
external css: Js.t({..}) = "default";

[@react.component]
let make = (~item: Item.t) =>
<tr className=css##item>
<td className=css##emoji> {item |> Item.toEmoji |> React.string} </td>
<td className=css##price>
{item |> Item.toPrice |> Format.currency}
</td>
</tr>;
};
// #endregion order-item-css
};

module OrderV2 = {
// #region order-external
[@mel.module "./order.module.css"] external css: Js.t({..}) = "default";

[@react.component]
let make = (~items: t) => {
let total =
items
|> Js.Array.reduce((acc, order) => acc +. Item.toPrice(order), 0.);

<table className=css##order>
<tbody>
{items
|> Js.Array.mapi((item, index) =>
<OrderItem key={"item-" ++ string_of_int(index)} item />
)
|> React.array}
<tr className=css##total>
<td> {React.string("Total")} </td>
<td> {total |> Format.currency} </td>
</tr>
</tbody>
</table>;
};
// #endregion order-external
};
8 changes: 8 additions & 0 deletions docs/styling-with-css/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
(melange.emit
(target output)
(libraries reason-react)
(preprocess
(pps melange.ppx reason-react-ppx))
(module_systems es6)
(runtime_deps
(glob_files *.css)))
Loading

0 comments on commit f3166ab

Please sign in to comment.