├── .gitignore
├── README.md
├── bsconfig.json
├── package.json
├── src
├── deck.mdx
├── images
│ ├── astrocoders.png
│ ├── astrocoders.svg
│ ├── download.jpeg
│ ├── fnm.svg
│ ├── glitch-bust.jpeg
│ ├── glitch-contrast.jpg
│ ├── glitch-contrast.png
│ ├── glitch-unsettling.jpg
│ ├── glitched-coffee.jpg
│ ├── glitched-faces.mp4
│ ├── perspective.jpg
│ ├── reasonml-architechture.svg
│ ├── refs.txt
│ ├── revery.png
│ ├── stinks.jpg
│ ├── stonks.jpg
│ ├── unbreakable.jpg
│ └── vaporwave-glitch.jpg
├── juice
│ ├── CodeSurfer.bs.js
│ ├── CodeSurfer.re
│ ├── CodeSurferHighlighter.js
│ ├── GlitchImage.bs.js
│ ├── GlitchImage.re
│ ├── Hooks.bs.js
│ ├── Hooks.re
│ ├── Image.bs.js
│ ├── Image.re
│ ├── Paragraph.bs.js
│ ├── Paragraph.re
│ ├── SplitLayout.bs.js
│ ├── SplitLayout.re
│ ├── Title.js
│ ├── VideoBackground.bs.js
│ └── VideoBackground.re
└── snippets
│ ├── GraphQLDemo.graphql
│ ├── GraphQLDemo.re
│ ├── PatternMatchingDemo.bs.js
│ ├── PatternMatchingDemo.re
│ ├── PatternMatchingDemo.ts
│ ├── PatternMatchingDemo2.ts
│ ├── PatternMatchingDemo3.ts
│ ├── PatternMatchingDemoError.bs.js
│ ├── PatternMatchingDemoError.re
│ ├── VariantDemo.bs.js
│ ├── VariantDemo.re
│ ├── VariantDemoSwitch.ts
│ └── VariantDemoTypes.ts
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | public
3 | .merlin
4 | lib/
5 | .bsb.lock
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ReasonML/ES2077 - ReactConf Dev
2 |
3 | mdx-deck presentation.
4 |
5 | Components were done in Reason and JS to demo interop.
6 |
7 | ### References
8 |
9 | https://reasonml.chat
10 |
11 | https://khoanguyen.me/reasonml-toolchain/
12 |
13 | https://medium.com/astrocoders/render-props-composition-for-reasonml-is-here-b9c004ca9fcb
14 |
15 | https://github.com/astrocoders/lenses-ppx
16 |
17 | https://github.com/revery-ui/revery
18 |
19 | https://github.com/Schniz/fnm/
20 |
21 | https://github.com/andreas/ocaml-graphql-server
22 |
23 | https://reasonml.github.io/reason-react/
24 |
25 | https://reasonml.github.io
26 |
27 | https://github.com/mhallin/graphql_ppx
28 |
--------------------------------------------------------------------------------
/bsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "deck",
3 | "reason": {
4 | "react-jsx": 3
5 | },
6 | "sources": {
7 | "dir": "src",
8 | "subdirs": [
9 | { "dir": "juice" }
10 | ]
11 | },
12 | "package-specs": [{
13 | "module": "commonjs",
14 | "in-source": true
15 | }],
16 | "suffix": ".bs.js",
17 | "namespace": true,
18 | "bs-dependencies": [
19 | "reason-react",
20 | "bs-css"
21 | ],
22 | "refmt": 3
23 | }
24 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "es2077-reactconf",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "mdx-deck src/deck.mdx",
8 | "bs:build": "bsb -make-world",
9 | "build": "yarn bs:build && mdx-deck build src/deck.mdx",
10 | "deck:publish": "yarn build && gh-pages -d public",
11 | "watch": "bsb -make-world -w"
12 | },
13 | "author": "",
14 | "license": "ISC",
15 | "devDependencies": {
16 | "mdx-deck": "^3.0.9"
17 | },
18 | "dependencies": {
19 | "aug-attr-spliced": "^0.2.0",
20 | "augmented-ui": "^1.1.0",
21 | "bs-css": "^10.0.1",
22 | "bs-platform": "^5.0.6",
23 | "gh-pages": "^2.1.1",
24 | "mdx-code": "^1.1.3",
25 | "prism-react-renderer": "^0.1.7",
26 | "qrcode.react": "^0.9.3",
27 | "reason-react": "^0.7.0",
28 | "styled-components": "^4.3.2"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/deck.mdx:
--------------------------------------------------------------------------------
1 | import { Image, Head, Notes, Appear, } from 'mdx-deck'
2 | import highlight from '@mdx-deck/themes/syntax-highlighter-prism'
3 | import QRCode from 'qrcode.react'
4 |
5 | import { Title } from './juice/Title'
6 | import Paragraph from './juice/Paragraph.bs'
7 | import SplitLayout from './juice/SplitLayout.bs'
8 | import ImageFit from './juice/Image.bs'
9 | import GlitchImage from './juice/GlitchImage.bs'
10 | import VideoBackground from './juice/VideoBackground.bs'
11 | import CodeSurfer from './juice/CodeSurfer.bs'
12 |
13 | import glitchFacesVideo from './images/glitched-faces.mp4'
14 |
15 | import glitchUnsettlingImage from './images/glitch-unsettling.jpg'
16 | import glitchContrastImage from './images/glitch-contrast.png'
17 | import glitchUnbreakableImage from './images/unbreakable.jpg'
18 | import glitchPerspectiveImage from './images/perspective.jpg'
19 | import glitchBust from './images/glitch-bust.jpeg'
20 | import astrocodersImage from './images/astrocoders.png'
21 |
22 | import fnmImage from './images/fnm.svg'
23 | import reveryImage from './images/revery.png'
24 |
25 | import variantSnippet from '!raw-loader!./snippets/VariantDemo.re'
26 | import variantTypesTsSnippet from '!raw-loader!./snippets/VariantDemoTypes.ts'
27 | import variantSwitchTsSnippet from '!raw-loader!./snippets/VariantDemoSwitch.ts'
28 |
29 | import patternMatchingDemoTS from '!raw-loader!./snippets/PatternMatchingDemo.ts'
30 | import patternMatchingDemoTS2 from '!raw-loader!./snippets/PatternMatchingDemo2.ts'
31 | import patternMatchingDemoTS3 from '!raw-loader!./snippets/PatternMatchingDemo3.ts'
32 | import patternMatchingDemoReason from '!raw-loader!./snippets/PatternMatchingDemo.re'
33 | import patternMatchingDemoReasonError from '!raw-loader!./snippets/PatternMatchingDemoError.re'
34 | import graphQLDemo from '!raw-loader!./snippets/GraphQLDemo.graphql'
35 | import graphQLDemoReason from '!raw-loader!./snippets/GraphQLDemo.re'
36 |
37 | import reasonmlToolchain from './images/reasonml-architechture.svg'
38 | import stinks from './images/stinks.jpg'
39 | import stonks from './images/stonks.jpg'
40 |
41 | export const themes = [
42 | highlight
43 | ]
44 |
45 |
46 | Unbreakable apps with ECMAScript 2077
47 |
48 |
49 |
50 |
51 |
52 |
53 | ## Incoming from the future
54 |
55 | ---
56 |
57 |
58 | ReasonML
59 |
60 |
61 | ---
62 |
63 |
64 |
65 |
66 |
Gabriel R. Abreu
67 |
Astrocoders
68 |
CTO Founder
69 |
Father
70 |
Bad Jokes Engineer
71 |
Creator of Epitath (hooks prior art)
72 |
and ReForm
73 |
74 |
75 |
76 | ---
77 |
78 | @fakenickels
79 |
80 |
81 | Twitter, GitHub, Reddit, Instagram
82 |
83 | ---
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | Slides
92 |
93 |
94 |
95 | ---
96 |
97 | What's ReasonML?
98 |
99 |
100 | - Yet Another Awesome Tool Created by Facebook
101 |
102 | - Envisioned by React creator Jordan Walke
103 | - Think of it as an syntax/dialect for OCaml
104 | - OCaml is a super fast, type inferred, highly hackable FP language
105 |
106 |
107 |
108 | ---
109 |
110 |
111 |
112 |
113 |
114 | # Put types in JS
115 |
116 |
117 |
118 | ---
119 |
120 |
121 |
122 |
123 | # Put JS in types
124 |
125 |
126 |
127 | ---
128 |
129 |
130 |
131 |
132 | How unbreakable?
133 |
134 |
135 | ---
136 |
137 | # Let's get philosophical
138 |
139 | >"Philosophically speaking, a problem is composed of many possible branches/conditions. Mishandling these conditions is the majority of what we call bugs."
140 |
141 | ---
142 |
143 | # Let's get philosophical
144 |
145 | >"A type system doesn't magically eliminate bugs; it points out the unhandled conditions and asks you to cover them"
146 |
147 | ---
148 |
149 |
158 |
159 | ---
160 |
161 |
162 |
163 |
164 |
165 |
Contrast
166 |
with TypeScript
167 |
168 |
169 |
170 | ---
171 |
172 | # Types
173 |
174 |
182 |
183 | ---
184 |
185 | # Pattern matching?
186 |
187 |
197 |
198 | ---
199 |
200 | # Not your grandma!
201 |
202 |
203 |
204 | Reason's type system is not just a powerful linter.
205 | You use it to model your program from top to bottom.
206 |
207 |
208 |
209 | ---
210 |
211 | # ReasonML ❤️ React
212 |
213 | ---
214 |
215 | # React demo
216 |
217 |
229 |
230 | ---
231 |
232 | # TS version
233 |
234 |
243 |
244 | ---
245 |
246 | # TS version
247 |
248 |
255 |
256 | ---
257 |
258 | # TS version
259 |
260 |
267 |
268 | ---
269 |
270 | # ReasonML
271 |
272 |
280 |
281 | ---
282 |
283 |
284 |
285 |
286 | Statically known types
287 |
288 |
289 | ---
290 |
291 | GraphQL
292 |
293 | ---
294 |
295 | # GraphQL
296 |
297 |
305 |
306 | ---
307 |
308 | # ReasonML
309 |
310 |
323 |
324 | ---
325 |
326 | This is less tests
327 |
328 | ---
329 |
330 | This is less bugs to production
331 |
332 | ---
333 |
334 | This is the future
335 |
336 | ---
337 |
338 | # Shared ecosystem
339 |
340 | - ReasonML brings together the OCaml community and the JS community
341 | - OCaml brings the safety and robustness the web needs
342 |
343 | ---
344 |
345 | # JS Shared ecosystem
346 |
347 | - Install it with `npm i --global bs-platform`
348 | - Or with a starter `bsb -init demo`
349 | - Or with a React starter `bsb -init demo -theme react-hooks`
350 |
351 | ---
352 |
353 | # Native ecosystem
354 |
355 | - Install it with `npm i --global esy pesy`
356 | - Or with a starter `mkdir demo && cd demo && pesy`
357 |
358 | ---
359 |
360 |
361 |
362 |
363 | ReasonML toolchain
364 |
365 |
366 | ---
367 |
368 |
369 |
370 | ---
371 |
372 | # Tools of the ecosystem
373 |
374 | - BuckleScript
375 | - esy.sh
376 | - Revery
377 |
378 | ---
379 |
380 | BuckleScript
381 |
382 |
383 | - Created by Bloomberg as a better alternative to js_of_ocaml
384 |
385 | - Powered by the ninja compiler, insane compile time
386 | - Readable output
387 |
388 |
389 |
390 | ---
391 |
392 | esy.sh
393 |
394 |
395 | - Brings npm concepts for OCaml ecosystem and package manager (OPAM)
396 |
397 | - Created also by Jordan Walke
398 | - Easiness to create pre-compiled and multiplatform programs
399 | - Created with esy:
400 |
401 |
402 |
403 | ---
404 |
405 |
406 |
407 |
408 |
409 |
fnm
410 | Fast and simple Node.js version manager, built in native ReasonML
411 |
412 |
413 |
414 | ---
415 |
416 |
417 |
418 |
419 |
Revery
420 | Build native, high-performance, cross-platform desktop apps with Reason!
421 |
422 |
423 |
424 | ---
425 |
426 |
427 |
428 | Unsettling
429 |
430 |
431 | ---
432 |
433 | Problems
434 |
435 |
436 |
437 | - Mindset change
438 |
439 | - Syntax errors
440 | - Docs are sparse sometimes
441 | - Community is growing at a fast pace, but you may still not find everything you need
442 |
443 |
444 |
445 |
446 | ---
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
discord.gg/reasonml
456 |
457 |
458 | I just heard about Reason at ReactConf Brazil!
459 |
460 |
461 |
462 |
463 |
464 | ---
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
Astrocoders
473 |
474 | - https://vannamei.com.br
475 | - https://astrocoders.com
476 | - https://github.com/Astrocoders
477 | - https://github.com/Astrocoders/fullstack-challenge
478 |
479 |
480 |
481 |
482 |
483 | ---
484 |
485 |
486 |
487 |
488 |
489 |
Thank you!
490 | Obrigado!
491 | 謝謝!
492 |
493 |
494 |
495 | ---
496 |
497 |
498 |
499 |
500 | Questions?
501 |
502 |
--------------------------------------------------------------------------------
/src/images/astrocoders.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fakenickels/es2077-reactconf/03ec80b25ca40bf4c3d8d2f66cd415c0b33ba8f1/src/images/astrocoders.png
--------------------------------------------------------------------------------
/src/images/astrocoders.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/images/download.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fakenickels/es2077-reactconf/03ec80b25ca40bf4c3d8d2f66cd415c0b33ba8f1/src/images/download.jpeg
--------------------------------------------------------------------------------
/src/images/fnm.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/images/glitch-bust.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fakenickels/es2077-reactconf/03ec80b25ca40bf4c3d8d2f66cd415c0b33ba8f1/src/images/glitch-bust.jpeg
--------------------------------------------------------------------------------
/src/images/glitch-contrast.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fakenickels/es2077-reactconf/03ec80b25ca40bf4c3d8d2f66cd415c0b33ba8f1/src/images/glitch-contrast.jpg
--------------------------------------------------------------------------------
/src/images/glitch-contrast.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fakenickels/es2077-reactconf/03ec80b25ca40bf4c3d8d2f66cd415c0b33ba8f1/src/images/glitch-contrast.png
--------------------------------------------------------------------------------
/src/images/glitch-unsettling.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fakenickels/es2077-reactconf/03ec80b25ca40bf4c3d8d2f66cd415c0b33ba8f1/src/images/glitch-unsettling.jpg
--------------------------------------------------------------------------------
/src/images/glitched-coffee.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fakenickels/es2077-reactconf/03ec80b25ca40bf4c3d8d2f66cd415c0b33ba8f1/src/images/glitched-coffee.jpg
--------------------------------------------------------------------------------
/src/images/glitched-faces.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fakenickels/es2077-reactconf/03ec80b25ca40bf4c3d8d2f66cd415c0b33ba8f1/src/images/glitched-faces.mp4
--------------------------------------------------------------------------------
/src/images/perspective.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fakenickels/es2077-reactconf/03ec80b25ca40bf4c3d8d2f66cd415c0b33ba8f1/src/images/perspective.jpg
--------------------------------------------------------------------------------
/src/images/reasonml-architechture.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/images/refs.txt:
--------------------------------------------------------------------------------
1 | https://www.reddit.com/r/glitch_art/comments/bpbnsb/cool_glitch_art_i_stumbled_upon/
2 | https://www.reddit.com/r/glitch_art/comments/d8ywvc/džⱦⱦϟ_and_æŵĥĭɣ/
3 | https://i.imgur.com/tREJVZG.jpg
4 |
--------------------------------------------------------------------------------
/src/images/revery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fakenickels/es2077-reactconf/03ec80b25ca40bf4c3d8d2f66cd415c0b33ba8f1/src/images/revery.png
--------------------------------------------------------------------------------
/src/images/stinks.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fakenickels/es2077-reactconf/03ec80b25ca40bf4c3d8d2f66cd415c0b33ba8f1/src/images/stinks.jpg
--------------------------------------------------------------------------------
/src/images/stonks.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fakenickels/es2077-reactconf/03ec80b25ca40bf4c3d8d2f66cd415c0b33ba8f1/src/images/stonks.jpg
--------------------------------------------------------------------------------
/src/images/unbreakable.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fakenickels/es2077-reactconf/03ec80b25ca40bf4c3d8d2f66cd415c0b33ba8f1/src/images/unbreakable.jpg
--------------------------------------------------------------------------------
/src/images/vaporwave-glitch.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fakenickels/es2077-reactconf/03ec80b25ca40bf4c3d8d2f66cd415c0b33ba8f1/src/images/vaporwave-glitch.jpg
--------------------------------------------------------------------------------
/src/juice/CodeSurfer.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 5.0.6, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var Css = require("bs-css/src/Css.js");
5 | var React = require("react");
6 | var MdxDeck = require("mdx-deck");
7 | var Belt_Array = require("bs-platform/lib/js/belt_Array.js");
8 | var CodeSurferHighlighter = require("./CodeSurferHighlighter");
9 |
10 | var make = CodeSurferHighlighter.Highlighter;
11 |
12 | var Highlighter = /* module */[/* make */make];
13 |
14 | function CodeSurfer(Props) {
15 | var code = Props.code;
16 | var language = Props.language;
17 | var highlights = Props.highlights;
18 | var length = highlights.length + 1 | 0;
19 | var currentStep = MdxDeck.useSteps(length);
20 | var noSurfing = currentStep === length || currentStep === 0;
21 | return React.createElement("div", {
22 | className: Css.style(/* :: */[
23 | Css.height(Css.vh(100)),
24 | /* :: */[
25 | Css.width(Css.vw(100)),
26 | /* :: */[
27 | Css.padding(Css.px(30)),
28 | /* :: */[
29 | Css.backgroundColor(Css.hex("fbfbfb")),
30 | /* :: */[
31 | Css.fontSize(Css.px(30)),
32 | /* :: */[
33 | Css.display(/* flex */-1010954439),
34 | /* :: */[
35 | Css.alignItems(Css.center),
36 | /* :: */[
37 | Css.justifyContent(Css.center),
38 | /* [] */0
39 | ]
40 | ]
41 | ]
42 | ]
43 | ]
44 | ]
45 | ]
46 | ])
47 | }, React.createElement(make, {
48 | code: code,
49 | language: language,
50 | noSurfing: noSurfing,
51 | currentHighlights: Belt_Array.get(highlights, currentStep - 1 | 0)
52 | }));
53 | }
54 |
55 | var make$1 = CodeSurfer;
56 |
57 | var $$default = CodeSurfer;
58 |
59 | exports.Highlighter = Highlighter;
60 | exports.make = make$1;
61 | exports.$$default = $$default;
62 | exports.default = $$default;
63 | exports.__esModule = true;
64 | /* make Not a pure module */
65 |
--------------------------------------------------------------------------------
/src/juice/CodeSurfer.re:
--------------------------------------------------------------------------------
1 | type range = (int, int);
2 |
3 | module Highlighter = {
4 | [@bs.module "./CodeSurferHighlighter"] [@react.component]
5 | external make:
6 | (
7 | ~code: string,
8 | ~language: string,
9 | ~noSurfing: bool,
10 | ~currentHighlights: option(range)
11 | ) =>
12 | React.element =
13 | "Highlighter";
14 | };
15 |
16 | [@react.component]
17 | let make = (~code, ~language, ~highlights: array(range)) => {
18 | let length = Array.length(highlights) + 1;
19 | let currentStep = Hooks.useSteps(length);
20 | let noSurfing = currentStep == length || currentStep == 0;
21 |
22 |
35 | Belt.Array.get(currentStep - 1)}
40 | />
41 |
;
42 | };
43 |
44 | let default = make;
45 |
--------------------------------------------------------------------------------
/src/juice/CodeSurferHighlighter.js:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import Highlight, { defaultProps } from "prism-react-renderer";
3 | import theme from "prism-react-renderer/themes/nightOwlLight"
4 |
5 | export const Highlighter = ({ code, language, currentHighlights = [NaN, NaN], noSurfing }) =>
6 |
7 | {({ className, style, tokens, getLineProps, getTokenProps }) => (
8 |
9 | {tokens.map((line, i) => {
10 | const { style: prismStyle, ...props } = getLineProps({ line, key: i })
11 | const style = {
12 | ...prismStyle,
13 | opacity: noSurfing || (i+1 >= currentHighlights[0] && i+1 <= currentHighlights[1]) ? 1 : 0.5,
14 | transition: 'opacity ease-out 0.3s'
15 | }
16 |
17 | return (
18 |
19 | {line.map((token, key) => (
20 |
21 | ))}
22 |
23 | )
24 | })}
25 |
26 | )}
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/juice/GlitchImage.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 5.0.6, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var Css = require("bs-css/src/Css.js");
5 | var React = require("react");
6 | var Caml_option = require("bs-platform/lib/js/caml_option.js");
7 |
8 | function wrapper(src) {
9 | return Css.style(/* :: */[
10 | Css.width(Css.pct(100)),
11 | /* :: */[
12 | Css.height(Css.pct(100)),
13 | /* :: */[
14 | Css.backgroundImage(/* `url */[
15 | 5843823,
16 | src
17 | ]),
18 | /* :: */[
19 | Css.backgroundRepeat(Css.noRepeat),
20 | /* :: */[
21 | Css.backgroundSize(Css.cover),
22 | /* :: */[
23 | Css.overflow(Css.hidden),
24 | /* :: */[
25 | Css.position(Css.relative),
26 | /* [] */0
27 | ]
28 | ]
29 | ]
30 | ]
31 | ]
32 | ]
33 | ]);
34 | }
35 |
36 | var glitchAnimation1Horizontal = Css.keyframes(/* :: */[
37 | /* tuple */[
38 | 0,
39 | /* :: */[
40 | Css.unsafe("clip-path", "polygon(0 2%, 100% 2%, 100% 5%, 0 5%)"),
41 | /* [] */0
42 | ]
43 | ],
44 | /* :: */[
45 | /* tuple */[
46 | 5,
47 | /* :: */[
48 | Css.unsafe("clip-path", "polygon(0 15%, 100% 15%, 100% 15%, 0 15%)"),
49 | /* [] */0
50 | ]
51 | ],
52 | /* :: */[
53 | /* tuple */[
54 | 10,
55 | /* :: */[
56 | Css.unsafe("clip-path", "polygon(0 10%, 100% 10%, 100% 20%, 0 20%)"),
57 | /* [] */0
58 | ]
59 | ],
60 | /* :: */[
61 | /* tuple */[
62 | 15,
63 | /* :: */[
64 | Css.unsafe("clip-path", "polygon(0 1%, 100% 1%, 100% 2%, 0 2%)"),
65 | /* [] */0
66 | ]
67 | ],
68 | /* :: */[
69 | /* tuple */[
70 | 20,
71 | /* :: */[
72 | Css.unsafe("clip-path", "polygon(0 33%, 100% 33%, 100% 33%, 0 33%)"),
73 | /* [] */0
74 | ]
75 | ],
76 | /* :: */[
77 | /* tuple */[
78 | 25,
79 | /* :: */[
80 | Css.unsafe("clip-path", "polygon(0 44%, 100% 44%, 100% 44%, 0 44%)"),
81 | /* [] */0
82 | ]
83 | ],
84 | /* :: */[
85 | /* tuple */[
86 | 30,
87 | /* :: */[
88 | Css.unsafe("clip-path", "polygon(0 50%, 100% 50%, 100% 20%, 0 20%)"),
89 | /* [] */0
90 | ]
91 | ],
92 | /* :: */[
93 | /* tuple */[
94 | 35,
95 | /* :: */[
96 | Css.unsafe("clip-path", "polygon(0 70%, 100% 70%, 100% 70%, 0 70%)"),
97 | /* [] */0
98 | ]
99 | ],
100 | /* :: */[
101 | /* tuple */[
102 | 40,
103 | /* :: */[
104 | Css.unsafe("clip-path", "polygon(0 80%, 100% 80%, 100% 80%, 0 80%)"),
105 | /* [] */0
106 | ]
107 | ],
108 | /* :: */[
109 | /* tuple */[
110 | 45,
111 | /* :: */[
112 | Css.unsafe("clip-path", "polygon(0 50%, 100% 50%, 100% 55%, 0 55%)"),
113 | /* [] */0
114 | ]
115 | ],
116 | /* :: */[
117 | /* tuple */[
118 | 50,
119 | /* :: */[
120 | Css.unsafe("clip-path", "polygon(0 70%, 100% 70%, 100% 80%, 0 80%)"),
121 | /* [] */0
122 | ]
123 | ],
124 | /* :: */[
125 | /* tuple */[
126 | 51,
127 | /* :: */[
128 | Css.unsafe("clip-path", "polygon(0 0, 0 0)"),
129 | /* [] */0
130 | ]
131 | ],
132 | /* :: */[
133 | /* tuple */[
134 | 100,
135 | /* :: */[
136 | Css.unsafe("clip-path", "polygon(0 0, 0 0)"),
137 | /* [] */0
138 | ]
139 | ],
140 | /* [] */0
141 | ]
142 | ]
143 | ]
144 | ]
145 | ]
146 | ]
147 | ]
148 | ]
149 | ]
150 | ]
151 | ]
152 | ]
153 | ]);
154 |
155 | function glitch(src, $staropt$star, bgColor, blendMode, $staropt$star$1, param) {
156 | var animDuration = $staropt$star !== undefined ? $staropt$star : 600;
157 | var animationName = $staropt$star$1 !== undefined ? Caml_option.valFromOption($staropt$star$1) : glitchAnimation1Horizontal;
158 | return Css.style(/* :: */[
159 | Css.position(Css.absolute),
160 | /* :: */[
161 | Css.top(Css.zero),
162 | /* :: */[
163 | Css.left(Css.zero),
164 | /* :: */[
165 | Css.width(Css.pct(110)),
166 | /* :: */[
167 | Css.height(Css.pct(110)),
168 | /* :: */[
169 | Css.backgroundImage(Css.url(src)),
170 | /* :: */[
171 | Css.backgroundRepeat(Css.noRepeat),
172 | /* :: */[
173 | Css.backgroundColor(bgColor),
174 | /* :: */[
175 | Css.backgroundPosition(Css.pct(50), Css.zero),
176 | /* :: */[
177 | Css.backgroundSize(Css.cover),
178 | /* :: */[
179 | Css.animation(animDuration, undefined, Css.alternateReverse, undefined, undefined, undefined, Css.infinite, animationName),
180 | /* :: */[
181 | Css.unsafe("backgroundBlendMode", blendMode),
182 | /* [] */0
183 | ]
184 | ]
185 | ]
186 | ]
187 | ]
188 | ]
189 | ]
190 | ]
191 | ]
192 | ]
193 | ]
194 | ]);
195 | }
196 |
197 | var Styles = /* module */[
198 | /* wrapper */wrapper,
199 | /* glitchAnimation1Horizontal */glitchAnimation1Horizontal,
200 | /* glitch */glitch
201 | ];
202 |
203 | function GlitchImage(Props) {
204 | var src = Props.src;
205 | var bgColor = /* `hex */[
206 | 5194459,
207 | "fff"
208 | ];
209 | var blendMode = "hard-light";
210 | return React.createElement("div", {
211 | className: wrapper(src)
212 | }, React.createElement("div", {
213 | className: glitch(src, 2300, bgColor, blendMode, undefined, /* () */0)
214 | }), React.createElement("div", {
215 | className: glitch(src, 2400, /* `hex */[
216 | 5194459,
217 | "000"
218 | ], blendMode, undefined, /* () */0)
219 | }), React.createElement("div", {
220 | className: glitch(src, 2500, bgColor, blendMode, undefined, /* () */0)
221 | }), React.createElement("div", {
222 | className: glitch(src, 2000, /* `hex */[
223 | 5194459,
224 | "000"
225 | ], "overlay", undefined, /* () */0)
226 | }));
227 | }
228 |
229 | var make = GlitchImage;
230 |
231 | var $$default = GlitchImage;
232 |
233 | exports.Styles = Styles;
234 | exports.make = make;
235 | exports.$$default = $$default;
236 | exports.default = $$default;
237 | exports.__esModule = true;
238 | /* glitchAnimation1Horizontal Not a pure module */
239 |
--------------------------------------------------------------------------------
/src/juice/GlitchImage.re:
--------------------------------------------------------------------------------
1 | /* Reference https://tympanus.net/Tutorials/CSSGlitchEffect/index.html */
2 |
3 | module Styles = {
4 | open Css;
5 |
6 | let wrapper = (~src) => style([
7 | width(pct(100.)),
8 | height(pct(100.)),
9 | backgroundImage(`url(src)),
10 | backgroundRepeat(noRepeat),
11 | backgroundSize(cover),
12 | overflow(hidden),
13 | position(relative),
14 | ]);
15 |
16 | let glitchAnimation1Horizontal = keyframes([
17 | (0, [
18 | unsafe("clip-path", "polygon(0 2%, 100% 2%, 100% 5%, 0 5%)"),
19 | ]),
20 | (5, [
21 | unsafe("clip-path", "polygon(0 15%, 100% 15%, 100% 15%, 0 15%)"),
22 | ]),
23 | (10, [
24 | unsafe("clip-path", "polygon(0 10%, 100% 10%, 100% 20%, 0 20%)"),
25 | ]),
26 | (15, [
27 | unsafe("clip-path", "polygon(0 1%, 100% 1%, 100% 2%, 0 2%)"),
28 | ]),
29 | (20, [
30 | unsafe("clip-path", "polygon(0 33%, 100% 33%, 100% 33%, 0 33%)"),
31 | ]),
32 | (25, [
33 | unsafe("clip-path", "polygon(0 44%, 100% 44%, 100% 44%, 0 44%)"),
34 | ]),
35 | (30, [
36 | unsafe("clip-path", "polygon(0 50%, 100% 50%, 100% 20%, 0 20%)"),
37 | ]),
38 | (35, [
39 | unsafe("clip-path", "polygon(0 70%, 100% 70%, 100% 70%, 0 70%)"),
40 | ]),
41 | (40, [
42 | unsafe("clip-path", "polygon(0 80%, 100% 80%, 100% 80%, 0 80%)"),
43 | ]),
44 | (45, [
45 | unsafe("clip-path", "polygon(0 50%, 100% 50%, 100% 55%, 0 55%)"),
46 | ]),
47 | (50, [
48 | unsafe("clip-path", "polygon(0 70%, 100% 70%, 100% 80%, 0 80%)"),
49 | ]),
50 | (51, [
51 | unsafe("clip-path", "polygon(0 0, 0 0)"),
52 | ]),
53 | (100, [
54 | unsafe("clip-path", "polygon(0 0, 0 0)"),
55 | ]),
56 | ])
57 |
58 | let glitch = (~src, ~animDuration=600, ~bgColor, ~blendMode, ~animationName=glitchAnimation1Horizontal, ()) => style([
59 | position(absolute),
60 | top(zero),
61 | left(zero),
62 | width(pct(110.)),
63 | height(pct(110.)),
64 | backgroundImage(url(src)),
65 | backgroundRepeat(noRepeat),
66 | backgroundColor(bgColor),
67 | backgroundPosition(pct(50.), zero),
68 | backgroundSize(cover),
69 | animation(~duration=animDuration, ~direction=alternateReverse, ~iterationCount=infinite, animationName),
70 | unsafe("backgroundBlendMode", blendMode)
71 | ])
72 | };
73 |
74 |
75 | [@react.component]
76 | let make = (~src) => {
77 | let bgColor = `hex("fff");
78 | let blendMode = "hard-light";
79 | let baseDuration = 1500;
80 |
81 |
87 | }
88 |
89 | let default = make
90 |
--------------------------------------------------------------------------------
/src/juice/Hooks.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 5.0.6, PLEASE EDIT WITH CARE
2 | /* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */
3 |
--------------------------------------------------------------------------------
/src/juice/Hooks.re:
--------------------------------------------------------------------------------
1 | [@bs.module "mdx-deck"] external useSteps : int => int = "useSteps";
2 |
--------------------------------------------------------------------------------
/src/juice/Image.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 5.0.6, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var Css = require("bs-css/src/Css.js");
5 | var React = require("react");
6 |
7 | function $$Image(Props) {
8 | var src = Props.src;
9 | return React.createElement("img", {
10 | className: Css.style(/* :: */[
11 | Css.maxWidth(Css.pct(100)),
12 | /* [] */0
13 | ]),
14 | src: src
15 | });
16 | }
17 |
18 | var make = $$Image;
19 |
20 | var $$default = $$Image;
21 |
22 | exports.make = make;
23 | exports.$$default = $$default;
24 | exports.default = $$default;
25 | exports.__esModule = true;
26 | /* Css Not a pure module */
27 |
--------------------------------------------------------------------------------
/src/juice/Image.re:
--------------------------------------------------------------------------------
1 | [@react.component]
2 | let make = (~src) => {
3 |
4 | }
5 |
6 | let default = make
7 |
--------------------------------------------------------------------------------
/src/juice/Paragraph.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 5.0.6, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var Css = require("bs-css/src/Css.js");
5 | var React = require("react");
6 |
7 | function Paragraph(Props) {
8 | var children = Props.children;
9 | return React.createElement("p", {
10 | className: Css.style(/* :: */[
11 | Css.padding(Css.px(30)),
12 | /* :: */[
13 | Css.textAlign(Css.center),
14 | /* [] */0
15 | ]
16 | ])
17 | }, children);
18 | }
19 |
20 | var make = Paragraph;
21 |
22 | var $$default = Paragraph;
23 |
24 | exports.make = make;
25 | exports.$$default = $$default;
26 | exports.default = $$default;
27 | exports.__esModule = true;
28 | /* Css Not a pure module */
29 |
--------------------------------------------------------------------------------
/src/juice/Paragraph.re:
--------------------------------------------------------------------------------
1 | [@react.component]
2 | let make = (~children) =>
3 |
4 | children
5 |
6 |
7 | let default = make;
8 |
--------------------------------------------------------------------------------
/src/juice/SplitLayout.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 5.0.6, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var Css = require("bs-css/src/Css.js");
5 | var React = require("react");
6 |
7 | var wrapper = Css.style(/* :: */[
8 | Css.width(Css.pct(100)),
9 | /* :: */[
10 | Css.height(Css.pct(100)),
11 | /* :: */[
12 | Css.display(Css.grid),
13 | /* :: */[
14 | Css.gridTemplateColumns(/* :: */[
15 | Css.fr(1),
16 | /* :: */[
17 | Css.fr(1),
18 | /* [] */0
19 | ]
20 | ]),
21 | /* :: */[
22 | Css.gridColumnGap(Css.px(15)),
23 | /* :: */[
24 | Css.alignItems(Css.center),
25 | /* [] */0
26 | ]
27 | ]
28 | ]
29 | ]
30 | ]
31 | ]);
32 |
33 | var Styles = /* module */[/* wrapper */wrapper];
34 |
35 | function SplitLayout(Props) {
36 | var children = Props.children;
37 | return React.createElement("div", {
38 | className: wrapper
39 | }, children);
40 | }
41 |
42 | var make = SplitLayout;
43 |
44 | var $$default = SplitLayout;
45 |
46 | exports.Styles = Styles;
47 | exports.make = make;
48 | exports.$$default = $$default;
49 | exports.default = $$default;
50 | exports.__esModule = true;
51 | /* wrapper Not a pure module */
52 |
--------------------------------------------------------------------------------
/src/juice/SplitLayout.re:
--------------------------------------------------------------------------------
1 | module Styles = {
2 | open Css;
3 |
4 | let wrapper = style([
5 | width(pct(100.)),
6 | height(pct(100.)),
7 | display(grid),
8 | gridTemplateColumns([fr(1.), fr(1.)]),
9 | gridColumnGap(px(15)),
10 | alignItems(center)
11 | ])
12 | };
13 |
14 |
15 | [@react.component]
16 | let make = (~children) => {
17 |
18 | children
19 |
20 | }
21 |
22 | let default = make
23 |
--------------------------------------------------------------------------------
/src/juice/Title.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import styled, {css, keyframes} from 'styled-components'
3 |
4 | // inspired from https://css-tricks.com/glitch-effect-text-images-svg/
5 |
6 | // const skewDistortion = `transform: skew(${Math.random() * 20 * (Math.random() > 0.5 ? -1 : 1)}deg)`
7 | const noiseAnimationSteps = 20;
8 | const noiseAnimation = keyframes`
9 | ${
10 | Array.from({length: noiseAnimationSteps}).map((_, index) => {
11 | const top = (Math.random() * 100);
12 | const bottom= Math.random() * (101 - top);
13 | return `
14 | ${Math.floor( index * 1/20 * 100 )}% {
15 | clip-path: inset(${top}% 0 ${bottom}% 0);
16 | }
17 | `}).join('')
18 | }
19 | `
20 |
21 | const glitchColor1 = 'red'
22 | const glitchColor2 = 'yellow'
23 | const backgroundColor = 'white'
24 | const textColor = 'black'
25 |
26 | const Wrapper = styled.div`
27 | background-color: ${backgroundColor};
28 | padding-left: 30px;
29 | padding-right: 30px;
30 | `
31 |
32 | const Glitch = styled.h2.attrs(({children}) => ({
33 | 'data-text': children,
34 | }))`
35 | text-align: center;
36 | position: relative;
37 | color: ${textColor};
38 | background-color: ${backgroundColor};
39 | font-style: italic;
40 | font-size: ${props => props.variant === "featured" ? "10rem" : "auto" }
41 |
42 | &::after, &::before {
43 | content: attr(data-text);
44 | position: absolute;
45 | top: 0;
46 | left: 0;
47 | width: 100%;
48 | height: 100%;
49 | }
50 |
51 | &::before {
52 | left: 2px;
53 | text-shadow: -2px 0 ${glitchColor1};
54 | animation: ${noiseAnimation} 4s infinite linear alternate-reverse;
55 | background-color: ${backgroundColor};
56 | color: ${textColor};
57 | }
58 |
59 | &::after {
60 | ${props => (props.glitchText1 ? css`content: "${props => props.glitchText1}";` : null )}
61 | left: -2px;
62 | text-shadow: 2px 0 ${glitchColor2};
63 | background-color: ${backgroundColor};
64 | color: ${textColor};
65 | animation: ${noiseAnimation} 4s infinite linear alternate-reverse;
66 | }
67 | `
68 |
69 | export const Title = ({ children, ...props }) => {
70 | return (
71 |
72 | {children}
73 |
74 | )
75 | }
76 |
--------------------------------------------------------------------------------
/src/juice/VideoBackground.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 5.0.6, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var Css = require("bs-css/src/Css.js");
5 | var React = require("react");
6 |
7 | var wrapper = Css.style(/* :: */[
8 | Css.height(Css.pct(100)),
9 | /* :: */[
10 | Css.width(Css.pct(100)),
11 | /* [] */0
12 | ]
13 | ]);
14 |
15 | var Styles = /* module */[/* wrapper */wrapper];
16 |
17 | function VideoBackground(Props) {
18 | var src = Props.src;
19 | return React.createElement("video", {
20 | className: wrapper,
21 | autoPlay: true,
22 | loop: true,
23 | muted: true
24 | }, React.createElement("source", {
25 | src: src,
26 | type: "video/mp4"
27 | }));
28 | }
29 |
30 | var make = VideoBackground;
31 |
32 | var $$default = VideoBackground;
33 |
34 | exports.Styles = Styles;
35 | exports.make = make;
36 | exports.$$default = $$default;
37 | exports.default = $$default;
38 | exports.__esModule = true;
39 | /* wrapper Not a pure module */
40 |
--------------------------------------------------------------------------------
/src/juice/VideoBackground.re:
--------------------------------------------------------------------------------
1 | module Styles = {
2 | open Css;
3 |
4 | let wrapper = style([
5 | height(pct(100.)),
6 | width(pct(100.))
7 | ])
8 | }
9 |
10 | [@react.component]
11 | let make = (~src) => {
12 |
15 | };
16 |
17 | let default = make
18 |
--------------------------------------------------------------------------------
/src/snippets/GraphQLDemo.graphql:
--------------------------------------------------------------------------------
1 | enum UserRoleEnum { ADMIN, OPERATOR }
2 |
3 | type User {
4 | name: String!
5 | role: UserRoleEnum!
6 | }
7 |
8 | type Query {
9 | me: User
10 | }
11 |
--------------------------------------------------------------------------------
/src/snippets/GraphQLDemo.re:
--------------------------------------------------------------------------------
1 | module UserQuery = [%graphql {|
2 | query UserQuery {
3 | currentUser {
4 | name
5 | role
6 | }
7 | }
8 | |}];
9 |
10 | [@react.component]
11 | let make = () => {
12 | let (result, _) = ReasonApolloHooks.useQuery(UserQuery.make());
13 |
14 | switch(result) {
15 | | Loading => {React.string("Loading...")}
16 | | Data(data) =>
17 | switch(data##currentUser) {
18 | | Some(user) =>
19 | switch(user##role) {
20 | | `ADMIN => {React.string("Hello admin")}
21 | | `OPERATOR => {React.string("Hello operator")}
22 | }
23 | | None => {React.string("Not logged in")}
24 | }
25 | | Error(_)
26 | | NoData(_) => {React.string("Something went wrong")}
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/src/snippets/PatternMatchingDemo.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 5.0.6, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var React = require("react");
5 | var Belt_Array = require("bs-platform/lib/js/belt_Array.js");
6 |
7 | function PatternMatchingDemo(Props) {
8 | var result = Props.result;
9 | var status = Props.status;
10 | if (status) {
11 | return React.createElement("p", undefined, "Unavailable.");
12 | } else if (typeof result === "number") {
13 | return React.createElement("p", undefined, "Loading...");
14 | } else if (result.tag) {
15 | var list = result[0];
16 | if (list.length !== 0) {
17 | return React.createElement("ul", undefined, Belt_Array.map(list, (function (item) {
18 | return React.createElement("li", undefined, item);
19 | })));
20 | } else {
21 | return React.createElement("p", undefined, "List is empty!");
22 | }
23 | } else {
24 | return React.createElement("p", undefined, "Something went wrong: " + result[0]);
25 | }
26 | }
27 |
28 | var make = PatternMatchingDemo;
29 |
30 | exports.make = make;
31 | /* react Not a pure module */
32 |
--------------------------------------------------------------------------------
/src/snippets/PatternMatchingDemo.re:
--------------------------------------------------------------------------------
1 | type result = | Loading | Error(string) | Data(array(string));
2 | type status = | Enabled | Disabled;
3 |
4 | [@react.component]
5 | let make = (~result, ~status) => {
6 | switch(status, result) {
7 | | (Enabled, Loading) => {React.string("Loading...")}
8 | | (Enabled, Error(error)) => {React.string("Something went wrong: " ++ error)}
9 | | (Enabled, Data([||])) => {React.string("List is empty!")}
10 | | (Enabled, Data(list)) =>
11 | {list->Belt.Array.map(item => - {React.string(item)}
)->React.array}
12 | | (Disabled, _) => {React.string("Unavailable.")}
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/snippets/PatternMatchingDemo.ts:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 |
3 | interface Result {
4 | loading: boolean;
5 | error: string | null;
6 | data: string[] | null;
7 | }
8 |
9 | interface Props {
10 | result: Result;
11 | enabled: boolean;
12 | }
13 |
14 | export const List = ({ result, enabled }: Props) => {
15 | if(enabled) return Unavailable
16 | else {
17 | if(result.loading) return Loading
18 | if(result.data.length == []) return List is empty!
19 | if(result.data) return (
20 | {result.data.map(item => - {item}
)}
21 | )
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/snippets/PatternMatchingDemo2.ts:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 |
3 | interface Result {
4 | loading: boolean;
5 | error: string | null;
6 | data: string[] | null;
7 | }
8 |
9 | interface Props {
10 | result: Result;
11 | enabled: boolean;
12 | }
13 |
14 | export const List = ({ result, enabled }: Props) => {
15 | if(enabled) return Unavailable
16 | else {
17 | if(result.loading) return Loading
18 | if(result.data || result.data.length === 0) return List is empty!
19 | if(result.data) return (
20 | {result.data.map(item => - {item}
)}
21 | )
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/snippets/PatternMatchingDemo3.ts:
--------------------------------------------------------------------------------
1 | import * as React from 'react'
2 |
3 | interface Result {
4 | loading: boolean;
5 | error: string | null;
6 | data: string[] | null;
7 | }
8 |
9 | interface Props {
10 | result: Result;
11 | enabled: boolean;
12 | }
13 |
14 | export const List = ({ result, enabled }: Props) => {
15 | if(!enabled) return Unavailable
16 | else {
17 | if(result.error) return {error}
18 | if(result.loading) return Loading...
19 | if(result.data || result.data.length === 0) return List is empty!
20 | if(result.data) return (
21 | {result.data.map(item => - {item}
)}
22 | )
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/snippets/PatternMatchingDemoError.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 5.0.6, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 | var React = require("react");
5 | var Belt_Array = require("bs-platform/lib/js/belt_Array.js");
6 | var Caml_builtin_exceptions = require("bs-platform/lib/js/caml_builtin_exceptions.js");
7 |
8 | function PatternMatchingDemoError(Props) {
9 | var result = Props.result;
10 | var status = Props.status;
11 | if (status) {
12 | return React.createElement("p", undefined, "Unavailable.");
13 | } else if (typeof result === "number") {
14 | return React.createElement("p", undefined, "Loading...");
15 | } else if (result.tag) {
16 | var list = result[0];
17 | if (list.length !== 0) {
18 | return React.createElement("ul", undefined, Belt_Array.map(list, (function (item) {
19 | return React.createElement("li", undefined, item);
20 | })));
21 | } else {
22 | return React.createElement("p", undefined, "List is empty!");
23 | }
24 | } else {
25 | throw [
26 | Caml_builtin_exceptions.match_failure,
27 | /* tuple */[
28 | "_none_",
29 | 1,
30 | -1
31 | ]
32 | ];
33 | }
34 | }
35 |
36 | var make = PatternMatchingDemoError;
37 |
38 | exports.make = make;
39 | /* react Not a pure module */
40 |
--------------------------------------------------------------------------------
/src/snippets/PatternMatchingDemoError.re:
--------------------------------------------------------------------------------
1 | type result = | Loading | Error(string) | Data(array(string));
2 | type status = | Enabled | Disabled;
3 |
4 | [@react.component]
5 | let make = (~result, ~status) => {
6 | /* You forgot to handle a possible case here, for example: (Enabled, Error _) */
7 | switch(status, result) {
8 | | (Enabled, Loading) => {React.string("Loading...")}
9 | | (Enabled, Data([||])) => {React.string("List is empty!")}
10 | | (Enabled, Data(list)) =>
11 | {list->Belt.Array.map(item => - {React.string(item)}
)->React.array}
12 | | (Disabled, _) => {React.string("Unavailable.")}
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/snippets/VariantDemo.bs.js:
--------------------------------------------------------------------------------
1 | // Generated by BUCKLESCRIPT VERSION 5.0.6, PLEASE EDIT WITH CARE
2 | 'use strict';
3 |
4 |
5 | function greeting(person) {
6 | if (typeof person === "number") {
7 | if (person !== 0) {
8 | return "Hello Director.";
9 | } else {
10 | return "Hey Professor!";
11 | }
12 | } else {
13 | var anyOtherName = person[0];
14 | if (anyOtherName === "Richard") {
15 | return "Still here Ricky?";
16 | } else {
17 | return "Hey, " + (anyOtherName + ".");
18 | }
19 | }
20 | }
21 |
22 | exports.greeting = greeting;
23 | /* No side effect */
24 |
--------------------------------------------------------------------------------
/src/snippets/VariantDemo.re:
--------------------------------------------------------------------------------
1 | type schoolPerson = Teacher | Director | Student(string);
2 |
3 | let greeting = person =>
4 | switch (person) {
5 | | Teacher => "Hey Professor!"
6 | | Director => "Hello Director."
7 | | Student("Richard") => "Still here Ricky?"
8 | | Student(anyOtherName) => "Hey, " ++ anyOtherName ++ "."
9 | };
10 |
--------------------------------------------------------------------------------
/src/snippets/VariantDemoSwitch.ts:
--------------------------------------------------------------------------------
1 | let greeting = (person: Person) => {
2 | switch (person.kind) {
3 | case SchoolPersonEnum.Teacher:
4 | return "Hey Professor!"
5 | case SchoolPersonEnum.Director:
6 | return "Hello Director."
7 | case SchoolPersonEnum.Student:
8 | if(person.name === "Richard") return "Still here Ricky?"
9 | else return `Hey, ${person.name}.`
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/snippets/VariantDemoTypes.ts:
--------------------------------------------------------------------------------
1 | enum SchoolPersonEnum {
2 | Teacher,
3 | Director,
4 | Student
5 | }
6 |
7 | interface Person {
8 | kind: SchoolPersonEnum
9 | name?: string;
10 | }
11 |
--------------------------------------------------------------------------------