diff --git a/package.json b/package.json index b33593a..ed4a579 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "galio-framework", "main": "src/index.js", - "version": "0.6.3", + "version": "0.7.0", "files": [ "src/" ], diff --git a/src/Accordion.js b/src/Accordion.js index c496abd..bef1f20 100644 --- a/src/Accordion.js +++ b/src/Accordion.js @@ -9,8 +9,8 @@ import { import PropTypes from "prop-types"; import Block from "./Block"; -import Icon from "./Icon"; -import Text from "./Text"; +import Icon from "./atomic/ions/Icon"; +import Text from "./atomic/ions/Text"; import GalioTheme from "./theme"; const { width } = Dimensions.get("screen"); diff --git a/src/Avatar.js b/src/Avatar.js new file mode 100644 index 0000000..d331fbd --- /dev/null +++ b/src/Avatar.js @@ -0,0 +1,109 @@ +import React from 'react'; +import { View, Text, StyleSheet, Image, ViewPropTypes } from 'react-native'; +import PropTypes from 'prop-types'; +import { withGalio } from 'theme'; + +const Avatar = ({ + source, + size, + label, + labelColor, + backgroundColor, + labelStyle, + imageProps, + imageStyle, + containerStyle, + styles, + theme, +}) => { + const getContainerStyle = () => { + return { + width: size, + height: size, + alignItems: 'center', + justifyContent: 'center', + borderRadius: size / 2, + }; + }; + + const getLabelContainerStyle = () => { + return { + ...StyleSheet.absoluteFillObject, + alignItems: 'center', + justifyContent: 'center', + borderRadius: size / 2, + }; + }; + + const renderImage = () => { + if (source) { + return ( + + ); + } + return null; + }; + + const labelContainerStyle = [ + getLabelContainerStyle(), + source && styles.labelContainerWithInset, + { backgroundColor: backgroundColor || theme.COLORS.MUTED }, + ]; + + const labelTextStyle = [ + { fontSize: size * 0.32 }, + styles.labelText, + labelColor && { color: labelColor }, + labelStyle || {}, + ]; + + return ( + + + {label && ( + + {label} + + )} + + {renderImage()} + + ); +}; + +Avatar.defaultProps = { + size: 50, +}; + +Avatar.propTypes = { + label: PropTypes.string, + labelColor: PropTypes.string, + size: PropTypes.number, + source: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), + backgroundColor: PropTypes.string, + imageProps: PropTypes.object, + imageStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array, PropTypes.number]), + containerStyle: ViewPropTypes.style, + styles: PropTypes.any, + theme: PropTypes.any, +}; + +const styles = theme => + StyleSheet.create({ + labelContainerWithInset: { + top: 1, + right: 1, + bottom: 1, + left: 1, + }, + labelText: { + color: theme.COLORS.BLACK, + backgroundColor: 'transparent', + }, + }); + +export default withGalio(Avatar, styles); diff --git a/src/Card.js b/src/Card.js index 6e0ecee..21ea20e 100644 --- a/src/Card.js +++ b/src/Card.js @@ -2,8 +2,10 @@ import React from 'react'; import { Image, StyleSheet } from 'react-native'; import PropTypes from 'prop-types'; - -import { Block, Icon, Text } from './'; +// galio components +import Block from './Block'; +import Text from './Text'; +import Icon from './Icon'; import GalioTheme, { withGalio } from './theme'; function Card({ diff --git a/src/Checkbox.js b/src/Checkbox.js index c1793af..db99967 100644 --- a/src/Checkbox.js +++ b/src/Checkbox.js @@ -3,7 +3,8 @@ import React from 'react'; import { View, TouchableOpacity, StyleSheet, Image } from 'react-native'; import PropTypes from 'prop-types'; // galio dependency -import { Icon, Text } from './'; +import Icon from './Icon'; +import Text from './Text'; import GalioTheme, { withGalio } from './theme'; function Checkbox({ @@ -26,9 +27,7 @@ function Checkbox({ theme, }) { const [checked, setChecked] = React.useState(initialValue); - React.useEffect(() => { - onChange(checked); - }, [checked]); + // adding the necessary margins depending on the flexDirection function spaceAround(direction) { switch (direction) { @@ -73,8 +72,9 @@ function Checkbox({ // onPress function that changes the component's state and callbacks the onChange prop function _onPress() { - setChecked(!checked); - return null; + const current = !checked; + onChange(current); + setChecked(current); } const colorStyle = theme.COLORS[color.toUpperCase()]; // this sets the correct color for the theme file diff --git a/src/NavBar.js b/src/NavBar.js index 4b411f4..afcd2f0 100644 --- a/src/NavBar.js +++ b/src/NavBar.js @@ -3,7 +3,9 @@ import { View, TouchableOpacity, StyleSheet, Dimensions } from 'react-native'; import PropTypes from 'prop-types'; // galio components -import { Block, Text, Icon } from './'; +import Block from './Block'; +import Text from './Text'; +import Icon from './Icon'; import GalioTheme, { withGalio } from './theme'; const { height } = Dimensions.get('screen'); @@ -16,6 +18,7 @@ function NavBar({ leftStyle, leftIconColor, leftHitSlop, + leftIconSize, leftIconName, leftIconFamily, onLeftPress, @@ -44,14 +47,14 @@ function NavBar({ function renderLeft() { if (!hideLeft) { - if (leftIconName || back) { + if (leftIconName || back && !left) { return ( onLeftPress && onLeftPress()} hitSlop={leftHitSlop}> diff --git a/src/Radio.js b/src/Radio.js index 5b877d9..5a32d64 100644 --- a/src/Radio.js +++ b/src/Radio.js @@ -2,7 +2,7 @@ import React from 'react'; import { View, TouchableOpacity, StyleSheet } from 'react-native'; import PropTypes from 'prop-types'; // G A L I O - D E P E N D E N C Y -import { Text } from './'; +import Text from './Text'; import GalioTheme, { withGalio } from './theme'; function Radio({ @@ -20,7 +20,7 @@ function Radio({ theme, }) { const [checked, setChecked] = React.useState(initialValue); - React.useEffect(() => onChange(checked), [checked]); + // A D D I N G - R E Q U I R E D - S P A C E (S) - B A S E D - O N - F L E X - D I R E C T I O N function spaceAround(direction) { switch (direction) { @@ -53,7 +53,9 @@ function Radio({ // O N - P R E S S - H A N D L E R function radioPressHandler() { - setChecked(!checked); + const current = !checked; + onChange(current); + setChecked(current); } diff --git a/src/Switch.js b/src/Switch.js index 2a21850..18aa8e6 100644 --- a/src/Switch.js +++ b/src/Switch.js @@ -13,9 +13,6 @@ function Switch({ ...rest }) { const [switchValue, setSwitchValue] = React.useState(initialValue); - React.useEffect(() => { - onChange(switchValue); - }, [switchValue]); function onPressSwitch() { setSwitchValue(!switchValue); return null; @@ -27,11 +24,12 @@ function Switch({ { onPressSwitch(); }} + onChange={() => onChange()} {...rest} /> ); diff --git a/src/Toast.js b/src/Toast.js index 343fb97..9358809 100644 --- a/src/Toast.js +++ b/src/Toast.js @@ -2,7 +2,7 @@ import React, { Component } from 'react'; import { Dimensions, StyleSheet, Animated, ViewPropTypes } from 'react-native'; import PropTypes from 'prop-types'; // galio components -import { Text } from '.'; +import Text from './Text'; import GalioTheme, { withGalio } from './theme'; const { height } = Dimensions.get('screen'); diff --git a/src/Button.js b/src/atomic/atoms/Button.js similarity index 70% rename from src/Button.js rename to src/atomic/atoms/Button.js index 7338431..4121ff0 100644 --- a/src/Button.js +++ b/src/atomic/atoms/Button.js @@ -2,8 +2,8 @@ import React from 'react'; import { ActivityIndicator, Dimensions, StyleSheet, TouchableOpacity, Text } from 'react-native'; import PropTypes from 'prop-types'; // galio components -import { Icon } from './'; -import GalioTheme, { withGalio } from './theme'; +import Icon from '../ions/Icon'; +import GalioTheme, { withGalio } from '../../theme'; const { width } = Dimensions.get('window'); @@ -14,6 +14,7 @@ function Button({ disabled, iconSize, icon, + iconRight, iconFamily, iconColor, loading, @@ -22,7 +23,6 @@ function Button({ onlyIcon, opacity, round, - radius, style, size, shadowless, @@ -49,13 +49,40 @@ function Button({ content = `${children.charAt(0).toUpperCase()}${children.slice(1)}`; } + if (icon && !onlyIcon && !iconRight) { + content = ( + <> + {' '} + {content} + + ); + } ; + if (iconRight && !onlyIcon) { + content = ( + <> + {content}{' '} + + + ); + }; + if (onlyIcon) { content = ( ); } else if (isString) { @@ -77,15 +104,15 @@ function Button({ color && !colorStyle && { backgroundColor: color }, // color set & no styles for that color color === 'transparent' || styles.androidShadow, color === 'transparent' && !shadowless && { borderWidth: 1, borderColor: theme.COLORS.WHITE }, - size === 'large' ? { width: width * 0.9 } : { width: width * 0.5 }, + size === 'large' ? { width: width * 0.9 } : ( size === "small" ? { width: width * 0.3 } : { width: width * 0.42 }), round && { borderRadius: theme.SIZES.BASE * 2 }, + onlyIcon && { - width: iconSize * 1.25, - height: iconSize * 2, + width: iconSize * 2.75, + height: iconSize * 2.75, borderWidth: 0, - borderRadius: iconSize, + borderRadius: iconSize * 2, }, - radius && { borderRadius: radius }, !shadowless && styles.shadow, { shadowColor: shadowColor || theme.COLORS[color.toUpperCase()] }, { zIndex: 2 }, @@ -101,9 +128,8 @@ function Button({ Button.defaultProps = { color: 'primary', - size: 'large', + size: 'default', disabled: false, - radius: 0, uppercase: false, lowercase: false, capitalize: false, @@ -112,10 +138,11 @@ Button.defaultProps = { onlyIcon: false, loading: false, loadingSize: 'small', - opacity: 0.8, + opacity: .8, icon: false, + iconRight: false, iconFamily: false, - iconSize: 14, + iconSize: 16, iconColor: null, styles: {}, theme: GalioTheme, @@ -124,23 +151,25 @@ Button.defaultProps = { Button.propTypes = { ...TouchableOpacity.propTypes, color: PropTypes.oneOfType([ - PropTypes.oneOf(['primary', 'theme', 'error', 'warning', 'success', 'transparent', 'info']), + PropTypes.oneOf([ + 'theme', 'primary', 'info', 'danger', 'warning', 'success', 'black', 'grey', 'secondary', 'transparent', 'white', + ]), PropTypes.string, ]), - size: PropTypes.oneOfType([PropTypes.oneOf(['large', 'small']), PropTypes.number]), + size: PropTypes.oneOfType([PropTypes.oneOf(['large', 'default', 'small']), PropTypes.number]), iconColor: PropTypes.string, disabled: PropTypes.bool, - radius: PropTypes.number, uppercase: PropTypes.bool, lowercase: PropTypes.bool, capitalize: PropTypes.bool, loading: PropTypes.bool, - loadingSize: PropTypes.oneOf(['small', 'large']), + loadingSize: PropTypes.oneOf(['small', 'default', 'large']), opacity: PropTypes.number, shadowless: PropTypes.bool, shadowColor: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]), onlyIcon: PropTypes.bool, icon: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]), + iconRight: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), iconFamily: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]), iconSize: PropTypes.number, styles: PropTypes.any, @@ -150,15 +179,16 @@ Button.propTypes = { const styles = theme => StyleSheet.create({ defaultButton: { - borderRadius: 3, + borderRadius: 4, width: theme.SIZES.BUTTON_WIDTH, height: theme.SIZES.BUTTON_HEIGHT, alignItems: 'center', justifyContent: 'center', + margin: 8 }, shadow: { shadowColor: theme.COLORS.BLOCK, - shadowOffset: { width: 0, height: 4 }, + shadowOffset: { width: 0, height: 2 }, shadowOpacity: theme.SIZES.OPACITY, shadowRadius: theme.SIZES.BUTTON_SHADOW_RADIUS, }, @@ -166,17 +196,17 @@ const styles = theme => fontSize: theme.SIZES.FONT, color: theme.COLORS.WHITE, }, - primary: { - backgroundColor: theme.COLORS.PRIMARY, - }, theme: { backgroundColor: theme.COLORS.THEME, }, + primary: { + backgroundColor: theme.COLORS.PRIMARY, + }, info: { backgroundColor: theme.COLORS.INFO, }, - error: { - backgroundColor: theme.COLORS.ERROR, + danger: { + backgroundColor: theme.COLORS.DANGER, }, warning: { backgroundColor: theme.COLORS.WARNING, @@ -184,6 +214,18 @@ const styles = theme => success: { backgroundColor: theme.COLORS.SUCCESS, }, + white: { + backgroundColor: theme.COLORS.WHITE, + }, + black: { + backgroundColor: theme.COLORS.BLACK, + }, + secondary: { + backgroundColor: theme.COLORS.SECONDARY, + }, + grey: { + backgroundColor: theme.COLORS.GREY, + }, transparent: { backgroundColor: theme.COLORS.TRANSPARENT, }, diff --git a/src/Input.js b/src/atomic/atoms/Input.js similarity index 82% rename from src/Input.js rename to src/atomic/atoms/Input.js index eba00ae..144937b 100644 --- a/src/Input.js +++ b/src/atomic/atoms/Input.js @@ -1,16 +1,19 @@ import React from 'react'; import { View, Text, TextInput, StyleSheet, TouchableOpacity } from 'react-native'; import PropTypes from 'prop-types'; -import Icon from './Icon'; -import GalioTheme, { withGalio } from './theme'; +import Icon from '../ions/Icon'; +import GalioTheme, { withGalio } from '../../theme'; function Input({ style, + textInputStyle, type, placeholderTextColor, label, + labelStyles, color, help, + helpStyles, bgColor, borderless, viewPass, @@ -27,6 +30,8 @@ function Input({ iconSize, iconContent, password, + onRef, + error, ...rest }) { const [isPassword, setIsPassword] = React.useState(false); @@ -40,15 +45,16 @@ function Input({ bgColor && { backgroundColor: bgColor }, rounded && styles.rounded, borderless && styles.borderless, + error && { borderColor: theme.COLORS.DANGER}, style, ]; - const inputStyles = [ styles.inputView, borderless && icon && styles.inputIcon, styles.inputText, color && { color }, + textInputStyle || {} ]; const iconInstance = icon ? ( @@ -56,12 +62,12 @@ function Input({ name={icon} family={family} size={iconSize || theme.SIZES.BASE * 1.0625} - style={{ marginRight: left && !right ? theme.SIZES.BASE * 0.2 : 0 }} - color={iconColor || placeholderTextColor || theme.COLORS.PLACEHOLDER} + style={{ marginRight: left && !right ? 4 : 0 }} + color={(error && theme.COLORS.DANGER) || iconColor || placeholderTextColor || theme.COLORS.PLACEHOLDER} /> ) : ( - iconContent - ); + iconContent + ); const viewPassElement = password && viewPass && ( setIsPassword(!isPassword)}> @@ -73,8 +79,8 @@ function Input({ /> ); - const lebelContent = label && {label}; - const helpContent = help && {help}; + const labelContent = label && {label}; + const helpContent = help && {help}; return ( - {lebelContent} + {labelContent} {topHelp && !bottomHelp && helpContent} {left && !right && iconInstance} label: { fontWeight: '500', fontSize: theme.SIZES.INPUT_LABEL_TEXT, - marginBottom: theme.SIZES.INPUT_LABEL_BOTTOM, + marginVertical: theme.SIZES.INPUT_VERTICAL_LABEL, + paddingHorizontal: theme.SIZES.INPUT_HORIZONTAL }, helpText: { + color: theme.COLORS.SECONDARY, fontSize: theme.SIZES.INPUT_HELP_TEXT, - fontStyle: 'italic', + marginVertical: 8, + paddingHorizontal: 16, + fontSize: 14 }, rounded: { borderRadius: theme.SIZES.INPUT_ROUNDED, diff --git a/src/atomic/atoms/Link.js b/src/atomic/atoms/Link.js new file mode 100644 index 0000000..bf85d3d --- /dev/null +++ b/src/atomic/atoms/Link.js @@ -0,0 +1,33 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import Text from '../ions/Text'; +import GalioTheme, { withGalio } from '../../theme'; + +function Link({ + children, + onPress, + theme, + ...rest + }) { + return ( + onPress()} + {...rest}> + {children} + + ); + } + + Link.defaultProps = { + children: null, + theme: GalioTheme, + }; + + Link.propTypes = { + children: PropTypes.any, + theme: PropTypes.any, + onPress: PropTypes.func.isRequired, + }; + +export default withGalio(Link); \ No newline at end of file diff --git a/src/Icon.js b/src/atomic/ions/Icon.js similarity index 70% rename from src/Icon.js rename to src/atomic/ions/Icon.js index 43ef204..61058b1 100644 --- a/src/Icon.js +++ b/src/atomic/ions/Icon.js @@ -2,9 +2,9 @@ import React from 'react'; import { createIconSetFromIcoMoon } from 'react-native-vector-icons'; import PropTypes from 'prop-types'; -import GalioTheme, { withGalio } from './theme'; -import getIconType from './helpers/getIconType'; -import galioConfig from './config/galio.json'; +import GalioTheme, { withGalio } from '../../theme'; +import getIconType from '../../helpers/getIconType'; +import galioConfig from '../../config/galio.json'; const Galio = createIconSetFromIcoMoon(galioConfig, 'Galio', './fonts/galio.ttf'); @@ -19,6 +19,8 @@ function Icon({ color, styles, theme, + medium, + large, ...rest }) { if (family === 'Galio') { @@ -26,8 +28,8 @@ function Icon({ return ( ); @@ -38,8 +40,8 @@ function Icon({ return ( ); diff --git a/src/Text.js b/src/atomic/ions/Text.js similarity index 79% rename from src/Text.js rename to src/atomic/ions/Text.js index 2e93d4f..1dff5e4 100644 --- a/src/Text.js +++ b/src/atomic/ions/Text.js @@ -2,8 +2,8 @@ import React from 'react'; import { Text } from 'react-native'; import PropTypes from 'prop-types'; -import normalize from './helpers/normalize'; -import GalioTheme, { withGalio } from './theme'; +import normalize from '../../helpers/normalize'; +import GalioTheme, { withGalio } from '../../theme'; function Typography({ style, @@ -12,7 +12,10 @@ function Typography({ h3, h4, h5, + h6, p, + body, + small, muted, neutral, size, @@ -32,8 +35,11 @@ function Typography({ h2 && { fontSize: normalize(38) }, h3 && { fontSize: normalize(30) }, h4 && { fontSize: normalize(24) }, - h5 && { fontSize: normalize(18) }, + h5 && { fontSize: normalize(21) }, + h6 && { fontSize: normalize(18) }, p && { fontSize: normalize(16) }, + body && { fontSize: normalize(14) }, + small && { fontSize: normalize(12) }, muted && { color: theme.COLORS.MUTED }, neutral && { color: theme.COLORS.NEUTRAL }, size && { fontSize: size }, @@ -57,7 +63,10 @@ Typography.defaultProps = { h3: false, h4: false, h5: false, + h6: false, p: false, + body: false, + small: false, size: 0, color: null, muted: false, @@ -75,7 +84,10 @@ Typography.propTypes = { h3: PropTypes.bool, h4: PropTypes.bool, h5: PropTypes.bool, + h6: PropTypes.bool, p: PropTypes.bool, + body: PropTypes.bool, + small: PropTypes.bool, size: PropTypes.number, color: PropTypes.string, muted: PropTypes.bool, diff --git a/src/index.js b/src/index.js index 0a6004b..f98b1da 100644 --- a/src/index.js +++ b/src/index.js @@ -3,20 +3,22 @@ import Accordion from './Accordion'; import Block from './Block'; -import Button from './Button'; +import Button from './atomic/atoms/Button'; import Card from './Card'; import Checkbox from './Checkbox'; import DeckSwiper from './DeckSwiper'; -import Icon from './Icon'; -import Input from './Input'; +import Icon from './atomic/ions/Icon'; +import Input from './atomic/atoms/Input'; import NavBar from './NavBar'; import Radio from './Radio'; import Slider from './Slider'; import Switch from './Switch'; -import Text from './Text'; +import Text from './atomic/ions/Text'; import Toast from './Toast'; +import Link from './atomic/atoms/Link'; -import theme, { withGalio, GalioProvider } from './theme'; + +import theme, { withGalio, GalioProvider, useGalioTheme } from './theme'; import galioConfig from './config/galio.json'; @@ -35,11 +37,13 @@ export { Radio, Slider, Text, + Link, Toast, Switch, theme, withGalio, GalioProvider, + useGalioTheme, galioConfig, GalioFont, }; diff --git a/src/theme/README.md b/src/theme/README.md index a64dbf5..a07a07e 100644 --- a/src/theme/README.md +++ b/src/theme/README.md @@ -12,8 +12,8 @@ - custom theme constants will **overwrite** the default galio theme constants ```js const customTheme = { - SIZES: { BASE: 18, } // this will overwrite the Galio SIZES BASE value 16 - COLORS: { PRIMARY: 'red', } // this will overwrite the Galio COLORS PRIMARY color #B23AFC + SIZES: { BASE: 16, } // this will overwrite the Galio SIZES BASE value 16 + COLORS: { PRIMARY: 'red', } // this will overwrite the Galio COLORS PRIMARY color #FE2472 }; @@ -32,76 +32,113 @@ FACEBOOK | #3B5998 | ![](https://dummyimage.com/40x12/3B5998/000000.png&text=+) TWITTER | #5BC0DE | ![](https://dummyimage.com/40x12/5BC0DE/000000.png&text=+) For social Twitter button DRIBBBLE | #EA4C89 | ![](https://dummyimage.com/40x12/EA4C89/000000.png&text=+) For social Dribble button **GALIO** | -THEME | #B23AFC | ![](https://dummyimage.com/40x12/B23AFC/000000.png&text=+) Theme default color -PRIMARY | #B23AFC | ![](https://dummyimage.com/40x12/B23AFC/000000.png&text=+) Primary color for Buttons -INFO | #1232FF | ![](https://dummyimage.com/40x12/1232FF/000000.png&text=+) Info color for Buttons & Text -ERROR | #FE2472 | ![](https://dummyimage.com/40x12/FE2472/000000.png&text=+) Info color for error messages -WARNING | #FF9C09 | ![](https://dummyimage.com/40x12/FF9C09/000000.png&text=+) Warning color for warning messages -SUCCESS | #45DF31 | ![](https://dummyimage.com/40x12/45DF31/000000.png&text=+) Success color for success messages -**COMPONENTS** | -INPUT | #808080 | ![](https://dummyimage.com/40x12/808080/000000.png&text=+) Input backgroundColor -PLACEHOLDER | #9FA5AA | ![](https://dummyimage.com/40x12/9FA5AA/000000.png&text=+) Input placeholder text color -NAVBAR | #F9F9F9 | ![](https://dummyimage.com/40x12/F9F9F9/000000.png&text=+) NavBar text color -BLOCK | #808080 | ![](https://dummyimage.com/40x12/808080/000000.png&text=+) Block border color -ICON | #000000 | ![](https://dummyimage.com/40x12/000000/000000.png&text=+) Icon default color +THEME | #FE2472 | ![](https://dummyimage.com/40x12/FE2472/000000.png&text=+) Theme default color +PRIMARY | #FE2472 | ![](https://dummyimage.com/40x12/FE2472/000000.png&text=+) Primary color for Buttons & Text +DARK_PRIMARY | #F4075C | ![](https://dummyimage.com/40x12/F4075C/000000.png&text=+) Dark Primary color +LIGHT_PRIMARY | #FF8AB9 | ![](https://dummyimage.com/40x12/FF8AB9/000000.png&text=+) Light Primary color +BRIGHT_PRIMARY | #FFD1E4 | ![](https://dummyimage.com/40x12/FFD1E4/000000.png&text=+) Bright Primary color +INFO | #0E2ADD | ![](https://dummyimage.com/40x12/0E2ADD/000000.png&text=+) Info color for Buttons & Text +DARK_INFO | #0520D0 | ![](https://dummyimage.com/40x12/0520D0/000000.png&text=+) Dark Info color +LIGHT_INFO | #8794FF | ![](https://dummyimage.com/40x12/8794FF/000000.png&text=+) Light Info color +BRIGHT_INFO | #D1D6FF | ![](https://dummyimage.com/40x12/D1D6FF/000000.png&text=+) Bright Info color +DANGER | #FF3F31 | ![](https://dummyimage.com/40x12/FF3F31/000000.png&text=+) Danger color for Buttons & Text +DARK_DANGER | #F43324 | ![](https://dummyimage.com/40x12/F43324/000000.png&text=+) Dark Danger color +LIGHT_DANGER | #FF7167 | ![](https://dummyimage.com/40x12/FF7167/000000.png&text=+) Light Danger color +BRIGHT_DANGER | #FFCAC6 | ![](https://dummyimage.com/40x12/FFCAC6/000000.png&text=+) Bright Danger color +WARNING | #FF9C09 | ![](https://dummyimage.com/40x12/FF9C09/000000.png&text=+) Warning color for Buttons & Text +DARK_WARNING | #EE8E00 | ![](https://dummyimage.com/40x12/EE8E00/000000.png&text=+) Dark Warning color +LIGHT_WARNING | #FFCC76 | ![](https://dummyimage.com/40x12/FFCC76/000000.png&text=+) Light Warning color +BRIGHT_WARNING | #FFEBCB | ![](https://dummyimage.com/40x12/FFEBCB/000000.png&text=+) Bright Warning color +SUCCESS | #18CE0F | ![](https://dummyimage.com/40x12/18CE0F/000000.png&text=+) Success color for Buttons & Text +DARK_SUCCESS | #24AD12 | ![](https://dummyimage.com/40x12/24AD12/000000.png&text=+) Dark Success color +LIGHT_SUCCESS | #88F38E | ![](https://dummyimage.com/40x12/88F38E/000000.png&text=+) Light Success color +BRIGHT_SUCCESS | #D2FBD3 | ![](https://dummyimage.com/40x12/D2FBD3/000000.png&text=+) Bright Success color **STANDARD** | WHITE | #FFFFFF | ![](https://dummyimage.com/40x12/FFFFFF/000000.png&text=+) White color -BLACK | #000000 | ![](https://dummyimage.com/40x12/000000/000000.png&text=+) Black color -GREY | #898989 | ![](https://dummyimage.com/40x12/898989/000000.png&text=+) Grey color -MUTED | #9FA5AA | ![](https://dummyimage.com/40x12/9FA5AA/000000.png&text=+) Text muted color +BLACK | #161D28 | ![](https://dummyimage.com/40x12/161D28/000000.png&text=+) Black color +DARK_BLACK | #000B19 | ![](https://dummyimage.com/40x12/000B19/000000.png&text=+) Dark Black color +LIGHT_BLACK | #2A2F36 | ![](https://dummyimage.com/40x12/2A2F36/000000.png&text=+) Light Black color +BRIGHT_BLACK | #3D4144 | ![](https://dummyimage.com/40x12/3D4144/000000.png&text=+) Bright Black color +SECONDARY | #9FA5AA | ![](https://dummyimage.com/40x12/9FA5AA/000000.png&text=+) Grey color +DARK_SECONDARY | #62676B | ![](https://dummyimage.com/40x12/62676B/000000.png&text=+) Dark Black color +LIGHT_SECONDARY | #D6DADD | ![](https://dummyimage.com/40x12/D6DADD/000000.png&text=+) Light Black color +BRIGHT_SECONDARY | #EEF1F3 | ![](https://dummyimage.com/40x12/EEF1F3/000000.png&text=+) Bright Black color +GREY | #E9EBEF | ![](https://dummyimage.com/40x12/E9EBEF/000000.png&text=+) Text muted color +DARK_GREY | #E0E4EA | ![](https://dummyimage.com/40x12/E0E4EA/000000.png&text=+) Dark Black color +LIGHT_GREY | #F0F1F4 | ![](https://dummyimage.com/40x12/F0F1F4/000000.png&text=+) Light Black color +BRIGHT_GREY | #F7F8F9 | ![](https://dummyimage.com/40x12/F7F8F9/000000.png&text=+) Bright Black color TRANSPARENT | transparent | Transparent value for Block, Button and other components NEUTRAL | rgba(255,255,255, 0.65) | Text neutral color white with 65% transparency +**SHADOWS** | +PRIMARY | 0 13px 11px -8 rgba(254, 36, 114, .30) | ![](https://dummyimage.com/40x12/fe2472/000000.png&text=+) Primary shadow +INFO | 0 13px 11px -8 rgba(14, 42, 221, .30) | ![](https://dummyimage.com/40x12/0E2ADD/000000.png&text=+) Info shadow +SUCCESS | 0 13px 11px -8 rgba(24, 206, 15, .30) | ![](https://dummyimage.com/40x12/18CE0F/000000.png&text=+) Success shadow +WARNING | 0 13px 11px -8 rgba(255, 156, 9, .30) | ![](https://dummyimage.com/40x12/FF9C09/000000.png&text=+) Warning shadow +DANGER | 0 13px 11px -8 rgba(255, 63, 49, .30) | ![](https://dummyimage.com/40x12/FF3F31/000000.png&text=+) Danger shadow +BLACK | 0 13px 11px -8 rgba(0, 0, 0, .30) | ![](https://dummyimage.com/40x12/161D28/000000.png&text=+) Black shadow +WHITE | 0 10px 20px -8 rgba(210, 210, 210, .100) | ![](https://dummyimage.com/40x12/FFFFFF/000000.png&text=+) White shadow +GREY | 0 13px 11px -8 rgba(152, 152, 152, .30) | ![](https://dummyimage.com/40x12/9FA5AA/000000.png&text=+) Grey shadow +LIGHT GREY | 0 13px 11px -8 rgba(149, 149, 149, .30) | ![](https://dummyimage.com/40x12/E9EBEF/000000.png&text=+) Light Grey shadow + #### SIZES reference table `const { height, width } = Dimensions.get('screen');` By default the size of **16** is used to calculate all the sizes **Size name** | **Default value** -:--- | :---: -**THEME** | -BASE | 16 | -FONT | 16 | -ICON | 16 | -OPACITY | 0.8 | -BORDER_RADIUS | 6 | -BORDER_WIDTH | 0.8 | -**BUTTON** | -BUTTON_WIDTH | 16 * 9 | -BUTTON_HEIGHT | 16 * 2.75 | -BUTTON_SHADOW_RADIUS | 10 | +:--- | :---: +**THEME** | +BASE | 16 | +PARAGRAPH | 16 | +ICON | 16 | +H1 | 16 * 2,75 | +H2 | 16 * 2,375 | +H3 | 16 * 1,875 | +H4 | 16 * 1,5 | +H5 | 16 * 1,3125 | +H6 | 16 * 1,125 | +BODY | 16 * 0,875 | +SMALL| 16 * 0,75 | +OPACITY | 0.8 | +BORDER_RADIUS | 4 | +BORDER_WIDTH | 1 | +**BUTTON** | +BUTTON_WIDTH | 16 * 9 | +BUTTON_HEIGHT | 16 * 2.75 | +BUTTON_SHADOW_RADIUS | {x: 0 , y: 13, blur: 11, spread: -8 } | **BLOCK** | -BLOCK_SHADOW_OPACITY | 0.15 | -BLOCK_SHADOW_RADIUS | 8 | +BLOCK_SHADOW_OPACITY | 0.15 | +BLOCK_SHADOW_RADIUS | 8 | ANDROID_ELEVATION | 1 | -**CARD** | -CARD_BORDER_RADIUS | 16 * 0.4 | -CARD_BORDER_WIDTH | 16 * 0.05 | -CARD_WIDTH | width - (16 * 2) | -CARD_MARGIN_VERTICAL | 16 * 0.875 | -CARD_FOOTER_HORIZONTAL | 16 * 0.75 | -CARD_FOOTER_VERTICAL | 16 * 0.75 | -CARD_AVATAR_WIDTH | 16 * 2.5 | -CARD_AVATAR_HEIGHT | 16 * 2.5 | -CARD_AVATAR_RADIUS | 16 * 1.25 | -CARD_IMAGE_HEIGHT | 16 * 12.5 | -CARD_ROUND | 16 * 0.1875 | -CARD_ROUNDED | 16 * 0.5 | -**INPUT** | -INPUT_BORDER_RADIUS | 16 * 0.5 | -INPUT_BORDER_WIDTH | 16 * 0.05 | +**CARD** | +CARD_BORDER_RADIUS | 16 * 0.4 | +CARD_BORDER_WIDTH | 16 * 0.05 | +CARD_WIDTH | width - (16 * 2) | +CARD_MARGIN_VERTICAL | 16 * 0.875 | +CARD_FOOTER_HORIZONTAL | 16 * 0.75 | +CARD_FOOTER_VERTICAL | 16 * 0.75 | +CARD_AVATAR_WIDTH | 16 * 2.5 | +CARD_AVATAR_HEIGHT | 16 * 2.5 | +CARD_AVATAR_RADIUS | 16 * 1.25 | +CARD_IMAGE_HEIGHT | 16 * 12.5 | +CARD_ROUND | 16 * 0.1875 | +CARD_ROUNDED | 16 * 0.5 | +**INPUT** | +INPUT_BORDER_RADIUS | 16 * 0.25 | +INPUT_BORDER_WIDTH | 16 * 0.0625 | INPUT_HEIGHT | 16 * 2.75 | -INPUT_HORIZONTAL | 16 | -INPUT_TEXT | 16 * 0.875 | -INPUT_LABEL_TEXT | 16 * 0.9 | -INPUT_LABEL_BOTTOM | 16 / 4 | -INPUT_HELP_TEXT | 16 * 0.8 | -INPUT_ROUNDED | 16 * 1.7 | +INPUT_PADDING_HORIZONTAL | 16 | +INPUT_TEXT | 14 | +INPUT_LABEL | 14 | +INPUT_LABEL_MARGIN_BOTTOM | 16 * 0.5 | +INPUT_HELP_TEXT | 14 | +INPUT_ROUNDED | 16 * 1.5 | **NAVBAR** | NAVBAR_HEIGHT | 16 * 4.125 | NAVBAR_VERTICAL | 16 | NAVBAR_TITLE_FLEX | 2 | NAVBAR_TITLE_HEIGHT | height * 0.07 | -NAVBAR_TITLE_TEXT | 16 * 0.875 | +NAVBAR_TITLE_TEXT | 14 | NAVBAR_LEFT_FLEX | 0.5 | NAVBAR_LEFT_HEIGHT | height * 0.07 | NAVBAR_LEFT_MARGIN | 16 | diff --git a/src/theme/colors.js b/src/theme/colors.js index 4db73e5..498c051 100644 --- a/src/theme/colors.js +++ b/src/theme/colors.js @@ -5,14 +5,55 @@ export const SOCIAL = { }; export const THEME = { - THEME: '#B23AFC', - PRIMARY: '#B23AFC', - INFO: '#1232FF', - ERROR: '#FE2472', + THEME: '#FE2472', + PRIMARY: '#FE2472', + DARK_PRIMARY: '#F4075C', + LIGHT_PRIMARY: '#FF8AB9', + BRIGHT_PRIMARY: '#FFD1E4', + INFO: '#0E2ADD', + DARK_INFO: '#0520D0', + LIGHT_INFO: '#8794FF', + BRIGHT_INFO: '#D1D6FF', + DANGER: '#FF3F31', + DARK_DANGER: '#F43324', + LIGHT_DANGER: '#FF7167', + BRIGHT_DANGER: '#FFCAC6', WARNING: '#FF9C09', - SUCCESS: '#45DF31', + DARK_WARNING: '#EE8E00', + LIGHT_WARNING: '#FFCC76', + BRIGHT_WARNING: '#FFEBCB', + SUCCESS: '#18CE0F', + DARK_SUCCESS: '#24AD12', + LIGHT_SUCCESS: '#88F38E', + BRIGHT_SUCCESS: '#D2FBD3', + WHITE: '#FFFFFF', + DARK_BLACK: '#000B19', + BLACK: '#161D28', + BRIGHT_BLACK: '#3D4144', + LIGHT_BLACK: '#2A2F36', + DARK_SECONDARY: '#62676B', + SECONDARY: '#9FA5AA', + BRIGHT_SECONDARY: '#EEF1F3', + LIGHT_SECONDARY: '#D6DADD', + DARK_GREY: '#E0E4EA', + GREY: '#E9EBEF', + BRIGHT_GREY: '#F7F8F9', + LIGHT_GREY: '#F0F1F4', + NEUTRAL: 'rgba(255,255,255, 0.65)', }; +// export const SHADOWS = { +// PRIMARY: 0 13px 11px -8 rgba(254, 36, 114, .30), +// INFO: 0 13px 11px -8 rgba(14, 42, 221, .30), +// SUCCESS: 0 13px 11px -8 rgba(24, 206, 15, .30), +// WARNING: 0 13px 11px -8 rgba(255, 156, 9, .30), +// DANGER: 0 13px 11px -8 rgba(255, 63, 49, .30), +// BLACK: 0 13px 11px -8 rgba(0, 0, 0, .30), +// WHITE: 0 10px 20px -8 rgba(210, 210, 210, .100), +// GREY: 0 13px 11px -8 rgba(152, 152, 152, .30), +// LIGHT_GREY: 0 13px 11px -8 rgba(149, 149, 149, .30), +// }; + export const COMPONENTS = { INPUT: '#808080', PLACEHOLDER: '#9FA5AA', diff --git a/src/theme/index.js b/src/theme/index.js index 4d5147c..84716f5 100644 --- a/src/theme/index.js +++ b/src/theme/index.js @@ -16,22 +16,40 @@ export default GalioTheme; // creating the GalioTheme context const GalioContext = React.createContext(); +/** + * useGalioTheme + * Galio custom hook which returns the theme object + */ + +export function useGalioTheme() { + const theme = React.useContext(GalioContext); + + if (theme === undefined) { + throw new Error( + 'useGalioTheme must be used within a component wrapped with GalioProvider' + ); + } + + return theme; +} + /* -* withGalio -* args: Component - React Component, styles to be added to Component -* theme: if no styles or theme add default theme={ SIZES, COLORS } -*/ + * withGalio + * args: Component - React Component, styles to be added to Component + * theme: if no styles or theme add default theme={ SIZES, COLORS } + */ export function withGalio(Component, styles) { // eslint-disable-next-line react/no-multi-comp - return class extends React.Component { + class EnhancedComponent extends React.Component { render() { - const { props } = this; + const { forwardedRef, ...rest } = this.props; return ( {theme => ( @@ -39,20 +57,24 @@ export function withGalio(Component, styles) { ); } - }; + } + + return React.forwardRef((props, ref) => { + return ; + }); } /* -* GalioProvider using React.Component -* GalioContext.Provider value has the default value from { COLORS, SIZES } -*/ + * GalioProvider using React.Component + * GalioContext.Provider value has the default value from { COLORS, SIZES } + */ // eslint-disable-next-line react/no-multi-comp export class GalioProvider extends React.Component { static defaultProps = { children: null, theme: {}, - } + }; render() { const { theme, children } = this.props; @@ -61,14 +83,10 @@ export class GalioProvider extends React.Component { const providerTheme = { COLORS: { ...GalioTheme.COLORS, ...CUSTOM_COLORS }, SIZES: { ...GalioTheme.SIZES, ...CUSTOM_SIZES }, - ...customTheme + ...customTheme, }; - return ( - - {children} - - ); + return {children}; } } diff --git a/src/theme/sizes.js b/src/theme/sizes.js index d55732f..5176eb1 100644 --- a/src/theme/sizes.js +++ b/src/theme/sizes.js @@ -2,18 +2,34 @@ import { Dimensions } from 'react-native'; const { height, width } = Dimensions.get('screen'); +export const BASE = 16; + const SIZES = { - BASE: 16, - FONT: 16, - ICON: 16, - OPACITY: 0.8, - BORDER_RADIUS: 6, + BASE: BASE, + FONT: BASE, + OPACITY: 0.6, + BORDER_RADIUS: 4, BORDER_WIDTH: 0.8, + // Typography + H1: BASE * 2.75, + H2: BASE * 2.375, + H3: BASE * 1.875, + H4: BASE * 1.5, + H5: BASE * 1.3125, + H6: BASE * 1.125, + BODY: BASE * 0.875, + SMALL: BASE * 0.75, + + // Icons + ICON: BASE, + ICON_MEDIUM: BASE * 1.5, + ICON_LARGE: BASE * 2, + // Button styles - BUTTON_WIDTH: 16 * 9, - BUTTON_HEIGHT: 16 * 2.75, - BUTTON_SHADOW_RADIUS: 10, + BUTTON_WIDTH: BASE * 9, + BUTTON_HEIGHT: BASE * 2.75, + BUTTON_SHADOW_RADIUS: 3, // Block styles BLOCK_SHADOW_OPACITY: 0.15, @@ -21,42 +37,41 @@ const SIZES = { ANDROID_ELEVATION: 1, // Card styles - CARD_BORDER_RADIUS: 16 * 0.4, - CARD_BORDER_WIDTH: 16 * 0.05, - CARD_WIDTH: width - (16 * 2), - CARD_MARGIN_VERTICAL: 16 * 0.875, - CARD_FOOTER_HORIZONTAL: 16 * 0.75, - CARD_FOOTER_VERTICAL: 16 * 0.75, - CARD_AVATAR_WIDTH: 16 * 2.5, - CARD_AVATAR_HEIGHT: 16 * 2.5, - CARD_AVATAR_RADIUS: 16 * 1.25, - CARD_IMAGE_HEIGHT: 16 * 12.5, - CARD_ROUND: 16 * 0.1875, - CARD_ROUNDED: 16 * 0.5, + CARD_BORDER_RADIUS: BASE * 0.4, + CARD_BORDER_WIDTH: BASE * 0.05, + CARD_WIDTH: width - (BASE * 2), + CARD_MARGIN_VERTICAL: BASE * 0.875, + CARD_FOOTER_HORIZONTAL: BASE * 0.75, + CARD_FOOTER_VERTICAL: BASE * 0.75, + CARD_AVATAR_WIDTH: BASE * 2.5, + CARD_AVATAR_HEIGHT: BASE * 2.5, + CARD_AVATAR_RADIUS: BASE * 1.25, + CARD_IMAGE_HEIGHT: BASE * 12.5, + CARD_ROUND: BASE * 0.1875, + CARD_ROUNDED: BASE * 0.5, // Input styles - INPUT_BORDER_RADIUS: 16 * 0.5, - INPUT_BORDER_WIDTH: 16 * 0.05, - INPUT_HEIGHT: 16 * 2.75, - INPUT_HORIZONTAL: 16, - INPUT_TEXT: 16 * 0.875, - INPUT_LABEL_TEXT: 16 * 0.9, - INPUT_LABEL_BOTTOM: 16 / 4, - INPUT_HELP_TEXT: 16 * 0.8, - INPUT_ROUNDED: 16 * 1.7, + INPUT_BORDER_RADIUS: BASE * 0.5, + INPUT_BORDER_WIDTH: BASE * 0.05, + INPUT_HEIGHT: BASE * 2.75, + INPUT_HORIZONTAL: BASE, + INPUT_VERTICAL_TEXT: 14, + INPUT_VERTICAL_LABEL: BASE / 2, + INPUT_TEXT: BASE * 0.875, + INPUT_ROUNDED: BASE * 1.5, // NavBar styles - NAVBAR_HEIGHT: 16 * 4.125, - NAVBAR_VERTICAL: 16, + NAVBAR_HEIGHT: BASE * 4.125, + NAVBAR_VERTICAL: BASE, NAVBAR_TITLE_FLEX: 2, NAVBAR_TITLE_HEIGHT: height * 0.07, - NAVBAR_TITLE_TEXT: 16 * 0.875, + NAVBAR_TITLE_TEXT: BASE * 0.875, NAVBAR_LEFT_FLEX: 0.5, NAVBAR_LEFT_HEIGHT: height * 0.07, - NAVBAR_LEFT_MARGIN: 16, + NAVBAR_LEFT_MARGIN: BASE, NAVBAR_RIGHT_FLEX: 0.5, NAVBAR_RIGHT_HEIGHT: height * 0.07, - NAVBAR_RIGHT_MARGIN: 16, + NAVBAR_RIGHT_MARGIN: BASE, // Checkbox CHECKBOX_WIDTH: 20,