Skip to content

Commit 51f599a

Browse files
committed
Render utils
1 parent 4788eb9 commit 51f599a

File tree

3 files changed

+306
-3
lines changed

3 files changed

+306
-3
lines changed

README.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,27 @@ See [Relude IO documentation](https://reazen.github.io/relude/#/api/IO) for more
113113

114114
### `ReludeReact.Render` utilities
115115

116-
TODO
116+
`ReludeReact.Render` contains a variety of useful functions for rendering different data types, to avoid extra boilerplate/noise in your components. See the code for details.
117+
118+
```reason
119+
ReludeReact.Render.ifTrue
120+
ReludeReact.Render.ifTrueLazy
121+
ReludeReact.Render.option
122+
ReludeReact.Render.optionLazy
123+
ReludeReact.Render.optionIfSome
124+
ReludeReact.Render.result
125+
ReludeReact.Render.resultIfOk
126+
ReludeReact.Render.resultIfError
127+
ReludeReact.Render.asyncData
128+
ReludeReact.Render.asyncDataLazy
129+
ReludeReact.Render.asyncDataByValue
130+
ReludeReact.Render.asyncDataLazyByValue
131+
ReludeReact.Render.asyncResult
132+
ReludeReact.Render.asyncResultLazy
133+
ReludeReact.Render.asyncResultByValue
134+
ReludeReact.Render.asyncResultLazyByValue
135+
// etc.
136+
```
117137

118138
## Examples
119139

src/ReludeReact.re

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
module SideEffect = ReludeReact_SideEffect;
2-
module Reducer = ReludeReact_Reducer;
31
module Effect = ReludeReact_Effect;
2+
module Reducer = ReludeReact_Reducer;
3+
module Render = ReludeReact_Render;
4+
module SideEffect = ReludeReact_SideEffect;

src/ReludeReact_Render.re

Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
/**
2+
Returns an element if the condition is true, otherwise React.null
3+
*/
4+
let ifTrue: (bool, React.element) => React.element =
5+
(condition, element) => if (condition) {element} else {React.null};
6+
7+
/**
8+
Renders an element if the condition is true, otherwise React.null
9+
*/
10+
let ifTrueLazy: (bool, unit => React.element) => React.element =
11+
(condition, element) =>
12+
if (condition) {
13+
element();
14+
} else {
15+
React.null;
16+
};
17+
18+
/**
19+
Renders an option with a None element or render fucntion for Some
20+
*/
21+
let option:
22+
'a.
23+
(option('a), React.element, 'a => React.element) => React.element
24+
=
25+
(opt, noneElement, someElement) =>
26+
switch (opt) {
27+
| None => noneElement
28+
| Some(a) => someElement(a)
29+
};
30+
31+
/**
32+
Renders an option with render functions for None and Some
33+
*/
34+
let optionLazy:
35+
'a.
36+
(option('a), unit => React.element, 'a => React.element) => React.element
37+
=
38+
(opt, noneElement, someElement) =>
39+
switch (opt) {
40+
| None => noneElement()
41+
| Some(a) => someElement(a)
42+
};
43+
44+
/**
45+
Renders an option with a render function for Some, otherwise React.null
46+
*/
47+
let optionIfSome: 'a. (option('a), 'a => React.element) => React.element =
48+
(opt, someElement) =>
49+
switch (opt) {
50+
| None => React.null
51+
| Some(a) => someElement(a)
52+
};
53+
54+
/**
55+
Renders a Belt.Result.t('a, 'e), with render functions for both channels
56+
*/
57+
let result:
58+
'a 'e.
59+
(Belt.Result.t('a, 'e), 'a => React.element, 'e => React.element) =>
60+
React.element
61+
=
62+
(result, okElement, errorElement) =>
63+
switch (result) {
64+
| Ok(a) => okElement(a)
65+
| Error(e) => errorElement(e)
66+
};
67+
68+
/**
69+
Renders a Belt.Result.t('a, 'e), with a render function for the Ok channel, otherwise React.null
70+
*/
71+
let resultIfOk:
72+
'a 'e.
73+
(Belt.Result.t('a, 'e), 'a => React.element) => React.element
74+
=
75+
(result, okElement) =>
76+
switch (result) {
77+
| Ok(a) => okElement(a)
78+
| Error(_) => React.null
79+
};
80+
81+
/**
82+
Renders a Belt.Result.t('a, 'e), with a render function for the Error channel, otherwise React.null
83+
*/
84+
let resultIfError:
85+
'a 'e.
86+
(Belt.Result.t('a, 'e), 'e => React.element) => React.element
87+
=
88+
(result, errorElement) =>
89+
switch (result) {
90+
| Ok(_) => React.null
91+
| Error(e) => errorElement(e)
92+
};
93+
94+
/**
95+
Renders a Relude.AsyncData value by providing an element/render function for each case
96+
*/
97+
let asyncData:
98+
'a.
99+
(
100+
Relude.AsyncData.t('a),
101+
React.element,
102+
React.element,
103+
'a => React.element,
104+
'a => React.element
105+
) =>
106+
React.element
107+
=
108+
(data, initElement, loadingElement, reloadingElement, completeElement) =>
109+
switch (data) {
110+
| Init => initElement
111+
| Loading => loadingElement
112+
| Reloading(a) => reloadingElement(a)
113+
| Complete(a) => completeElement(a)
114+
};
115+
116+
/**
117+
Renders a Relude.AsyncData value by providing a render function for each case
118+
*/
119+
let asyncDataLazy:
120+
'a.
121+
(
122+
Relude.AsyncData.t('a),
123+
unit => React.element,
124+
unit => React.element,
125+
'a => React.element,
126+
'a => React.element
127+
) =>
128+
React.element
129+
=
130+
(data, initElement, loadingElement, reloadingElement, completeElement) =>
131+
switch (data) {
132+
| Init => initElement()
133+
| Loading => loadingElement()
134+
| Reloading(a) => reloadingElement(a)
135+
| Complete(a) => completeElement(a)
136+
};
137+
138+
/**
139+
Renders a Relude.AsyncData value by providing an element/render function for each type of same-type value
140+
*/
141+
let asyncDataByValue:
142+
'a.
143+
(Relude.AsyncData.t('a), React.element, 'a => React.element) =>
144+
React.element
145+
=
146+
(data, initOrLoadingElement, valueElement) =>
147+
switch (data) {
148+
| Init
149+
| Loading => initOrLoadingElement
150+
| Reloading(a)
151+
| Complete(a) => valueElement(a)
152+
};
153+
154+
/**
155+
Renders a Relude.AsyncData value by providing a render function for each type of same-type value
156+
*/
157+
let asyncDataByValueLazy:
158+
'a.
159+
(Relude.AsyncData.t('a), unit => React.element, 'a => React.element) =>
160+
React.element
161+
=
162+
(data, initOrLoadingElement, valueElement) =>
163+
switch (data) {
164+
| Init
165+
| Loading => initOrLoadingElement()
166+
| Reloading(a)
167+
| Complete(a) => valueElement(a)
168+
};
169+
170+
/**
171+
Renders a Relude.AsyncResult value by providing an element/render function for each case
172+
*/
173+
let asyncResult:
174+
'a 'e.
175+
(
176+
Relude.AsyncResult.t('a, 'e),
177+
React.element,
178+
React.element,
179+
'a => React.element,
180+
'e => React.element,
181+
'a => React.element,
182+
'e => React.element
183+
) =>
184+
React.element
185+
=
186+
(
187+
result,
188+
initElement,
189+
loadingElement,
190+
reloadingOkElement,
191+
reloadingErrorElement,
192+
completeOkElement,
193+
completeErrorElement,
194+
) =>
195+
switch (result) {
196+
| Init => initElement
197+
| Loading => loadingElement
198+
| Reloading(Ok(a)) => reloadingOkElement(a)
199+
| Reloading(Error(e)) => reloadingErrorElement(e)
200+
| Complete(Ok(a)) => completeOkElement(a)
201+
| Complete(Error(e)) => completeErrorElement(e)
202+
};
203+
204+
/**
205+
Renders a Relude.AsyncResult value by providing a render function for each case
206+
*/
207+
let asyncResultLazy:
208+
'a 'e.
209+
(
210+
Relude.AsyncResult.t('a, 'e),
211+
unit => React.element,
212+
unit => React.element,
213+
'a => React.element,
214+
'e => React.element,
215+
'a => React.element,
216+
'e => React.element
217+
) =>
218+
React.element
219+
=
220+
(
221+
result,
222+
initElement,
223+
loadingElement,
224+
reloadingOkElement,
225+
reloadingErrorElement,
226+
completeOkElement,
227+
completeErrorElement,
228+
) =>
229+
switch (result) {
230+
| Init => initElement()
231+
| Loading => loadingElement()
232+
| Reloading(Ok(a)) => reloadingOkElement(a)
233+
| Reloading(Error(e)) => reloadingErrorElement(e)
234+
| Complete(Ok(a)) => completeOkElement(a)
235+
| Complete(Error(e)) => completeErrorElement(e)
236+
};
237+
238+
/**
239+
Renders a Relude.AsyncResult value by providing an element/render function for each same-type value
240+
*/
241+
let asyncResultByValue:
242+
'a 'e.
243+
(
244+
Relude.AsyncResult.t('a, 'e),
245+
React.element,
246+
'a => React.element,
247+
'e => React.element
248+
) =>
249+
React.element
250+
=
251+
(result, initOrLoadingElement, okElement, errorElement) =>
252+
switch (result) {
253+
| Init
254+
| Loading => initOrLoadingElement
255+
| Reloading(Ok(a))
256+
| Complete(Ok(a)) => okElement(a)
257+
| Reloading(Error(e))
258+
| Complete(Error(e)) => errorElement(e)
259+
};
260+
261+
/**
262+
Renders a Relude.AsyncResult value by providing a render function for each same-type value
263+
*/
264+
let asyncResultByValueLazy:
265+
'a 'e.
266+
(
267+
Relude.AsyncResult.t('a, 'e),
268+
React.element,
269+
'a => React.element,
270+
'e => React.element
271+
) =>
272+
React.element
273+
=
274+
(result, initOrLoadingElement, okElement, errorElement) =>
275+
switch (result) {
276+
| Init
277+
| Loading => initOrLoadingElement
278+
| Reloading(Ok(a))
279+
| Complete(Ok(a)) => okElement(a)
280+
| Reloading(Error(e))
281+
| Complete(Error(e)) => errorElement(e)
282+
};

0 commit comments

Comments
 (0)