├── 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; --------------------------------------------------------------------------------