├── src
├── label
│ └── Label.re
├── loading-spinner
│ └── LoadingSpinner.re
├── Option.re
├── theme
│ ├── Theme_Breakpoints.re
│ ├── Theme_Space.re
│ ├── Theme.re
│ └── Theme_Colors.re
├── dropdown
│ └── Dropdown.re
├── spacer
│ └── Spacer.re
├── shims
│ └── ReactNative.shim.ts
├── hoverable
│ └── Hoverable.re
├── index.ts
├── input
│ ├── Input_Theme.re
│ └── Input.re
├── text
│ ├── Text_Theme.re
│ └── Text.re
├── button
│ ├── Button_Theme.re
│ └── Button.re
├── responsive
│ └── Responsive.re
└── box
│ ├── Box.re
│ └── AnimatedBox.re
├── README.md
├── babel.config.js
├── .npmignore
├── tsconfig.json
├── bsconfig.json
├── .gitignore
└── package.json
/src/label/Label.re:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Renew
2 |
3 | Universal Component Kit for Web and React Native, written in ReasonML.
4 |
--------------------------------------------------------------------------------
/src/loading-spinner/LoadingSpinner.re:
--------------------------------------------------------------------------------
1 | [@react.component]
2 | let make = () => {
3 | ;
4 | };
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['next/babel'],
3 | plugins: [['react-native-web', { commonjs: true }]],
4 | }
5 |
--------------------------------------------------------------------------------
/src/Option.re:
--------------------------------------------------------------------------------
1 | let (>>=) = Belt.Option.flatMap;
2 | let (<$>) = Belt.Option.map;
3 |
4 | let (|?) = (option, defaultValue) =>
5 | switch (option) {
6 | | Some(value) => value
7 | | None => defaultValue
8 | };
--------------------------------------------------------------------------------
/src/theme/Theme_Breakpoints.re:
--------------------------------------------------------------------------------
1 | type t = {
2 | xs: float,
3 | sm: float,
4 | md: float,
5 | lg: float,
6 | xl: float,
7 | };
8 |
9 | [@genType]
10 | let defaultTheme: t = {xs: 0., sm: 576., md: 768., lg: 992., xl: 1200.};
--------------------------------------------------------------------------------
/src/theme/Theme_Space.re:
--------------------------------------------------------------------------------
1 | // space for margin and padding
2 | type t = array(ReactNative.Style.size);
3 |
4 | let dp = ReactNative.Style.dp;
5 |
6 | [@genType]
7 | let defaultTheme: t = [|
8 | 0.->dp,
9 | 4.->dp,
10 | 8.->dp,
11 | 16.->dp,
12 | 32.->dp,
13 | 64.->dp,
14 | 128.->dp,
15 | 256.->dp,
16 | 512.->dp,
17 | |];
--------------------------------------------------------------------------------
/src/dropdown/Dropdown.re:
--------------------------------------------------------------------------------
1 | module View = ReactNative.View;
2 | [@react.component]
3 | let make = (~isShow=false, ~trigger, ~children) => {
4 |
5 | trigger
6 |
7 | {isShow ? children : React.null}
8 |
9 | ;
10 | };
11 |
12 | [@genType]
13 | let default = make;
--------------------------------------------------------------------------------
/src/spacer/Spacer.re:
--------------------------------------------------------------------------------
1 | [@react.component]
2 | let make = (~v=1., ~h=1.) => {
3 | let theme = Theme.useTheme();
4 |
5 | let baseRem = theme.text.fontSize.md;
6 |
7 | let width = h *. baseRem;
8 | let height = v *. baseRem;
9 |
10 | ReactNative.Style.dp} h={height->ReactNative.Style.dp} />;
11 | };
12 |
13 | [@genType]
14 | let default = make;
--------------------------------------------------------------------------------
/src/shims/ReactNative.shim.ts:
--------------------------------------------------------------------------------
1 | import * as RN from "react-native";
2 |
3 | export type Style_t = RN.ViewStyle;
4 |
5 | export type Style_size = number | string;
6 |
7 | export type Style_margin = number | string;
8 | export type Style_offset = number | string;
9 |
10 | export type Color_t = string;
11 |
12 | export type FontVariant_t = RN.FontVariant;
13 |
14 | export type Event_pressEvent = RN.GestureResponderEvent;
15 |
--------------------------------------------------------------------------------
/src/hoverable/Hoverable.re:
--------------------------------------------------------------------------------
1 | let isWeb = ReactNative.Platform.os == ReactNative.Platform.web;
2 |
3 | [@react.component]
4 | let make = (~children, ~onHoverIn, ~onHoverOut) =>
5 | if (!isWeb) {
6 | children;
7 | } else {
8 | // let (isHover, setHover) = React.useState(() => false);
9 |
10 | let onMouseEnter = _ => {
11 | onHoverIn();
12 | };
13 | let onMouseLeave = _ => {
14 | onHoverOut();
15 | };
16 |
17 | children ;
18 | };
19 |
20 | [@genType]
21 | let default = make;
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 |
21 | # debug
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 |
26 | # local env files
27 | .env.local
28 | .env.development.local
29 | .env.test.local
30 | .env.production.local
31 |
32 | # reason/bucklescript
33 | /lib
34 | .bsb.lock
35 | .merlin
36 |
37 | /.docz/
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import Box from "./box/Box.gen";
2 | import Button from "./button/Button.gen";
3 | import Dropdown from "./dropdown/Dropdown.gen";
4 | import Input from "./input/Input.gen";
5 | import Responsive from "./responsive/Responsive.gen";
6 | import Spacer from "./spacer/Spacer.gen";
7 | import Text from "./text/Text.gen";
8 | import ThemeProvider, { defaultTheme, useTheme } from "./theme/Theme.gen";
9 |
10 | export {
11 | ThemeProvider,
12 | defaultTheme,
13 | Button,
14 | Spacer,
15 | Box,
16 | useTheme,
17 | Input,
18 | Text,
19 | Responsive,
20 | Dropdown,
21 | };
22 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "esnext",
5 | "strict": true,
6 | "esModuleInterop": true,
7 | "lib": ["dom", "dom.iterable", "esnext"],
8 | "allowJs": true,
9 | "skipLibCheck": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "noEmit": true,
12 | "moduleResolution": "node",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve"
16 | },
17 | "exclude": ["node_modules"],
18 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "pages/_document.js"]
19 | }
20 |
--------------------------------------------------------------------------------
/bsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "renew",
3 | "sources": [
4 | {
5 | "dir": "src",
6 | "subdirs": true
7 | }
8 | ],
9 | "bs-dependencies": ["reason-react", "reason-react-native"],
10 | "gentypeconfig": {
11 | "language": "typescript",
12 | "shims": {
13 | "ReactNative": "ReactNative"
14 | },
15 | "debug": {
16 | "all": false,
17 | "basic": false
18 | }
19 | },
20 | "reason": { "react-jsx": 3 },
21 | "package-specs": {
22 | "module": "commonjs",
23 | "in-source": true
24 | },
25 | "suffix": ".bs.js",
26 | "bsc-flags": ["-bs-super-errors"],
27 | "refmt": 3
28 | }
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 |
21 | # debug
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 |
26 | # local env files
27 | .env.local
28 | .env.development.local
29 | .env.test.local
30 | .env.production.local
31 |
32 | # reason/bucklescript
33 | /lib
34 | .bsb.lock
35 | .merlin
36 |
37 | src/index.js
38 | src/index.d.ts
39 |
40 | *.gen.tsx
41 | *.bs.js
42 |
43 | /.docz/
--------------------------------------------------------------------------------
/src/input/Input_Theme.re:
--------------------------------------------------------------------------------
1 | type textTransformT = [ | `none | `uppercase | `capitalize | `lowercase];
2 |
3 | type t = {
4 | borderRadius: float,
5 | borderWidth: float,
6 | textColor: string,
7 | placeholderColor: string,
8 | backgroundColor: string,
9 | //
10 | height: float,
11 | paddingHorizontal: float,
12 | textTransform: textTransformT,
13 | };
14 |
15 | [@genType]
16 | let defaultTheme: t = {
17 | borderRadius: 4.,
18 | borderWidth: 1.,
19 | textTransform: `none,
20 | textColor: Theme_Colors.light.foreground,
21 | placeholderColor: Theme_Colors.light.neutral300,
22 | backgroundColor: Theme_Colors.light.background,
23 | height: 35.,
24 | paddingHorizontal: 14.,
25 | };
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@damaera/renew",
3 | "version": "0.0.3",
4 | "main": "./src/index.js",
5 | "types": "./src/index.d.ts",
6 | "scripts": {
7 | "re-dev": "bsb -clean-world -make-world -w",
8 | "re-build": "bsb -clean-world -make-world",
9 | "re-clean": "bsb -clean-world",
10 | "gen-d-ts": "tsc -d src/index.ts",
11 | "build": "yarn re-build && yarn gen-d-ts"
12 | },
13 | "dependencies": {
14 | "gentype": "^3.22.0",
15 | "react": "^16.8.0",
16 | "react-dom": "^16.8.0",
17 | "react-native": "^0.62.2",
18 | "react-native-web": "^0.11.6",
19 | "reason-react": "^0.7.0",
20 | "reason-react-native": "^0.61.1"
21 | },
22 | "devDependencies": {
23 | "@types/react": "^16.9.35",
24 | "@types/react-native": "^0.62.10",
25 | "babel-plugin-react-native-web": "^0.11.7",
26 | "bs-platform": "^7.3.2",
27 | "typescript": "^3.9.3"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/text/Text_Theme.re:
--------------------------------------------------------------------------------
1 | type sizeT = {
2 | xs: float,
3 | sm: float,
4 | md: float,
5 | lg: float,
6 | xl: float,
7 | _2xl: float,
8 | _3xl: float,
9 | _4xl: float,
10 | _5xl: float,
11 | _6xl: float,
12 | };
13 |
14 | type fontFamilyT = {
15 | body: string,
16 | heading: string,
17 | tertiary: string,
18 | monospace: string,
19 | };
20 |
21 | type t = {
22 | fontSize: sizeT,
23 | fontFamily: fontFamilyT,
24 | };
25 | [@genType]
26 | let defaultTheme: t = {
27 | fontFamily: {
28 | body: "",
29 | heading: "",
30 | tertiary: "",
31 | monospace: "",
32 | },
33 | // https://type-scale.com/
34 | // scale: Major Third
35 | // base size = 14
36 | fontSize: {
37 | xs: 8.96,
38 | sm: 11.2,
39 | md: 14.,
40 | lg: 17.5,
41 | xl: 21.88,
42 | _2xl: 27.34,
43 | _3xl: 34.18,
44 | _4xl: 42.72,
45 | _5xl: 53.41,
46 | _6xl: 66.76,
47 | },
48 | };
--------------------------------------------------------------------------------
/src/theme/Theme.re:
--------------------------------------------------------------------------------
1 | type t = {
2 | // global
3 | breakpoints: Theme_Breakpoints.t,
4 | colors: Theme_Colors.t,
5 | // component
6 | button: Button_Theme.t,
7 | text: Text_Theme.t,
8 | space: Theme_Space.t,
9 | input: Input_Theme.t,
10 | };
11 |
12 | [@genType]
13 | let defaultTheme: t = {
14 | // global
15 | breakpoints: Theme_Breakpoints.defaultTheme,
16 | colors: Theme_Colors.light,
17 | // component
18 | button: Button_Theme.defaultTheme,
19 | text: Text_Theme.defaultTheme,
20 | input: Input_Theme.defaultTheme,
21 | space: Theme_Space.defaultTheme,
22 | };
23 |
24 | let themeContext = React.createContext(defaultTheme);
25 |
26 | let makeProps = (~value: t=defaultTheme, ~children, ()) => {
27 | "value": value,
28 | "children": children,
29 | };
30 |
31 | let make = React.Context.provider(themeContext);
32 |
33 | [@genType]
34 | let useTheme = () => {
35 | let theme = React.useContext(themeContext);
36 | theme;
37 | };
38 |
39 | [@genType]
40 | let default = make;
--------------------------------------------------------------------------------
/src/button/Button_Theme.re:
--------------------------------------------------------------------------------
1 | type sizeT = {
2 | xs: float,
3 | sm: float,
4 | md: float,
5 | lg: float,
6 | xl: float,
7 | };
8 |
9 | type fontWeightT = [
10 | | `normal
11 | | `bold
12 | | `_100
13 | | `_200
14 | | `_300
15 | | `_400
16 | | `_500
17 | | `_600
18 | | `_700
19 | | `_800
20 | | `_900
21 | ];
22 |
23 | type textTransformT = [ | `none | `uppercase | `capitalize | `lowercase];
24 |
25 | type t = {
26 | borderRadius: float,
27 | borderWidth: float,
28 | fontWeight: fontWeightT,
29 | solidTextColor: string,
30 | height: sizeT,
31 | paddingHorizontal: sizeT,
32 | textTransform: textTransformT,
33 | };
34 |
35 | [@genType]
36 | let defaultTheme: t = {
37 | borderRadius: 4.,
38 | borderWidth: 2.,
39 | textTransform: `none,
40 | fontWeight: `bold,
41 | solidTextColor: Theme_Colors.light.background,
42 | height: {
43 | xs: 21.,
44 | sm: 28.,
45 | md: 35.,
46 | lg: 42.,
47 | xl: 49.,
48 | },
49 | paddingHorizontal: {
50 | xs: 7.,
51 | sm: 10.5,
52 | md: 14.,
53 | lg: 17.5,
54 | xl: 21.,
55 | },
56 | };
--------------------------------------------------------------------------------
/src/input/Input.re:
--------------------------------------------------------------------------------
1 | open ReactNative.Style;
2 |
3 | type variantColorT = [
4 | | `primary
5 | | `secondary
6 | | `success
7 | | `danger
8 | | `info
9 | | `warning
10 | | `neutral
11 | ];
12 |
13 | [@react.component]
14 | let make =
15 | (
16 | ~component=,
17 | ~color: variantColorT=`neutral,
18 | ~onFocus=_ => (),
19 | ~onBlur=_ => (),
20 | ~style=?,
21 | ) => {
22 | let theme = Theme.useTheme();
23 |
24 | let (isFocused, setFocused) = React.useState(_ => false);
25 |
26 | let themeBorderColor = {
27 | switch (color) {
28 | | `primary => theme.colors.primary
29 | | `secondary => theme.colors.secondary
30 | | `success => theme.colors.success
31 | | `danger => theme.colors.danger
32 | | `info => theme.colors.info
33 | | `warning => theme.colors.warning
34 | | `neutral => theme.colors.neutral300
35 | };
36 | };
37 |
38 | let resolvedStyle = arrayOption([|style|]);
39 |
40 | let inputElement =
41 | ReasonReact.cloneElement(
42 | component,
43 | ~props={
44 | "style": resolvedStyle,
45 | "onFocus": e => {
46 | setFocused(_ => true);
47 | onFocus(e);
48 | },
49 | "onBlur": e => {
50 | setFocused(_ => false);
51 | onBlur(e);
52 | },
53 | },
54 | [||],
55 | );
56 |
57 | dp}
62 | h={theme.input.height->dp}
63 | bg={theme.input.backgroundColor}
64 | borderColor=themeBorderColor
65 | />;
66 | };
67 |
68 | [@genType]
69 | let default = make;
--------------------------------------------------------------------------------
/src/theme/Theme_Colors.re:
--------------------------------------------------------------------------------
1 | type t = {
2 | background: string,
3 | foreground: string,
4 | //
5 | neutral100: string,
6 | neutral200: string,
7 | neutral300: string,
8 | neutral400: string,
9 | neutral500: string,
10 | neutral600: string,
11 | neutral700: string,
12 | neutral800: string,
13 | neutral900: string,
14 | //
15 | primary: string,
16 | primaryLight: string,
17 | primaryLighter: string,
18 | primaryDark: string,
19 | primaryDarker: string,
20 | //
21 | secondary: string,
22 | secondaryLight: string,
23 | secondaryLighter: string,
24 | secondaryDark: string,
25 | secondaryDarker: string,
26 | //
27 | success: string,
28 | successLight: string,
29 | successLighter: string,
30 | successDark: string,
31 | successDarker: string,
32 | //
33 | danger: string,
34 | dangerLight: string,
35 | dangerLighter: string,
36 | dangerDark: string,
37 | dangerDarker: string,
38 | //
39 | info: string,
40 | infoLight: string,
41 | infoLighter: string,
42 | infoDark: string,
43 | infoDarker: string,
44 | //
45 | warning: string,
46 | warningLight: string,
47 | warningLighter: string,
48 | warningDark: string,
49 | warningDarker: string,
50 | };
51 |
52 | [@genType]
53 | let light: t = {
54 | background: "#fff",
55 | foreground: "#000",
56 | //
57 | neutral100: "#fafafa",
58 | neutral200: "#eaeaea",
59 | neutral300: "#999",
60 | neutral400: "#888",
61 | neutral500: "#666",
62 | neutral600: "#444",
63 | neutral700: "#333",
64 | neutral800: "#111",
65 | neutral900: "#060606",
66 | //
67 | primary: "#3f51b5",
68 | primaryDark: "#303f9f",
69 | primaryDarker: "#1a237e",
70 | primaryLight: "#7986cb",
71 | primaryLighter: "#c5cae9",
72 | //
73 | secondary: "#e91e63",
74 | secondaryDark: "#c2185b",
75 | secondaryDarker: "#880e4f",
76 | secondaryLight: "#f06292",
77 | secondaryLighter: "#f8bbd0",
78 | //
79 | success: "#4caf50",
80 | successDark: "#388e3c",
81 | successDarker: "#1b5e20",
82 | successLight: "#81c784",
83 | successLighter: "#c8e6c9",
84 | //
85 | danger: "#f44336",
86 | dangerDark: "#ba000d",
87 | dangerDarker: "#b71c1c",
88 | dangerLight: "#e57373",
89 | dangerLighter: "#ffcdd2",
90 | //
91 | info: "#2196f3",
92 | infoDark: "#1976d2",
93 | infoDarker: "#0d47a1",
94 | infoLight: "#64b5f6",
95 | infoLighter: "#bbdefb",
96 | //
97 | warning: "#ffc107",
98 | warningDark: "#ffa000",
99 | warningDarker: "#ff6f00",
100 | warningLight: "#ffd54f",
101 | warningLighter: "#ffecb3",
102 | };
--------------------------------------------------------------------------------
/src/text/Text.re:
--------------------------------------------------------------------------------
1 | open Option;
2 |
3 | type variantT = [ | `body | `heading | `tertiary | `monospace];
4 |
5 | [@react.component]
6 | let make =
7 | (
8 | ~component=,
9 | ~children=?,
10 | ~value="",
11 | ~style=?,
12 | // size theme
13 | ~size=`md,
14 | ~variant: variantT=`body,
15 | // rn style props
16 | ~textShadowOffset=?,
17 | ~color=?,
18 | ~fontSize=?,
19 | ~fontStyle=?,
20 | ~fontWeight=?,
21 | ~lineHeight=?,
22 | ~textAlign=?,
23 | ~textDecorationLine=?,
24 | ~textShadowColor=?,
25 | ~fontFamily=?,
26 | ~textShadowRadius=?,
27 | ~includeFontPadding=?,
28 | ~textAlignVertical=?,
29 | ~fontVariant=?,
30 | ~letterSpacing=?,
31 | ~textDecorationColor=?,
32 | ~textDecorationStyle=?,
33 | ~textTransform=?,
34 | ~writingDirection=?,
35 | ) => {
36 | let theme = Theme.useTheme();
37 |
38 | let styleText = style;
39 |
40 | let themeFontSize =
41 | switch (size) {
42 | | `xs => theme.text.fontSize.xs
43 | | `sm => theme.text.fontSize.sm
44 | | `md => theme.text.fontSize.md
45 | | `lg => theme.text.fontSize.lg
46 | | `xl => theme.text.fontSize.xl
47 | | `_2xl => theme.text.fontSize._2xl
48 | | `_3xl => theme.text.fontSize._3xl
49 | | `_4xl => theme.text.fontSize._4xl
50 | | `_5xl => theme.text.fontSize._5xl
51 | | `_6xl => theme.text.fontSize._6xl
52 | };
53 |
54 | let fontFamilyThemeStyle =
55 | switch (variant) {
56 | | `body => theme.text.fontFamily.body
57 | | `heading => theme.text.fontFamily.heading
58 | | `tertiary => theme.text.fontFamily.tertiary
59 | | `monospace => theme.text.fontFamily.monospace
60 | };
61 |
62 | let t = ReactNative.Style.textStyle;
63 |
64 | let resolvedStyle =
65 | ReactNative.Style.(
66 | arrayOption([|
67 | Some(
68 | textStyle(
69 | ~fontSize=themeFontSize,
70 | ~fontFamily=fontFamilyThemeStyle,
71 | (),
72 | ),
73 | ),
74 | // Text Props
75 | textShadowOffset <$> (s => t(~textShadowOffset=s, ())),
76 | color <$> (s => t(~color=s, ())),
77 | fontSize <$> (s => t(~fontSize=s, ())),
78 | fontStyle <$> (s => t(~fontStyle=s, ())),
79 | fontWeight <$> (s => t(~fontWeight=s, ())),
80 | lineHeight <$> (s => t(~lineHeight=s, ())),
81 | textAlign <$> (s => t(~textAlign=s, ())),
82 | textDecorationLine <$> (s => t(~textDecorationLine=s, ())),
83 | textShadowColor <$> (s => t(~textShadowColor=s, ())),
84 | fontFamily <$> (s => t(~fontFamily=s, ())),
85 | textShadowRadius <$> (s => t(~textShadowRadius=s, ())),
86 | includeFontPadding <$> (s => t(~includeFontPadding=s, ())),
87 | textAlignVertical <$> (s => t(~textAlignVertical=s, ())),
88 | fontVariant <$> (s => t(~fontVariant=s, ())),
89 | letterSpacing <$> (s => t(~letterSpacing=s, ())),
90 | textDecorationColor <$> (s => t(~textDecorationColor=s, ())),
91 | textDecorationStyle <$> (s => t(~textDecorationStyle=s, ())),
92 | textTransform <$> (s => t(~textTransform=s, ())),
93 | writingDirection <$> (s => t(~writingDirection=s, ())),
94 | //
95 | styleText,
96 | |])
97 | );
98 | let reactChildren = {
99 | switch (children) {
100 | | Some(children) => [|children|]
101 | | None => [|value->React.string|]
102 | };
103 | };
104 | ReasonReact.cloneElement(
105 | component,
106 | ~props={"style": resolvedStyle},
107 | reactChildren,
108 | );
109 | };
110 |
111 | [@genType]
112 | let default = make;
--------------------------------------------------------------------------------
/src/responsive/Responsive.re:
--------------------------------------------------------------------------------
1 | open Option;
2 |
3 | type resT('a) = {
4 | xs: option('a),
5 | sm: option('a),
6 | md: option('a),
7 | lg: option('a),
8 | xl: option('a),
9 | };
10 |
11 | let useWindowWidth = () => {
12 | let initial = ReactNative.Dimensions.get(`window);
13 | let (windowWidth, setWindowWidth) = React.useState(() => initial##width);
14 | let handler = v => setWindowWidth(_ => v##window##width);
15 | React.useEffect0(() => {
16 | ReactNative.Dimensions.addEventListener(`change, handler);
17 | Some(() => ReactNative.Dimensions.removeEventListener(`change, handler));
18 | });
19 |
20 | windowWidth;
21 | };
22 |
23 | let useScreenSize = () => {
24 | let windowWidth = useWindowWidth();
25 | let theme = Theme.useTheme();
26 | let currentScreenSize =
27 | switch (windowWidth) {
28 | | w when w >= theme.breakpoints.xl => `xl
29 | | w when w >= theme.breakpoints.lg => `lg
30 | | w when w >= theme.breakpoints.md => `md
31 | | w when w >= theme.breakpoints.sm => `sm
32 | | _ => `xs
33 | };
34 | currentScreenSize;
35 | };
36 |
37 | let makeSize = (~xs=?, ~sm=?, ~md=?, ~lg=?, ~xl=?, ()) => {
38 | let size = {xs, sm, md, lg, xl};
39 | size;
40 | };
41 |
42 | [@react.component]
43 | let make =
44 | (
45 | ~component=,
46 | ~display=?,
47 | // Flex
48 | ~alignContent=?,
49 | ~alignItems=?,
50 | ~alignSelf=?,
51 | ~flex=?,
52 | ~flexBasis=?,
53 | ~flexDirection=?,
54 | ~flexGrow=?,
55 | ~flexShrink=?,
56 | ~flexWrap=?,
57 | ~justifyContent=?,
58 | // width and height
59 | ~width=?,
60 | ~height=?,
61 | ~minWidth=?,
62 | ~minHeight=?,
63 | ~maxWidth=?,
64 | ~maxHeight=?,
65 | //
66 | ~style=?,
67 | ~children=?,
68 | ) => {
69 | let currentScreenSize = useScreenSize();
70 |
71 | let resVal = (v, defaultValue) => {
72 | switch (currentScreenSize) {
73 | | `xs => v.xs |? defaultValue
74 | | `sm => v.sm |? (v.xs |? defaultValue)
75 | | `md => v.md |? (v.sm |? (v.xs |? defaultValue))
76 | | `lg => v.lg |? (v.md |? (v.sm |? (v.xs |? defaultValue)))
77 | | `xl => v.xl |? (v.lg |? (v.md |? (v.sm |? (v.xs |? defaultValue))))
78 | };
79 | };
80 |
81 | let v = ReactNative.Style.viewStyle;
82 | let dp = ReactNative.Style.dp;
83 | let pct = ReactNative.Style.pct;
84 |
85 | let resolvedStyle =
86 | ReactNative.Style.arrayOption([|
87 | display <$> (d => v(~display=resVal(d, `flex), ())),
88 | // flex
89 | alignContent <$> (s => v(~alignContent=resVal(s, `flexStart), ())),
90 | alignItems <$> (s => v(~alignItems=resVal(s, `flexStart), ())),
91 | alignSelf <$> (s => v(~alignSelf=resVal(s, `flexStart), ())),
92 | flex <$> (s => v(~flex=resVal(s, 1.), ())),
93 | flexBasis <$> (s => v(~flexBasis=resVal(s, 0.->dp), ())),
94 | flexDirection <$> (s => v(~flexDirection=resVal(s, `row), ())),
95 | flexGrow <$> (s => v(~flexGrow=resVal(s, 1.), ())),
96 | flexShrink <$> (s => v(~flexShrink=resVal(s, 1.), ())),
97 | flexWrap <$> (s => v(~flexWrap=resVal(s, `wrap), ())),
98 | justifyContent <$> (s => v(~justifyContent=resVal(s, `flexStart), ())),
99 | // width and height
100 | width <$> (d => v(~width=resVal(d, 100.->pct), ())),
101 | height <$> (s => v(~height=resVal(s, 100.->pct), ())),
102 | minWidth <$> (s => v(~minWidth=resVal(s, 0.->dp), ())),
103 | minHeight <$> (s => v(~minHeight=resVal(s, 0.->dp), ())),
104 | maxWidth <$> (s => v(~maxWidth=resVal(s, 100.->pct), ())),
105 | maxHeight <$> (s => v(~maxHeight=resVal(s, 100.->pct), ())),
106 | // rest
107 | style,
108 | |]);
109 |
110 | let reactChildren = {
111 | switch (children) {
112 | | Some(children) => [|children|]
113 | | None => [||]
114 | };
115 | };
116 |
117 | ReasonReact.cloneElement(
118 | component,
119 | ~props={"style": resolvedStyle},
120 | reactChildren,
121 | );
122 | };
123 |
124 | [@genType]
125 | let default = make;
--------------------------------------------------------------------------------
/src/button/Button.re:
--------------------------------------------------------------------------------
1 | module UIText = Text;
2 | open ReactNative;
3 |
4 | type sizeT = [ | `xs | `sm | `md | `lg | `xl];
5 | type variantColorT = [
6 | | `primary
7 | | `secondary
8 | | `success
9 | | `danger
10 | | `info
11 | | `warning
12 | | `neutral
13 | ];
14 |
15 | type variantT = [ | `solid | `ghost | `outline | `light];
16 |
17 | type colorT = {
18 | normal: string,
19 | light: string,
20 | lighter: string,
21 | dark: string,
22 | darker: string,
23 | };
24 |
25 | [@react.component]
26 | let make =
27 | (
28 | ~text,
29 | ~size: sizeT=`md,
30 | ~variant: variantT=`solid,
31 | ~color: variantColorT=`neutral,
32 | ~prefixElement=?,
33 | ~suffixElement=?,
34 | ~style=?,
35 | ~textStyle=?,
36 | ~children=?,
37 | ~onPress=_ => (),
38 | ) => {
39 | let theme = Theme.useTheme();
40 |
41 | let styleButton = style;
42 | let styleText = textStyle;
43 |
44 | let (isHover, setHover) = React.useState(() => false);
45 |
46 | let (height, paddingHorizontal) =
47 | Style.(
48 | switch (size) {
49 | | `xs => (
50 | theme.button.height.xs->dp,
51 | theme.button.paddingHorizontal.xs->dp,
52 | )
53 | | `sm => (
54 | theme.button.height.sm->dp,
55 | theme.button.paddingHorizontal.sm->dp,
56 | )
57 | | `md => (
58 | theme.button.height.md->dp,
59 | theme.button.paddingHorizontal.md->dp,
60 | )
61 | | `lg => (
62 | theme.button.height.lg->dp,
63 | theme.button.paddingHorizontal.lg->dp,
64 | )
65 |
66 | | `xl => (
67 | theme.button.height.xl->dp,
68 | theme.button.paddingHorizontal.xl->dp,
69 | )
70 | }
71 | );
72 |
73 | let color = {
74 | switch (color) {
75 | | `primary => {
76 | normal: theme.colors.primary,
77 | light: theme.colors.primaryLight,
78 | lighter: theme.colors.primaryLighter,
79 | dark: theme.colors.primaryDark,
80 | darker: theme.colors.primaryDarker,
81 | }
82 | | `secondary => {
83 | normal: theme.colors.secondary,
84 | light: theme.colors.secondaryLight,
85 | lighter: theme.colors.secondaryLighter,
86 | dark: theme.colors.secondaryDark,
87 | darker: theme.colors.secondaryDarker,
88 | }
89 | | `success => {
90 | normal: theme.colors.success,
91 | light: theme.colors.successLight,
92 | lighter: theme.colors.successLighter,
93 | dark: theme.colors.successDark,
94 | darker: theme.colors.successDarker,
95 | }
96 | | `danger => {
97 | normal: theme.colors.danger,
98 | light: theme.colors.dangerLight,
99 | lighter: theme.colors.dangerLighter,
100 | dark: theme.colors.dangerDark,
101 | darker: theme.colors.dangerDarker,
102 | }
103 | | `info => {
104 | normal: theme.colors.info,
105 | light: theme.colors.infoLight,
106 | lighter: theme.colors.infoLighter,
107 | dark: theme.colors.infoDark,
108 | darker: theme.colors.infoDarker,
109 | }
110 | | `warning => {
111 | normal: theme.colors.warning,
112 | light: theme.colors.warningLight,
113 | lighter: theme.colors.warningLighter,
114 | dark: theme.colors.warningDark,
115 | darker: theme.colors.warningDarker,
116 | }
117 | | `neutral => {
118 | normal: theme.colors.neutral600,
119 | light: theme.colors.neutral400,
120 | lighter: theme.colors.neutral200,
121 | dark: theme.colors.neutral700,
122 | darker: theme.colors.neutral900,
123 | }
124 | };
125 | };
126 |
127 | let typeStyleText =
128 | switch (variant) {
129 | | `solid => Style.textStyle(~color=theme.button.solidTextColor, ())
130 | | `outline => Style.textStyle(~color=color.dark, ())
131 | | `ghost => Style.textStyle(~color=color.normal, ())
132 | | `light => Style.textStyle(~color=color.darker, ())
133 | };
134 |
135 | let bg =
136 | switch (variant) {
137 | | `solid => color.normal
138 | | `outline => theme.colors.background
139 | | `ghost => theme.colors.background
140 | | `light => color.lighter
141 | };
142 | let borderColor =
143 | switch (variant) {
144 | | `solid => color.normal
145 | | `outline => color.dark
146 | | `ghost => theme.colors.background
147 | | `light => color.lighter
148 | };
149 |
150 | let resolvedStyle = Style.(arrayOption([|styleButton|]));
151 |
152 | let resolvedTextStyle =
153 | Style.(arrayOption([|Some(typeStyleText), styleText|]));
154 |
155 | let baseRem = theme.text.fontSize.md;
156 |
157 | let spacerSize =
158 | switch (size) {
159 | | `xs => theme.text.fontSize.xs /. baseRem
160 | | `sm => theme.text.fontSize.sm /. baseRem
161 | | `md => 1.
162 | | `lg => theme.text.fontSize.lg /. baseRem
163 | | `xl => theme.text.fontSize.xl /. baseRem
164 | };
165 |
166 | let onHoverIn = () => {
167 | setHover(_ => true);
168 | };
169 | let onHoverOut = () => {
170 | setHover(_ => false);
171 | };
172 |
173 |
174 |
181 | }
182 | flexDirection=`row
183 | alignItems=`center
184 | borderRadius={theme.button.borderRadius}
185 | borderWidth={theme.button.borderWidth}
186 | bg
187 | borderColor
188 | h=height
189 | ph=paddingHorizontal
190 | opacity={isHover ? 0.9 : 1.}
191 | style=resolvedStyle>
192 | {switch (prefixElement) {
193 | | Some(element) =>
194 | <> element >
195 | | None => React.null
196 | }}
197 |
198 | {switch (children) {
199 | | Some(children) => children
200 | | None =>
201 |
208 | }}
209 |
210 | {switch (suffixElement) {
211 | | Some(element) =>
212 | <> element >
213 | | None => React.null
214 | }}
215 |
216 | ;
217 | };
218 |
219 | [@genType]
220 | let default = make;
--------------------------------------------------------------------------------
/src/box/Box.re:
--------------------------------------------------------------------------------
1 | open ReactNative;
2 |
3 | let (>>=) = Belt.Option.flatMap;
4 | let (<$>) = Belt.Option.map;
5 |
6 | [@react.component]
7 | let make =
8 | /* flex */
9 | (
10 | ~alignContent=?,
11 | ~alignItems=?,
12 | ~alignSelf=?,
13 | ~flex=?,
14 | ~flexBasis=?,
15 | ~flexDirection=?,
16 | ~flexGrow=?,
17 | ~flexShrink=?,
18 | ~flexWrap=?,
19 | ~justifyContent=?,
20 | /* padding */
21 | ~p=?,
22 | ~pt=?,
23 | ~pr=?,
24 | ~pl=?,
25 | ~pb=?,
26 | ~pv=?,
27 | ~ph=?,
28 | ~pe=?,
29 | ~ps=?,
30 | /* margin */
31 | ~m=?,
32 | ~mt=?,
33 | ~mr=?,
34 | ~ml=?,
35 | ~mb=?,
36 | ~mv=?,
37 | ~mh=?,
38 | ~me=?,
39 | ~ms=?,
40 | /* position */
41 | ~position=?,
42 | ~top=?,
43 | ~right=?,
44 | ~left=?,
45 | ~bottom=?,
46 | ~start=?,
47 | ~end_=?,
48 | /* size */
49 | ~w=?,
50 | ~h=?,
51 | ~maxW=?,
52 | ~maxH=?,
53 | ~minW=?,
54 | ~minH=?,
55 | ~aspectRatio=?,
56 | /* bg */
57 | ~bg=?,
58 | /* opacity */
59 | ~opacity=?,
60 | /* borderWidth */
61 | ~borderWidth=?,
62 | ~borderTopWidth=?,
63 | ~borderRightWidth=?,
64 | ~borderBottomWidth=?,
65 | ~borderLeftWidth=?,
66 | ~borderStartWidth=?,
67 | ~borderEndWidth=?,
68 | /* borderRadius */
69 | ~borderRadius=?,
70 | ~borderTopRightRadius=?,
71 | ~borderTopLeftRadius=?,
72 | ~borderTopStartRadius=?,
73 | ~borderTopEndRadius=?,
74 | ~borderBottomRightRadius=?,
75 | ~borderBottomLeftRadius=?,
76 | ~borderBottomStartRadius=?,
77 | ~borderBottomEndRadius=?,
78 | /* borderColor */
79 | ~borderColor=?,
80 | ~borderTopColor=?,
81 | ~borderRightColor=?,
82 | ~borderBottomColor=?,
83 | ~borderLeftColor=?,
84 | ~borderStartColor=?,
85 | ~borderEndColor=?,
86 | /* overflow */
87 | ~overflow=?,
88 | /* zIndex */
89 | ~zIndex=?,
90 | /* direction */
91 | ~direction=?,
92 | // display
93 | ~display=?,
94 | /* rest */
95 | ~style=?,
96 | ~children=?,
97 | ~component=,
98 | ) => {
99 | /* theme */
100 | let pt_ = pt;
101 |
102 | // value
103 | let v = Style.viewStyle;
104 |
105 | let resolvedStyle =
106 | Style.arrayOption([|
107 | // flex
108 | alignContent <$> (a => v(~alignContent=a, ())),
109 | alignItems <$> (a => v(~alignItems=a, ())),
110 | alignSelf <$> (a => v(~alignSelf=a, ())),
111 | flex <$> (a => v(~flex=a, ())),
112 | flexBasis <$> (a => v(~flexBasis=a, ())),
113 | flexDirection <$> (a => v(~flexDirection=a, ())),
114 | flexGrow <$> (a => v(~flex=a, ())),
115 | flexShrink <$> (a => v(~flexShrink=a, ())),
116 | flexWrap <$> (a => v(~flexWrap=a, ())),
117 | justifyContent <$> (a => v(~justifyContent=a, ())),
118 | // padding
119 | p <$> (p => v(~padding=p, ())),
120 | pt_ <$> (pt_ => v(~paddingTop=pt_, ())), // pt is
121 | pr <$> (pr => v(~paddingRight=pr, ())),
122 | pb <$> (pb => v(~paddingBottom=pb, ())),
123 | pl <$> (pl => v(~paddingLeft=pl, ())),
124 | pv <$> (pv => v(~paddingVertical=pv, ())),
125 | ph <$> (ph => v(~paddingHorizontal=ph, ())),
126 | pe <$> (pe => v(~paddingStart=pe, ())),
127 | ps <$> (ps => v(~paddingEnd=ps, ())),
128 | // margin
129 | m <$> (m => v(~margin=m, ())),
130 | mt <$> (mt => v(~marginTop=mt, ())),
131 | mr <$> (mr => v(~marginRight=mr, ())),
132 | mb <$> (mb => v(~marginBottom=mb, ())),
133 | ml <$> (ml => v(~marginLeft=ml, ())),
134 | mv <$> (mv => v(~marginVertical=mv, ())),
135 | mh <$> (mh => v(~marginHorizontal=mh, ())),
136 | me <$> (me => v(~marginStart=me, ())),
137 | ms <$> (ms => v(~marginEnd=ms, ())),
138 | // size
139 | w <$> (w => v(~width=w, ())),
140 | h <$> (h => v(~height=h, ())),
141 | maxW <$> (w => v(~maxWidth=w, ())),
142 | maxH <$> (h => v(~maxHeight=h, ())),
143 | minW <$> (w => v(~minWidth=w, ())),
144 | minH <$> (h => v(~minHeight=h, ())),
145 | aspectRatio <$> (a => v(~aspectRatio=a, ())),
146 | // position
147 | position <$> (p => v(~position=p, ())),
148 | top <$> (t => v(~top=t, ())),
149 | right <$> (r => v(~right=r, ())),
150 | bottom <$> (b => v(~bottom=b, ())),
151 | left <$> (l => v(~left=l, ())),
152 | start <$> (s => v(~start=s, ())),
153 | end_ <$> (e => v(~_end=e, ())),
154 | // background
155 | bg <$> (bg => v(~backgroundColor=bg, ())),
156 | // opacity
157 | opacity <$> (o => v(~opacity=o, ())),
158 | // borderWidth
159 | borderWidth <$> (b => v(~borderWidth=b, ())),
160 | borderTopWidth <$> (b => v(~borderTopWidth=b, ())),
161 | borderRightWidth <$> (b => v(~borderRightWidth=b, ())),
162 | borderBottomWidth <$> (b => v(~borderBottomWidth=b, ())),
163 | borderLeftWidth <$> (b => v(~borderLeftWidth=b, ())),
164 | borderStartWidth <$> (b => v(~borderStartWidth=b, ())),
165 | borderEndWidth <$> (b => v(~borderEndWidth=b, ())),
166 | // borderRadius
167 | borderRadius <$> (b => v(~borderRadius=b, ())),
168 | borderTopRightRadius <$> (b => v(~borderTopRightRadius=b, ())),
169 | borderTopLeftRadius <$> (b => v(~borderTopLeftRadius=b, ())),
170 | borderTopStartRadius <$> (b => v(~borderTopStartRadius=b, ())),
171 | borderTopEndRadius <$> (b => v(~borderTopEndRadius=b, ())),
172 | borderBottomRightRadius <$> (b => v(~borderBottomRightRadius=b, ())),
173 | borderBottomLeftRadius <$> (b => v(~borderBottomLeftRadius=b, ())),
174 | borderBottomStartRadius <$> (b => v(~borderBottomStartRadius=b, ())),
175 | borderBottomEndRadius <$> (b => v(~borderBottomEndRadius=b, ())),
176 | // borderColor
177 | borderColor <$> (b => v(~borderColor=b, ())),
178 | borderTopColor <$> (b => v(~borderTopColor=b, ())),
179 | borderRightColor <$> (b => v(~borderRightColor=b, ())),
180 | borderBottomColor <$> (b => v(~borderBottomColor=b, ())),
181 | borderLeftColor <$> (b => v(~borderLeftColor=b, ())),
182 | borderStartColor <$> (b => v(~borderStartColor=b, ())),
183 | borderEndColor <$> (b => v(~borderEndColor=b, ())),
184 | // overflow
185 | overflow <$> (o => v(~overflow=o, ())),
186 | // zIndex
187 | zIndex <$> (z => v(~zIndex=z, ())),
188 | // direction
189 | direction <$> (d => v(~direction=d, ())),
190 | // display
191 | display <$> (d => v(~display=d, ())),
192 | // rest
193 | style,
194 | |]);
195 | let reactChildren = {
196 | switch (children) {
197 | | Some(children) => [|children|]
198 | | None => [||]
199 | };
200 | };
201 | ReasonReact.cloneElement(
202 | component,
203 | ~props={"style": resolvedStyle},
204 | reactChildren,
205 | );
206 | };
207 |
208 | [@genType]
209 | let default = make;
--------------------------------------------------------------------------------
/src/box/AnimatedBox.re:
--------------------------------------------------------------------------------
1 | open ReactNative;
2 |
3 | let (>>=) = Belt.Option.flatMap;
4 | let (<$>) = Belt.Option.map;
5 |
6 | [@react.component]
7 | let make =
8 | /* flex */
9 | (
10 | ~alignContent=?,
11 | ~alignItems=?,
12 | ~alignSelf=?,
13 | ~flex=?,
14 | ~flexBasis=?,
15 | ~flexDirection=?,
16 | ~flexGrow=?,
17 | ~flexShrink=?,
18 | ~flexWrap=?,
19 | ~justifyContent=?,
20 | /* padding */
21 | ~p=?,
22 | ~pt=?,
23 | ~pr=?,
24 | ~pl=?,
25 | ~pb=?,
26 | ~pv=?,
27 | ~ph=?,
28 | ~pe=?,
29 | ~ps=?,
30 | /* margin */
31 | ~m=?,
32 | ~mt=?,
33 | ~mr=?,
34 | ~ml=?,
35 | ~mb=?,
36 | ~mv=?,
37 | ~mh=?,
38 | ~me=?,
39 | ~ms=?,
40 | /* position */
41 | ~position=?,
42 | ~top=?,
43 | ~right=?,
44 | ~left=?,
45 | ~bottom=?,
46 | ~start=?,
47 | ~end_=?,
48 | /* size */
49 | ~w=?,
50 | ~h=?,
51 | ~maxW=?,
52 | ~maxH=?,
53 | ~minW=?,
54 | ~minH=?,
55 | ~aspectRatio=?,
56 | /* bg */
57 | ~bg=?,
58 | /* opacity */
59 | ~opacity=?,
60 | /* borderWidth */
61 | ~borderWidth=?,
62 | ~borderTopWidth=?,
63 | ~borderRightWidth=?,
64 | ~borderBottomWidth=?,
65 | ~borderLeftWidth=?,
66 | ~borderStartWidth=?,
67 | ~borderEndWidth=?,
68 | /* borderRadius */
69 | ~borderRadius=?,
70 | ~borderTopRightRadius=?,
71 | ~borderTopLeftRadius=?,
72 | ~borderTopStartRadius=?,
73 | ~borderTopEndRadius=?,
74 | ~borderBottomRightRadius=?,
75 | ~borderBottomLeftRadius=?,
76 | ~borderBottomStartRadius=?,
77 | ~borderBottomEndRadius=?,
78 | /* borderColor */
79 | ~borderColor=?,
80 | ~borderTopColor=?,
81 | ~borderRightColor=?,
82 | ~borderBottomColor=?,
83 | ~borderLeftColor=?,
84 | ~borderStartColor=?,
85 | ~borderEndColor=?,
86 | /* overflow */
87 | ~overflow=?,
88 | /* zIndex */
89 | ~zIndex=?,
90 | /* direction */
91 | ~direction=?,
92 | // display
93 | ~display=?,
94 | /* rest */
95 | ~style=?,
96 | ~children=?,
97 | ~component=,
98 | ) => {
99 | /* theme */
100 | let pt_ = pt;
101 |
102 | // value
103 | let v = Style.viewStyle;
104 |
105 | let resolvedStyle =
106 | Style.arrayOption([|
107 | // flex
108 | alignContent <$> (a => v(~alignContent=a, ())),
109 | alignItems <$> (a => v(~alignItems=a, ())),
110 | alignSelf <$> (a => v(~alignSelf=a, ())),
111 | flex <$> (a => v(~flex=a, ())),
112 | flexBasis <$> (a => v(~flexBasis=a, ())),
113 | flexDirection <$> (a => v(~flexDirection=a, ())),
114 | flexGrow <$> (a => v(~flex=a, ())),
115 | flexShrink <$> (a => v(~flexShrink=a, ())),
116 | flexWrap <$> (a => v(~flexWrap=a, ())),
117 | justifyContent <$> (a => v(~justifyContent=a, ())),
118 | // padding
119 | p <$> (p => v(~padding=p, ())),
120 | pt_ <$> (pt_ => v(~paddingTop=pt_, ())), // pt is
121 | pr <$> (pr => v(~paddingRight=pr, ())),
122 | pb <$> (pb => v(~paddingBottom=pb, ())),
123 | pl <$> (pl => v(~paddingLeft=pl, ())),
124 | pv <$> (pv => v(~paddingVertical=pv, ())),
125 | ph <$> (ph => v(~paddingHorizontal=ph, ())),
126 | pe <$> (pe => v(~paddingStart=pe, ())),
127 | ps <$> (ps => v(~paddingEnd=ps, ())),
128 | // margin
129 | m <$> (m => v(~margin=m, ())),
130 | mt <$> (mt => v(~marginTop=mt, ())),
131 | mr <$> (mr => v(~marginRight=mr, ())),
132 | mb <$> (mb => v(~marginBottom=mb, ())),
133 | ml <$> (ml => v(~marginLeft=ml, ())),
134 | mv <$> (mv => v(~marginVertical=mv, ())),
135 | mh <$> (mh => v(~marginHorizontal=mh, ())),
136 | me <$> (me => v(~marginStart=me, ())),
137 | ms <$> (ms => v(~marginEnd=ms, ())),
138 | // size
139 | w <$> (w => v(~width=w, ())),
140 | h <$> (h => v(~height=h, ())),
141 | maxW <$> (w => v(~maxWidth=w, ())),
142 | maxH <$> (h => v(~maxHeight=h, ())),
143 | minW <$> (w => v(~minWidth=w, ())),
144 | minH <$> (h => v(~minHeight=h, ())),
145 | aspectRatio <$> (a => v(~aspectRatio=a, ())),
146 | // position
147 | position <$> (p => v(~position=p, ())),
148 | top <$> (t => v(~top=t, ())),
149 | right <$> (r => v(~right=r, ())),
150 | bottom <$> (b => v(~bottom=b, ())),
151 | left <$> (l => v(~left=l, ())),
152 | start <$> (s => v(~start=s, ())),
153 | end_ <$> (e => v(~_end=e, ())),
154 | // background
155 | bg <$> (bg => v(~backgroundColor=bg, ())),
156 | // opacity
157 | opacity <$> (o => v(~opacity=o, ())),
158 | // borderWidth
159 | borderWidth <$> (b => v(~borderWidth=b, ())),
160 | borderTopWidth <$> (b => v(~borderTopWidth=b, ())),
161 | borderRightWidth <$> (b => v(~borderRightWidth=b, ())),
162 | borderBottomWidth <$> (b => v(~borderBottomWidth=b, ())),
163 | borderLeftWidth <$> (b => v(~borderLeftWidth=b, ())),
164 | borderStartWidth <$> (b => v(~borderStartWidth=b, ())),
165 | borderEndWidth <$> (b => v(~borderEndWidth=b, ())),
166 | // borderRadius
167 | borderRadius <$> (b => v(~borderRadius=b, ())),
168 | borderTopRightRadius <$> (b => v(~borderTopRightRadius=b, ())),
169 | borderTopLeftRadius <$> (b => v(~borderTopLeftRadius=b, ())),
170 | borderTopStartRadius <$> (b => v(~borderTopStartRadius=b, ())),
171 | borderTopEndRadius <$> (b => v(~borderTopEndRadius=b, ())),
172 | borderBottomRightRadius <$> (b => v(~borderBottomRightRadius=b, ())),
173 | borderBottomLeftRadius <$> (b => v(~borderBottomLeftRadius=b, ())),
174 | borderBottomStartRadius <$> (b => v(~borderBottomStartRadius=b, ())),
175 | borderBottomEndRadius <$> (b => v(~borderBottomEndRadius=b, ())),
176 | // borderColor
177 | borderColor <$> (b => v(~borderColor=b, ())),
178 | borderTopColor <$> (b => v(~borderTopColor=b, ())),
179 | borderRightColor <$> (b => v(~borderRightColor=b, ())),
180 | borderBottomColor <$> (b => v(~borderBottomColor=b, ())),
181 | borderLeftColor <$> (b => v(~borderLeftColor=b, ())),
182 | borderStartColor <$> (b => v(~borderStartColor=b, ())),
183 | borderEndColor <$> (b => v(~borderEndColor=b, ())),
184 | // overflow
185 | overflow <$> (o => v(~overflow=o, ())),
186 | // zIndex
187 | zIndex <$> (z => v(~zIndex=z, ())),
188 | // direction
189 | direction <$> (d => v(~direction=d, ())),
190 | // display
191 | display <$> (d => v(~display=d, ())),
192 | // rest
193 | style,
194 | |]);
195 | let reactChildren = {
196 | switch (children) {
197 | | Some(children) => [|children|]
198 | | None => [||]
199 | };
200 | };
201 | ReasonReact.cloneElement(
202 | component,
203 | ~props={"style": resolvedStyle},
204 | reactChildren,
205 | );
206 | };
207 |
208 | [@genType]
209 | let default = make;
--------------------------------------------------------------------------------