Reason React Native Styled System (Beta)
Last active
April 29, 2019 19:32
-
-
Save hew/3d2b8c00b62e58fd45fb73fefc71d203 to your computer and use it in GitHub Desktop.
Reason React Native Styled System (Beta)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[@bs.module "react-native-responsive-fontsize"] | |
external rf: float => float = "default"; | |
module type Config = {let scale: array(int);}; | |
module TextMaker = (Config: Config) => { | |
open Belt.Option; | |
let systemize = shorthand => | |
shorthand->mapWithDefault(0, m => | |
switch (m) { | |
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 => Config.scale[m] | |
| _ => m | |
} | |
) | |
|> float_of_int; | |
let systemizeFont = v => | |
v->mapWithDefault(16, m => | |
switch (m) { | |
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 => Config.scale[m] | |
| _ => m | |
} | |
) | |
|> float_of_int; | |
let systemizeSize = v => v |> systemize |> Style.Size.pct; | |
let systemizeMargin = v => v |> systemize |> Style.Margin.pct; | |
[@react.component] | |
let make = | |
( | |
~py=?, | |
~px=?, | |
~p=?, | |
~mt=?, | |
~mb=?, | |
~ml=?, | |
~mr=?, | |
~size=?, | |
~style as styl: Style.t=?, | |
~color as clr=?, | |
~weight=?, | |
~align=?, | |
~children, | |
(), | |
) => | |
<Text | |
style=Style.( | |
listOption([ | |
mt->isSome | |
? Some(style(~marginTop=systemizeMargin(mt), ())) : None, | |
mb->isSome | |
? Some(style(~marginBottom=systemizeMargin(mb), ())) : None, | |
ml->isSome | |
? Some(style(~marginLeft=systemizeMargin(ml), ())) : None, | |
mr->isSome | |
? Some(style(~marginRight=systemizeMargin(mr), ())) : None, | |
p->isSome ? Some(style(~padding=systemizeSize(p), ())) : None, | |
py->isSome | |
? Some(style(~paddingTop=systemizeSize(py), ())) : None, | |
py->isSome | |
? Some(style(~paddingBottom=systemizeSize(py), ())) : None, | |
px->isSome | |
? Some(style(~paddingLeft=systemizeSize(px), ())) : None, | |
px->isSome | |
? Some(style(~paddingRight=systemizeSize(px), ())) : None, | |
size->isSome | |
? Some(style(~fontSize=systemizeFont(size), ())) : None, | |
clr->isSome | |
? Some( | |
style( | |
~color=clr->mapWithDefault("black", v => v) |> color, | |
(), | |
), | |
) | |
: None, | |
weight->isSome | |
? Some( | |
style( | |
~fontWeight=weight->mapWithDefault(`normal, w => w), | |
(), | |
), | |
) | |
: None, | |
align->isSome | |
? Some( | |
style(~textAlign=align->mapWithDefault(`center, w => w), ()), | |
) | |
: None, | |
Some(styl), | |
]) | |
)> | |
children | |
</Text>; | |
}; | |
module BoxMaker = (Config: Config) => { | |
open Belt.Option; | |
let systemize = shorthand => | |
shorthand->mapWithDefault(0, m => | |
switch (m) { | |
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 => Config.scale[m] | |
| _ => m | |
} | |
) | |
|> float_of_int; | |
let systemizeSize = v => v |> systemize |> rf |> Style.Size.pt; | |
let systemizeMargin = v => v |> systemize |> rf |> Style.Margin.pt; | |
[@react.component] | |
let make = | |
( | |
~py=?, | |
~px=?, | |
~p=?, | |
~mt=?, | |
~mb=?, | |
~ml=?, | |
~mr=?, | |
~bgColor=?, | |
~width=?, | |
~flex=?, | |
~content=?, | |
~direction=?, | |
~style as styl: Style.t=?, | |
~children=?, | |
(), | |
) => | |
<View | |
style=Style.( | |
listOption([ | |
mt->isSome | |
? Some(style(~marginTop=systemizeMargin(mt), ())) : None, | |
mb->isSome | |
? Some(style(~marginBottom=systemizeMargin(mb), ())) : None, | |
ml->isSome | |
? Some(style(~marginLeft=systemizeMargin(ml), ())) : None, | |
mr->isSome | |
? Some(style(~marginRight=systemizeMargin(mr), ())) : None, | |
p->isSome ? Some(style(~padding=systemizeSize(p), ())) : None, | |
py->isSome | |
? Some(style(~paddingTop=systemizeSize(py), ())) : None, | |
py->isSome | |
? Some(style(~paddingBottom=systemizeSize(py), ())) : None, | |
px->isSome | |
? Some(style(~paddingLeft=systemizeSize(px), ())) : None, | |
px->isSome | |
? Some(style(~paddingRight=systemizeSize(px), ())) : None, | |
width->isSome | |
? Some( | |
style( | |
~width=width->mapWithDefault(100., v => v) |> Size.pct, | |
(), | |
), | |
) | |
: None, | |
bgColor->isSome | |
? Some( | |
style( | |
~backgroundColor= | |
bgColor->mapWithDefault("black", v => v) |> color, | |
(), | |
), | |
) | |
: None, | |
content->isSome | |
? Some( | |
style( | |
~justifyContent=content->mapWithDefault(`flexStart, w => w), | |
(), | |
), | |
) | |
: None, | |
direction->isSome | |
? Some( | |
style( | |
~flexDirection=direction->mapWithDefault(`column, w => w), | |
(), | |
), | |
) | |
: None, | |
flex->isSome | |
? Some(style(~flex=flex->mapWithDefault(1., w => w), ())) : None, | |
Some(styl), | |
]) | |
)> | |
{switch (children) { | |
| Some(child) => child | |
| None => React.null | |
}} | |
</View>; | |
}; | |
module Box = | |
BoxMaker({ | |
let scale = System.Scale.space; | |
}); | |
module Txt = | |
TextMaker({ | |
let scale = System.Scale.font; | |
}); |
I think I understand now. the global open only adds like 4 more things to the namespace, but Belt.Option
has a bunch of functions, and opening it floods any given namespace with all of them. I'll default to something like let Opt = Belt.Option in the future.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@hew Yes, this flag is sometimes used to 'overlay' a new set of standard modules on top of the built-in ones that are available in OCaml. Typically it's desirable to
open
modules which will have as little effect on the global namespace as possible. So,open Belt
is not too bad because it brings a small number of top-level modules into scope (as seen in https://bucklescript.github.io/bucklescript/api/Belt.html ). Butopen Belt.Option
is a bit more frowned on because it will bring a large number of functions into scope. And at module scope it will pollute your namespace with lots of names. The more this is done, the harder it is to track where names are coming from and you have to keep referring to other parts of the code when you're reading some function, to figure it out.