Skip to content

Commit

Permalink
- Refactor, version bump
Browse files Browse the repository at this point in the history
  • Loading branch information
avishayil committed Apr 23, 2020
1 parent 6260a3c commit 1252282
Show file tree
Hide file tree
Showing 12 changed files with 265 additions and 158 deletions.
8 changes: 8 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@
"react"
],
"rules": {
"require-jsdoc": [
"error",
{
"require": {
"FunctionDeclaration": false
}
}
]
},
"settings": {
"react": {
Expand Down
5 changes: 4 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
Examples
Examples
screenshots
.travis.yml
.gitignore
53 changes: 35 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,53 @@
A bare-bones user avatar display with support for falling back to using the user's initials on a colored background as the avatar.
Based on the great library for React: https://github.com/wbinnssmith/react-user-avatar, and ported to React Native.

![](http://i.imgur.com/LJjK9cl.png)
iOS Screenshot | Android Screenshot
:-------------------------:|:-------------------------:
<img src="./screenshots/ios.png" title="iOS Screenshot" width="250"> | <img src="./screenshots/android.png" title="Android Screenshot" width="250">

## Installation

`npm install --save react-native-user-avatar` or `yarn add react-native-user-avatar`

## Usage

```jsx
import UserAvatar from 'react-native-user-avatar';


<UserAvatar size="100" name="Avishay Bar" />
<UserAvatar size="100" name="Avishay Bar" src="https://dummyimage.com/100x100/000/fff" />
<UserAvatar size="50" name="John Doe" colors={['#ccc', '#fafafa', '#ccaabb']}/>
<UserAvatar size="50" name="John Doe" />
<UserAvatar size="50" name="Jane Doe" color="#000" />
```

## User-defined Image-Component
The fallback avatar's color may be set by passing in the `bgColor` prop, or you can customize the range of colors
used by passing in an array of `bgColors`. The component uses a simple calculation to consistently use the same
color for the same user's name every time.

It is also possible to use another Image-Component than the built-in `<Image>`.
### UserAvatar Component

```jsx
<UserAvatar size="50" name="John Doe" component={CachedImage} />
import UserAvatar from 'react-native-user-avatar';

const App: () => React$Node = () => {
return (
<>
...
<View>
<UserAvatar size="100" name="Avishay Bar" />
<UserAvatar size="100" name="Avishay Bar" src="https://dummyimage.com/100x100/000/fff" />
<UserAvatar size="50" name="John Doe" colors={['#ccc', '#fafafa', '#ccaabb']}/>
<UserAvatar size="50" name="John Doe" />
<UserAvatar size="50" name="Jane Doe" color="#000" />
</View>
...
```
The fallback avatar's color may be set by passing in the `color` prop, or you can customize the range of colors
used by passing in an array of `colors`. The component uses a simple calculation to consistently use the same
color for the same user's name every time.
### UserAvatar Props
Attribute | Type | Default Value | Description
---------------- | --------------- | ------------- | -----------
`name` | string | `'John Doe'` | name used for generating initials
`src` | string | `undefined` | source image on the internet to display
`bgColor` | string | `undefined` | custom background color for the initials
`bgColors` | array | see index.js | custom array of background colors to choose from
`textColor` | string | `'#fff'` | custom text color for the initials font
`size` | number | `32` | custom size that defines both the avatar and the initials font size
`imageStyle` | object | `undefined` | custom image styling to append to the `Image` component displays the source image
`style` | object | `undefined` | custom style to append to the `UserAvatar` component container
`borderRadius` | number | `size * 0.5` | custom border radius for the component
`component` | React.Component | `undefined` | custom component to display instead of initials or source image
## Credits
Expand Down
34 changes: 34 additions & 0 deletions components/ImageAvatar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import PropTypes from 'prop-types';
import {Image} from 'react-native';

const ImageAvatar = (props) => {
const {
src,
size,
imageStyle,
borderRadius,
} = props;

const imageDefaultStyle = {
borderRadius: borderRadius ? borderRadius : (size * 0.5),
width: size,
height: size,
};

const newProps = {
style: [imageDefaultStyle, imageStyle],
source: {uri: src},
};

return React.createElement(Image, newProps);
};

ImageAvatar.propTypes = {
src: PropTypes.string,
size: PropTypes.number,
imageStyle: PropTypes.object,
borderRadius: PropTypes.number,
};

export default ImageAvatar;
43 changes: 43 additions & 0 deletions components/TextAvatar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react';
import {View, Text} from 'react-native';
import PropTypes from 'prop-types';
import {abbr} from '../helpers';

const TextAvatar = (props) => {
const {
name,
size,
textColor,
} = props;

const textContainerStyle = {
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
marginTop: -(size / 20),
height: size,
width: size,
};

return (
<View style={textContainerStyle}>
<Text
style={{
color: textColor,
fontSize: size / 2.5,
}}
adjustsFontSizeToFit={true}
>
{abbr(name)}
</Text>
</View>
);
};

TextAvatar.propTypes = {
name: PropTypes.string,
size: PropTypes.number,
textColor: PropTypes.string,
};

export default TextAvatar;
4 changes: 4 additions & 0 deletions components/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import ImageAvatar from './ImageAvatar';
import TextAvatar from './TextAvatar';

export {ImageAvatar, TextAvatar};
56 changes: 56 additions & 0 deletions helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import initials from 'initials';

export function abbr(name) {
let abbr = initials(name);
if (name.startsWith('+')) {
abbr = `+${ abbr }`;
}
if (!abbr) abbr = name;
return abbr;
}

export function sumChars(str) {
let sum = 0;
for (let i = 0; i < str.length; i++) {
sum += str.charCodeAt(i);
}

return sum;
}

export async function fetchImage(src) {
try {
const fetchCall = await fetch(src);
if (fetchCall.headers.map['content-type'].startsWith('image/')) {
return true;
} else {
console.warn('Online fetched source is not a supported image');
return false;
}
} catch (err) {
console.warn('Error fetching source, falling back to initials', err);
return false;
}
}

export function generateBackgroundStyle(name, bgColor, bgColors) {
let background;
if (bgColor) {
background = bgColor;
} else {
// Pick a deterministic color from the list
const i = sumChars(name) % bgColors.length;
background = bgColors[i];
}
return {backgroundColor: background};
}

export function getContainerStyle(size, src, borderRadius) {
return {
borderRadius: borderRadius ? borderRadius : (size * 0.5),
borderWidth: src ? 0 : 1,
borderColor: 'transparent',
justifyContent: 'center',
alignItems: 'center',
};
};
21 changes: 10 additions & 11 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import React from 'react'
import { ViewStyle, ImageStyle, StyleProp } from 'react-native'
import { ImageStyle, StyleProp } from 'react-native'
type UserAvatarPropsType = {
src?: string
name: string
color?: string
textColor?: string
colors?: string[]
size?: number
containerStyle?: ViewStyle
imageStyle?: ImageStyle
defaultName?: string
borderRadius?: number
style?: StyleProp
src: string
bgColor: string
bgColors: string[]
textColor: string
size: number
imageStyle: ImageStyle
style: StyleProp
borderRadius: number
component: Object
}

export default class UserAvatar extends React.PureComponent<UserAvatarPropsType, any> {
Expand Down
Loading

0 comments on commit 1252282

Please sign in to comment.