Skip to content

Commit

Permalink
feat(ui): toggle - add text property
Browse files Browse the repository at this point in the history
  • Loading branch information
artyorsh committed Sep 25, 2019
1 parent 060fe5d commit 327ce36
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 157 deletions.
81 changes: 60 additions & 21 deletions src/framework/ui/toggle/toggle.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,27 @@ import React from 'react';
import {
Animated,
Easing,
GestureResponderEvent,
PanResponder,
PanResponderCallbacks,
PanResponderGestureState,
PanResponderInstance,
StyleProp,
StyleSheet,
TextStyle,
View,
ViewProps,
PanResponderInstance,
GestureResponderEvent,
PanResponderGestureState,
TouchableOpacity,
PanResponderCallbacks,
} from 'react-native';
import {
StyledComponentProps,
StyleType,
Interaction,
styled,
StyledComponentProps,
StyleType,
} from '@kitten/theme';
import {
Text,
TextElement,
} from '../text/text.component';
import { CheckMark } from '../support/components';
import { I18nLayoutService } from '../support/services';

Expand All @@ -32,6 +37,8 @@ interface ComponentProps {
disabled?: boolean;
status?: string;
size?: string;
text?: string;
textStyle?: StyleProp<TextStyle>;
onChange?: (checked: boolean) => void;
}

Expand Down Expand Up @@ -225,6 +232,12 @@ export class ToggleComponent extends React.Component<ToggleProps> implements Pan
thumbHeight,
thumbBorderRadius,
thumbBackgroundColor,
textMarginHorizontal,
textFontSize,
textFontWeight,
textLineHeight,
textFontFamily,
textColor,
iconWidth,
iconHeight,
iconTintColor,
Expand All @@ -247,8 +260,8 @@ export class ToggleComponent extends React.Component<ToggleProps> implements Pan
const thumbScale: Animated.AnimatedDiffClamp = this.animateThumbScale(offsetValue);

return {
container: {},
componentContainer: {
toggleContainer: {},
ellipseContainer: {
borderColor: borderColor,
backgroundColor: interpolatedBackgroundColor,
...containerParameters,
Expand All @@ -275,6 +288,14 @@ export class ToggleComponent extends React.Component<ToggleProps> implements Pan
elevation: disabled ? 0 : 5,
transform: [{ translateX: this.thumbTranslateAnimation }],
},
text: {
marginHorizontal: textMarginHorizontal,
fontSize: textFontSize,
fontWeight: textFontWeight,
lineHeight: textLineHeight,
fontFamily: textFontFamily,
color: textColor,
},
icon: {
width: source.iconWidth,
height: source.iconHeight,
Expand Down Expand Up @@ -351,42 +372,60 @@ export class ToggleComponent extends React.Component<ToggleProps> implements Pan
});
};

private renderTextElement = (style: StyleType): TextElement => {
return (
<Text style={[style, this.props.textStyle]}>
{this.props.text}
</Text>
);
};

private renderComponentChildren = (style: StyleType): React.ReactNodeArray => {
return [
this.props.text && this.renderTextElement(style.text),
];
};

public render(): React.ReactElement<ViewProps> {
const { themedStyle, style, disabled, checked, ...restProps } = this.props;

const componentStyle: StyleType = this.getComponentStyle(themedStyle);
const [textElement] = this.renderComponentChildren(componentStyle);

return (
<View
{...restProps}
style={[componentStyle.container, styles.container, style]}>
<View style={[componentStyle.highlight, styles.highlight]} />
<TouchableOpacity
onPressIn={this.onPressIn}
onPressOut={this.onPressOut}
onPress={this.onPress}>
<Animated.View
style={[componentStyle.componentContainer, styles.componentContainer]}
{...this.panResponder.panHandlers}>
<Animated.View style={[componentStyle.ellipse, styles.ellipse]} />
{...this.panResponder.panHandlers}
style={[styles.container, style]}>
<View style={[componentStyle.toggleContainer, styles.toggleContainer]}>
<View style={[componentStyle.highlight, styles.highlight]}/>
<Animated.View style={[componentStyle.ellipseContainer, styles.ellipseContainer]}>
<Animated.View style={[componentStyle.ellipse, styles.ellipse]}/>
<Animated.View style={[componentStyle.thumb, styles.thumb]}>
<CheckMark
style={componentStyle.icon}
isAnimated={true}
/>
</Animated.View>
</Animated.View>
</TouchableOpacity>
</View>
{textElement}
</View>
);
}
}

const styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
toggleContainer: {
alignItems: 'center',
justifyContent: 'center',
},
componentContainer: {
ellipseContainer: {
justifyContent: 'center',
alignSelf: 'center',
overflow: 'hidden',
Expand Down
112 changes: 31 additions & 81 deletions src/framework/ui/toggle/toggle.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import React from 'react';
import { TouchableOpacity } from 'react-native';
import {
fireEvent,
render,
shallow,
RenderAPI,
fireEvent,
waitForElement,
} from 'react-native-testing-library';
import { ReactTestInstance } from 'react-test-renderer';
import {
Expand All @@ -14,13 +11,29 @@ import {
} from '@kitten/theme';
import {
Toggle,
ToggleComponent,
ToggleProps,
} from './toggle.component';
import {
mapping,
theme,
} from '../support/tests';

jest.mock('Animated', (): unknown => {
const AnimatedModule = jest.requireActual('Animated');
return {
...AnimatedModule,
timing: (value, config) => {
return {
start: (callback) => {
value.setValue(config.toValue);
callback && callback();
},
};
},
};
});

const Mock = (props?: ToggleProps): React.ReactElement<ApplicationProviderProps> => {
return (
<ApplicationProvider
Expand All @@ -37,92 +50,25 @@ const renderComponent = (props?: ToggleProps): RenderAPI => {
);
};

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

it('default', () => {
const component: RenderAPI = renderComponent();
const { output } = shallow(component.getByType(Toggle));

expect(output).toMatchSnapshot();
});

it('checked', () => {
const component: RenderAPI = renderComponent({ checked: true });
const { output } = shallow(component.getByType(Toggle));

expect(output).toMatchSnapshot();
});

it('disabled', () => {
const component: RenderAPI = renderComponent({ disabled: true });
const { output } = shallow(component.getByType(Toggle));

expect(output).toMatchSnapshot();
});
describe('@toggle: component checks', () => {

it('checked disabled', () => {
it('contains text', () => {
const component: RenderAPI = renderComponent({
checked: true,
disabled: true,
text: 'Sample Text',
});
const { output } = shallow(component.getByType(Toggle));

expect(output).toMatchSnapshot();
expect(component.getByText('Sample Text')).toBeTruthy();
});

it('active', async () => {
const component: RenderAPI = renderComponent();

fireEvent(component.getByType(TouchableOpacity), 'pressIn');

const active: ReactTestInstance = await waitForElement(() => {
return component.getByType(Toggle);
});
const { output: activeOutput } = shallow(active);

fireEvent(component.getByType(TouchableOpacity), 'pressOut');

const inactive: ReactTestInstance = await waitForElement(() => {
return component.getByType(Toggle);
});
const { output: inactiveOutput } = shallow(inactive);

expect(activeOutput).toMatchSnapshot();
expect(inactiveOutput).toMatchSnapshot('default');
});

it('active checked', async () => {
const component: RenderAPI = renderComponent({ checked: true });

fireEvent(component.getByType(TouchableOpacity), 'pressIn');
const active: ReactTestInstance = await waitForElement(() => {
return component.getByType(Toggle);
});
const { output: activeOutput } = shallow(active);

fireEvent(component.getByType(TouchableOpacity), 'pressOut');

const inactive: ReactTestInstance = await waitForElement(() => {
return component.getByType(Toggle);
});
const { output: inactiveOutput } = shallow(inactive);

expect(activeOutput).toMatchSnapshot();
expect(inactiveOutput).toMatchSnapshot('checked');
});

});

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

it('emits onChange', () => {
const onChange = jest.fn();

const component: RenderAPI = renderComponent({ onChange: onChange });
const component: RenderAPI = renderComponent({ onChange });
const { [0]: containerView } = component.getByType(ToggleComponent).children;

fireEvent.press(component.getByType(TouchableOpacity));
fireEvent(containerView as ReactTestInstance, 'responderRelease');

expect(onChange).toBeCalled();
expect(onChange).toHaveBeenCalled();
});

it('checking of value direct', () => {
Expand All @@ -136,7 +82,9 @@ describe('@toggle: component checks', () => {
onChange: onChangeValue,
});

fireEvent.press(component.getByType(TouchableOpacity));
const { [0]: containerView } = component.getByType(ToggleComponent).children;

fireEvent(containerView as ReactTestInstance, 'responderRelease');

expect(checked).toBe(true);
});
Expand All @@ -152,7 +100,9 @@ describe('@toggle: component checks', () => {
onChange: onChangeValue,
});

fireEvent.press(component.getByType(TouchableOpacity));
const { [0]: containerView } = component.getByType(ToggleComponent).children;

fireEvent(containerView as ReactTestInstance, 'responderRelease');

expect(checked).toBe(false);
});
Expand Down
55 changes: 0 additions & 55 deletions src/framework/ui/toggle/toggle.spec.tsx.snap

This file was deleted.

0 comments on commit 327ce36

Please sign in to comment.