Skip to content

Commit

Permalink
feat(ui): avatar component
Browse files Browse the repository at this point in the history
  • Loading branch information
artyorsh authored Mar 13, 2019
1 parent 1afbcfe commit d63df29
Show file tree
Hide file tree
Showing 7 changed files with 404 additions and 0 deletions.
52 changes: 52 additions & 0 deletions src/framework/ui/avatar/avatar.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React from 'react';
import {
Image,
TouchableOpacityProps,
ImageProps,
ImageStyle,
StyleSheet,
} from 'react-native';
import {
StyledComponentProps,
StyleType,
} from '@kitten/theme';

interface AvatarProps {
shape?: string;
size?: string;
}

export type Props = AvatarProps & StyledComponentProps & ImageProps;

export class Avatar extends React.Component<Props> {

private getComponentStyle = (source: StyleType): StyleType => {
const { roundCoefficient, ...componentStyle } = source;

const baseStyle: ImageStyle = {
...componentStyle,
...StyleSheet.flatten(this.props.style),
};

// @ts-ignore: rhs operator is restricted to be number
const borderRadius: number = roundCoefficient * baseStyle.height;

return { ...baseStyle, borderRadius };
};

public render(): React.ReactElement<TouchableOpacityProps> {
const { themedStyle, ...derivedProps } = this.props;
const componentStyle: StyleType = this.getComponentStyle(themedStyle);

return (
<Image
{...derivedProps}
style={[componentStyle, styles.container]}
/>
);
}
}

const styles = StyleSheet.create({
container: {},
});
105 changes: 105 additions & 0 deletions src/framework/ui/avatar/avatar.spec.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { ThemeMappingType } from 'eva/packages/types';
import { ThemeType } from '@kitten/theme';

export const mapping: ThemeMappingType = {
'Avatar': {
'meta': {
'scope': 'all',
'mapping': {
'roundCoefficient': {
'type': 'number',
},
'margin': {
'type': 'number',
},
'width': {
'type': 'number',
},
'height': {
'type': 'number',
},
},
'appearances': {
'default': {
'default': true,
},
},
'variants': {
'shape': {
'round': {
'default': true,
},
'rounded': {
'default': false,
},
'square': {
'default': false,
},
},
'size': {
'small': {
'default': false,
},
'medium': {
'default': true,
},
'large': {
'default': false,
},
},
},
'states': {},
},
'appearance': {
'default': {
'mapping': {
'margin': 16,
},
'variant': {
'shape': {
'round': {
'roundCoefficient': 0.5,
},
'rounded': {
'roundCoefficient': 0.3,
},
'square': {
'roundCoefficient': 0,
},
},
'size': {
'small': {
'width': 40,
'height': 40,
},
'medium': {
'width': 48,
'height': 48,
},
'large': {
'width': 64,
'height': 64,
},
},
},
},
},
},
};

export const theme: ThemeType = {
'blue-primary': '#3366FF',
'blue-dark': '#2541CC',
'gray-light': '#DDE1EB',
'gray-primary': '#A6AEBD',
'gray-dark': '#8992A3',
'gray-highlight': '#EDF0F5',
'pink-primary': '#FF3D71',
'text-primary': '#000000',
'text-primary-inverse': '#ffffff',

'gray-100': '#f7f8fa',
'gray-200': '#edf0f5',
'gray-300': '#c8cedb',
'gray-400': '#a6aebd',
};
94 changes: 94 additions & 0 deletions src/framework/ui/avatar/avatar.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import React from 'react';
import {
Image,
StyleSheet,
} from 'react-native';
import {
render,
RenderAPI,
shallow,
} from 'react-native-testing-library';
import { ReactTestInstance } from 'react-test-renderer';
import {
styled,
StyleProvider,
StyleProviderProps,
} from '@kitten/theme';
import {
Avatar as AvatarComponent,
Props as AvatarProps,
} from './avatar.component';
import * as config from './avatar.spec.config';

const Avatar = styled<AvatarComponent, AvatarProps>(AvatarComponent);

const Mock = (props?: AvatarProps): React.ReactElement<StyleProviderProps> => (
<StyleProvider mapping={config.mapping} theme={config.theme} styles={{}}>
<Avatar {...props} />
</StyleProvider>
);

const renderComponent = (props?: AvatarProps): RenderAPI => {
return render(
<Mock {...props} />,
);
};

describe('@avatar: matches snapshot', () => {

describe('* appearance', () => {

it('* default', () => {
const component: RenderAPI = renderComponent({
source: { uri: 'https://akveo.github.io/eva-icons/fill/png/128/star.png' },
});

expect(component).toMatchSnapshot();
});

});

});

describe('@avatar: component checks', () => {

it('* round shape styled properly', () => {
const component: RenderAPI = renderComponent({
source: { uri: 'https://akveo.github.io/eva-icons/fill/png/128/star.png' },
shape: 'round',
});

const avatar: ReactTestInstance = component.getByType(Image);

const { borderRadius, height } = StyleSheet.flatten(avatar.props.style);

expect(borderRadius).toEqual(height / 2);
});

it('* rounded shape styled properly', () => {
const component: RenderAPI = renderComponent({
source: { uri: 'https://akveo.github.io/eva-icons/fill/png/128/star.png' },
shape: 'rounded',
});

const avatar: ReactTestInstance = component.getByType(Image);

const { borderRadius, height } = StyleSheet.flatten(avatar.props.style);

expect(borderRadius).toBeLessThan(height);
});

it('* square shape', () => {
const component: RenderAPI = renderComponent({
source: { uri: 'https://akveo.github.io/eva-icons/fill/png/128/star.png' },
shape: 'square',
});

const avatar: ReactTestInstance = component.getByType(Image);

const { borderRadius } = StyleSheet.flatten(avatar.props.style);

expect(borderRadius).toEqual(0);
});

});
41 changes: 41 additions & 0 deletions src/framework/ui/avatar/avatar.spec.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`@avatar: matches snapshot * appearance * default 1`] = `
<Image
appearance="default"
dispatch={[Function]}
source={
Object {
"uri": "https://akveo.github.io/eva-icons/fill/png/128/star.png",
}
}
style={
Array [
Object {
"borderRadius": 24,
"height": 48,
"margin": 16,
"width": 48,
},
Object {},
]
}
theme={
Object {
"blue-dark": "#2541CC",
"blue-primary": "#3366FF",
"gray-100": "#f7f8fa",
"gray-200": "#edf0f5",
"gray-300": "#c8cedb",
"gray-400": "#a6aebd",
"gray-dark": "#8992A3",
"gray-highlight": "#EDF0F5",
"gray-light": "#DDE1EB",
"gray-primary": "#A6AEBD",
"pink-primary": "#FF3D71",
"text-primary": "#000000",
"text-primary-inverse": "#ffffff",
}
}
/>
`;
7 changes: 7 additions & 0 deletions src/framework/ui/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { styled } from '@kitten/theme';
import {
Avatar as AvatarComponent,
Props as AvatarProps,
} from './avatar/avatar.component';
import {
Button as ButtonComponent,
Props as ButtonProps,
Expand Down Expand Up @@ -88,6 +92,7 @@ import {
Placements as PopoverPlacements,
} from './popover/type';

const Avatar = styled<AvatarComponent, AvatarProps>(AvatarComponent);
const Button = styled<ButtonComponent, ButtonProps>(ButtonComponent);
const ButtonGroup = styled<ButtonGroupComponent, ButtonGroupProps>(ButtonGroupComponent);
const Input = styled<InputComponent, InputProps>(InputComponent);
Expand All @@ -109,6 +114,7 @@ const TopNavigationBarAction =
const Modal = styled<ModalComponent, ModalProps>(ModalComponent);

export {
Avatar,
Button,
ButtonGroup,
Input,
Expand All @@ -128,6 +134,7 @@ export {
Tooltip,
ViewPager,
TabView,
AvatarProps,
ButtonProps,
InputProps,
ButtonGroupProps,
Expand Down
Loading

0 comments on commit d63df29

Please sign in to comment.