diff --git a/docs/assets/avatar.png b/docs/assets/avatar.png new file mode 100644 index 00000000..7c1c2f02 Binary files /dev/null and b/docs/assets/avatar.png differ diff --git a/docs/avatar.md b/docs/avatar.md new file mode 100644 index 00000000..1396ffb0 --- /dev/null +++ b/docs/avatar.md @@ -0,0 +1,46 @@ +--- +id: avatar +title: Avatar +--- + +Avatar component. + +![Avatar component](assets/avatar.png) + +Example usage: +```javascript + +``` + +## Props + +### `initials` (optional) +**type:** `string` + +String to be displayed inside Avatar. +**default value:** '' + +### `onPress` (optional) +**type:** `void => void` + +onPress event handler. + +### `size` (optional) +**type:** `number` + +Size of an Avatar. + +### `style` (optional) +**type:** `Object` + +Custom styles to apply to Avatar. + +### `theme` (optional) +**type:** [`Theme`](theme.html) + +Custom theme for component. By default provided by the ThemeProvider. + +### `url` (optional) +**type:** `string` + +Url pointing to remote avatar image. diff --git a/example/rn-cli.config.js b/example/rn-cli.config.js index fe7a0936..273825a9 100644 --- a/example/rn-cli.config.js +++ b/example/rn-cli.config.js @@ -15,9 +15,6 @@ module.exports = { return ['react-native', 'react', ...dependencies]; }, getBlacklistRE() { - return blacklist([ - glob(`${path.resolve(__dirname, '..')}/node_modules/*`), - glob(`${path.resolve(__dirname, '..')}/docs/node_modules/*`), - ]); + return blacklist([glob(`${path.resolve(__dirname, '..')}/node_modules/*`)]); }, }; diff --git a/example/src/ExampleList.js b/example/src/ExampleList.js index bbe28bae..47db07f2 100644 --- a/example/src/ExampleList.js +++ b/example/src/ExampleList.js @@ -7,6 +7,7 @@ import type { Theme } from 'react-native-ios-kit/types'; import withSafeArea from './withSafeArea'; import Buttons from './scenes/Buttons'; +import Avatars from './scenes/Avatars'; import Typography from './scenes/Typography'; import TabBar from './scenes/TabBar'; import Stepper from './scenes/Stepper'; @@ -25,49 +26,53 @@ type Route = { const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 }); const dataSource = ds.cloneWithRows([ + { + component: Avatars, + title: 'Avatars', + }, { component: Buttons, title: 'Buttons', }, { - component: Typography, - title: 'Typography', + component: Icons, + title: 'Icons', }, { - component: TabBar, - title: 'TabBar', + component: SearchBar, + title: 'SearchBar', }, { - component: Stepper, - title: 'Stepper', + component: SegmentedControl, + title: 'SegmentedControl', }, { - component: SearchBar, - title: 'SearchBar', + component: Slider, + title: 'Slider', + }, + { + component: Stepper, + title: 'Stepper', }, { component: Switch, title: 'Switch', }, { - component: SegmentedControl, - title: 'SegmentedControl', + component: TabBar, + title: 'TabBar', }, { component: TableView, title: 'TableView', }, - { - component: Slider, - title: 'Slider', - }, { component: TextField, title: 'TextField', }, { - component: Icons, - title: 'Icons', + component: Typography, + title: 'Typography', }, ]); diff --git a/example/src/scenes/Avatars.js b/example/src/scenes/Avatars.js new file mode 100644 index 00000000..f729c315 --- /dev/null +++ b/example/src/scenes/Avatars.js @@ -0,0 +1,52 @@ +/* @flow */ +import * as React from 'react'; +import { View, StyleSheet } from 'react-native'; + +import { Avatar, withTheme, Body } from 'react-native-ios-kit'; + +import type { Theme } from 'react-native-ios-kit/types'; + +type Props = { + theme: Theme, +}; + +class AvatarExample extends React.Component { + render() { + return ( + + + Default + + + + Url prop + + + + Initials + + + + With onPress handler + alert('Hello')} + /> + + + ); + } +} + +export default withTheme(AvatarExample); + +const styles = StyleSheet.create({ + row: { + flexDirection: 'row', + padding: 10, + borderBottomColor: '#333', + borderBottomWidth: StyleSheet.hairlineWidth, + justifyContent: 'space-between', + alignItems: 'center', + }, +}); diff --git a/src/assets/avatartGradient.png b/src/assets/avatartGradient.png new file mode 100644 index 00000000..bfc87cfe Binary files /dev/null and b/src/assets/avatartGradient.png differ diff --git a/src/components/Avatar.js b/src/components/Avatar.js new file mode 100644 index 00000000..fa57193d --- /dev/null +++ b/src/components/Avatar.js @@ -0,0 +1,91 @@ +/* @flow */ +import * as React from 'react'; +import { + StyleSheet, + Image, + ImageBackground, + View, + Text, + TouchableOpacity, +} from 'react-native'; + +import type { Theme } from '../types/Theme'; +import { withTheme } from '../'; +import type { StyleObj } from 'react-native/Libraries/StyleSheet/StyleSheetTypes'; + +type Props = { + theme: Theme, + initials: string, + url?: string, + size: number, + style?: StyleObj, + onPress?: void => void, +}; + +class Avatar extends React.Component { + static defaultProps = { + initials: '', + size: 50, + }; + + renderTouchableAvatar = () => { + const styles = getStyles(this.props.size); + return ( + + {this.renderAvatar()} + + ); + }; + + renderAvatar = () => { + const { url, style, initials, size } = this.props; + const styles = getStyles(size); + + if (url) { + return ; + } + const overlay = require('../assets/avatartGradient.png'); + return ( + + + {initials.slice(0, 2)} + + + ); + }; + + render() { + const { onPress } = this.props; + if (onPress) return this.renderTouchableAvatar(); + return this.renderAvatar(); + } +} + +export default withTheme(Avatar); + +const getStyles = (avatarSize: number) => + StyleSheet.create({ + letterWrapper: { + height: avatarSize, + width: avatarSize, + borderRadius: avatarSize / 2, + justifyContent: 'center', + backgroundColor: 'transparent', + }, + letters: { + fontSize: avatarSize / 2.4, + fontFamily: 'ArialRoundedMTBold', + textAlign: 'center', + backgroundColor: 'transparent', + color: 'white', + }, + avatar: { + width: avatarSize, + height: avatarSize, + borderRadius: avatarSize / 2, + }, + }); diff --git a/src/index.js b/src/index.js index d860c63b..ecef7a36 100644 --- a/src/index.js +++ b/src/index.js @@ -5,6 +5,7 @@ export { default as ThemeProvider } from './core/ThemeProvider'; export { default as DefaultTheme } from './styles/DefaultTheme'; export { default as DarkTheme } from './styles/DarkTheme'; +export { default as Avatar } from './components/Avatar'; export { default as Button } from './components/Button'; export { default as CheckboxRow } from './components/CheckboxRow'; export { default as Icon } from './components/Icon'; diff --git a/website/core/Footer.js b/website/core/Footer.js index d33ba659..e030f194 100644 --- a/website/core/Footer.js +++ b/website/core/Footer.js @@ -49,7 +49,7 @@ class Footer extends React.Component {
Docs
Getting Started - API Reference + API Reference
Community
diff --git a/website/i18n/en.json b/website/i18n/en.json index 75e3ddb0..9f874c59 100644 --- a/website/i18n/en.json +++ b/website/i18n/en.json @@ -4,6 +4,7 @@ "next": "Next", "previous": "Previous", "tagline": "The missing React Native UI Kit for iOS.", + "avatar": "Avatar", "button": "Button", "checkbox-row": "CheckboxRow", "customization": "Customization", diff --git a/website/sidebars.json b/website/sidebars.json index 53129d21..16b56c80 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -2,6 +2,7 @@ "docs": { "Getting Started": ["installation", "usage", "customization", "theme"], "API": [ + "avatar", "button", "checkbox-row", "icon", diff --git a/website/siteConfig.js b/website/siteConfig.js index 52cf4e9e..db0a3be9 100644 --- a/website/siteConfig.js +++ b/website/siteConfig.js @@ -8,7 +8,7 @@ const siteConfig = { baseUrl: '/react-native-ios-kit/', headerLinks: [ { doc: 'installation', label: 'Docs' }, - { doc: 'button', label: 'API' }, + { doc: 'avatar', label: 'API' }, { page: 'help', label: 'Help' }, ], users,