Skip to content

Instantly share code, notes, and snippets.

@hew
Last active January 18, 2019 05:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hew/9ccf4932771ff648aa731966de95ddb3 to your computer and use it in GitHub Desktop.
Save hew/9ccf4932771ff648aa731966de95ddb3 to your computer and use it in GitHub Desktop.
Variant Types Example

reasonml box component

open Rebolt; /* or BsReactNative */
open Style;
/* This isn't represented very well. It's taken from "get it done" production code. */
/* But it illustates the idea of how to use variant types. */
module Box =
Restyled.BoxView(
{
type paddingType = [ | `p(float) | `px(float) | `py(float)];
type marginType = [
| `mt(float)
| `mb(float)
| `mr(float)
| `ml(float)
];
let baseStyle = [] /*display(Flex) hmmmm */;
let getPaddStyle = spaceType =>
switch (spaceType) {
| `p(p) => [padding(Pct(p))]
| `px(p) => [paddingRight(Pct(p)), paddingLeft(Pct(p))]
| `py(p) => [paddingTop(Pct(p)), paddingBottom(Pct(p))]
};
let getMargStyle = marginType =>
switch (marginType) {
| `mt(m) => [marginTop(Pct(m))]
| `mb(m) => [marginBottom(Pct(m))]
| `mr(m) => [marginRight(Pct(m))]
| `ml(m) => [marginLeft(Pct(m))]
};
let paddingStyle = spaceType =>
switch (spaceType) {
| Some(spaceType) => getPaddStyle(spaceType)
| None => baseStyle
};
let marginStyle = marginType =>
switch (marginType) {
| Some(marginType) => getMargStyle(marginType)
| None => baseStyle
};
let bgColorStyle = bg =>
switch (bg) {
| Some(bg) => [backgroundColor(String(bg))]
| None => []
};
let style = (paddingType, marginType, bgColor) =>
style(
List.append(
List.flatten([
marginStyle(marginType),
paddingStyle(paddingType),
bgColorStyle(bgColor),
]),
baseStyle,
),
);
},
);
/* Here, we are applying "1.5 margin left", into the m/margin prop. The variant type means 1.5 can */
/* be implemented as however we want, which is the power of this kind of abtraction. (I use `Pct` as seen above) */
<Box m={`ml(1.5)}>
<ClickText
title="Signup here."
onPress={_evt => navigation.push(Config.SignUp)}
/>
</Box>
open Rebolt;
let get = (arg, default) =>
switch (arg) {
| None => default
| Some(value) => value
};
module type BoxConfig = {
type paddingType;
type marginType;
let style:
(option(paddingType), option(marginType), option(string)) => Style.t;
};
module BoxView = (Config: BoxConfig) => {
let make =
(~p=?, ~m=?, ~bgColor=?, ~style as additionalStyle=Style.(style([]))) =>
View.make(
~style=Style.combine(Config.style(p, m, bgColor), additionalStyle),
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment