Skip to content

Commit 4001fd1

Browse files
authored
Zero cost bindings for style merge (array/list) (react#347)
* Zero cost bindings for style merge (array/list) RN accept works out of the box array of styles (object|int from StyleSheet entries). It also recursively resolve the array of styles, so list should work too (as list are just recursive array). I tried to find "smart" name but at the end, using merge/flatten/combine/concat just make this more confusing. I am deprecating combine/merge as this is totally unsafe IRL (you cannot merge object of style with a stylesheet entry, which works with current types...) Thoughts? Idea for better naming? * bs-react-native-next: Remove StyleSheet.flatten in Style module * Zero cost bindings for style merge (array/list) fixup
1 parent 67ae8f5 commit 4001fd1

5 files changed

Lines changed: 114 additions & 61 deletions

File tree

bs-react-native-example/src/pages/ViewExample.re

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ module ZIndexExample = {
106106
{ReasonReact.string("Tap to flip sorting order")}
107107
</Text>
108108
<View
109-
style={fromList([
109+
style={list([
110110
styles##zIndex,
111111
style([
112112
marginTop(Pt(0.)),
@@ -117,7 +117,7 @@ module ZIndexExample = {
117117
<Text> {ReasonReact.string(zIndexStr(0))} </Text>
118118
</View>
119119
<View
120-
style={fromList([
120+
style={list([
121121
styles##zIndex,
122122
style([
123123
marginLeft(Pt(50.)),
@@ -128,7 +128,7 @@ module ZIndexExample = {
128128
<Text> {ReasonReact.string(zIndexStr(1))} </Text>
129129
</View>
130130
<View
131-
style={fromList([
131+
style={list([
132132
styles##zIndex,
133133
style([
134134
marginLeft(Pt(100.)),
@@ -139,7 +139,7 @@ module ZIndexExample = {
139139
<Text> {ReasonReact.string(zIndexStr(2))} </Text>
140140
</View>
141141
<View
142-
style={fromList([
142+
style={list([
143143
styles##zIndex,
144144
style([
145145
marginLeft(Pt(150.)),
@@ -204,19 +204,18 @@ let examples: array(Example.t) =
204204
borderColor(String("#bb0000")),
205205
borderWidth(1.),
206206
])}>
207-
<View
208-
style={fromList([styles##box, style([padding(Pt(5.))])])}>
207+
<View style={list([styles##box, style([padding(Pt(5.))])])}>
209208
<Text style={style([fontSize(Float(11.))])}>
210209
{ReasonReact.string("5px padding")}
211210
</Text>
212211
</View>
213-
<View style={fromList([styles##box, style([margin(Pt(5.))])])}>
212+
<View style={list([styles##box, style([margin(Pt(5.))])])}>
214213
<Text style={style([fontSize(Float(11.))])}>
215214
{ReasonReact.string("5px margin")}
216215
</Text>
217216
</View>
218217
<View
219-
style={fromList([
218+
style={list([
220219
styles##box,
221220
style([
222221
margin(Pt(5.)),

bs-react-native-next/src/Style.re

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,39 @@ external style:
252252
t =
253253
"";
254254

255-
// Duplicated from StyleSheet.re for convenience.
256-
[@bs.module "react-native"] [@bs.scope "StyleSheet"]
257-
external flatten: array(t) => t = "";
255+
/*
256+
<View style=array([|
257+
styles##thing,
258+
styles##whatever,
259+
|])>
260+
*/
261+
external array: array(t) => t = "%identity";
262+
263+
/*
264+
<View style=arrayOption([|
265+
Some(styles##thing),
266+
Some(styles##whatever),
267+
optionalStyle,
268+
cond ? Some({something:"dynamic"}) : None
269+
|])>
270+
*/
271+
external arrayOption: array(option(t)) => t = "%identity";
272+
273+
/* list works too since RN accept recursive array of styles (list are just recursive arrays)*/
274+
/*
275+
<View style=list([
276+
styles##thing,
277+
styles##whatever,
278+
])>
279+
*/
280+
external list: list(t) => t = "%identity";
281+
282+
/*
283+
<View style=listOption([
284+
Some(styles##thing),
285+
Some(styles##whatever),
286+
optionalStyle,
287+
cond ? Some({something:"dynamic"}) : None
288+
])>
289+
*/
290+
external listOption: list(option(t)) => t = "%identity";

bs-react-native/src/style.bs.js

Lines changed: 23 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bs-react-native/src/style.re

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -81,27 +81,23 @@ let objectStyle = (key, value) => (key, Internals.Encoder.object_(value));
8181
let arrayStyle = (key, value) => (key, Internals.Encoder.array(value));
8282

8383
let style = sarr => sarr |> Js.Dict.fromList |> to_style;
84-
let emptyStyle = Js.Dict.empty()->to_style;
8584

86-
external fromArray: array(t) => t = "%identity";
87-
let fromList = styles => styles->Belt.List.toArray->arrayOfStyle;
88-
let merge = (a, b) => {
85+
external array: array(t) => t = "%identity";
86+
external arrayOption: array(option(t)) => t = "%identity";
87+
external list: list(t) => t = "%identity";
88+
external listOption: list(option(t)) => t = "%identity";
89+
90+
/* deprecated */
91+
let flatten = array;
92+
let concat = styles => styles->Belt.List.toArray->arrayOfStyle;
93+
let combine = (a, b) => {
8994
let entries =
9095
Array.append(
9196
Js.Dict.entries(style_to_dict(a)),
9297
Js.Dict.entries(style_to_dict(b)),
9398
);
9499
Js.Dict.fromArray(entries) |> to_style;
95100
};
96-
let mergeOptional = (s, so) =>
97-
so->Belt.Option.map(so => s->merge(so))->Belt.Option.getWithDefault(s);
98-
let optional = s => s->Belt.Option.getWithDefault(emptyStyle);
99-
100-
/* deprecated */
101-
let flatten = fromArray;
102-
let concat = fromList;
103-
let combine = merge;
104-
let combineOptional = mergeOptional;
105101

106102
/***
107103
* Layout Props

bs-react-native/src/style.rei

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,48 @@ type deg_animated('a) =
2525
| Animated(AnimatedRe.value('a));
2626

2727
let style: list(styleElement) => t;
28-
external fromArray: array(t) => t = "%identity";
29-
let fromList: list(t) => t;
30-
let merge: (t, t) => t;
31-
let mergeOptional: (t, option(t)) => t;
32-
let optional: option(t) => t;
3328

34-
[@deprecated "use Style.fromArray([|t|]) instead"]
29+
/*
30+
<View style=array([|
31+
styles##thing,
32+
styles##whatever,
33+
|])>
34+
*/
35+
let array: array(t) => t;
36+
/*
37+
<View style=arrayOption([|
38+
Some(styles##thing),
39+
Some(styles##whatever),
40+
optionalStyle,
41+
cond ? Some({something:"dynamic"}) : None
42+
|])>
43+
*/
44+
let arrayOption: array(option(t)) => t;
45+
/* list works too since RN accept recursive array of styles (list are just recursive arrays)*/
46+
/*
47+
<View style=list([
48+
styles##thing,
49+
styles##whatever,
50+
])>
51+
*/
52+
let list: list(t) => t;
53+
/*
54+
<View style=listOption([
55+
Some(styles##thing),
56+
Some(styles##whatever),
57+
optionalStyle,
58+
cond ? Some({something:"dynamic"}) : None
59+
])>
60+
*/
61+
let listOption: list(option(t)) => t;
62+
[@deprecated "Use Style.array([|t|]) instead"]
3563
let flatten: array(t) => t;
36-
[@deprecated "use Style.merge(t, t) instead"]
37-
let combine: (t, t) => t;
38-
[@deprecated "use Style.fromList([t]) instead"]
64+
[@deprecated "Use Style.list([t]) instead"]
3965
let concat: list(t) => t;
40-
[@deprecated "use Style.mergeOptional(t, option(t)) instead"]
41-
let combineOptional: (t, option(t)) => t;
66+
[@deprecated
67+
"This method is unsafe as it doesn't work well with StyleSheet values."
68+
]
69+
let combine: (t, t) => t;
4270

4371
type alignContent =
4472
| FlexStart

0 commit comments

Comments
 (0)