Skip to content

Commit

Permalink
feat(ui): button-group component. Closes #290
Browse files Browse the repository at this point in the history
  • Loading branch information
artyorsh authored Mar 5, 2019
1 parent 9028953 commit 6a6a0ad
Show file tree
Hide file tree
Showing 9 changed files with 972 additions and 6 deletions.
3 changes: 2 additions & 1 deletion src/framework/ui/button/button.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export class Button extends React.Component<Props> {
static defaultProps: Partial<Props> = {
status: 'primary',
size: 'medium',
alignment: 'left',
};

private onPress = (event: GestureResponderEvent) => {
Expand Down Expand Up @@ -124,7 +125,7 @@ export class Button extends React.Component<Props> {
return (
<TouchableOpacity
{...derivedProps}
style={[style, container, strictStyles.container]}
style={[container, style, strictStyles.container]}
activeOpacity={1.0}
onPress={this.onPress}
onPressIn={this.onPressIn}
Expand Down
15 changes: 10 additions & 5 deletions src/framework/ui/button/button.spec.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
exports[`@button: matches snapshot * appearance * empty 1`] = `
<TouchableOpacity
activeOpacity={1}
alignment="left"
appearance="default"
dispatch={[Function]}
onPress={[Function]}
Expand All @@ -12,14 +13,14 @@ exports[`@button: matches snapshot * appearance * empty 1`] = `
status="primary"
style={
Array [
undefined,
Object {
"borderRadius": 6,
"flexDirection": "row",
"minHeight": 24,
"minWidth": 24,
"padding": 4,
},
undefined,
Object {
"alignItems": "center",
"justifyContent": "space-evenly",
Expand All @@ -45,6 +46,7 @@ exports[`@button: matches snapshot * appearance * empty 1`] = `
exports[`@button: matches snapshot * appearance * icon 1`] = `
<TouchableOpacity
activeOpacity={1}
alignment="left"
appearance="default"
dispatch={[Function]}
icon={
Expand All @@ -59,14 +61,14 @@ exports[`@button: matches snapshot * appearance * icon 1`] = `
status="primary"
style={
Array [
undefined,
Object {
"borderRadius": 6,
"flexDirection": "row",
"minHeight": 24,
"minWidth": 24,
"padding": 4,
},
undefined,
Object {
"alignItems": "center",
"justifyContent": "space-evenly",
Expand Down Expand Up @@ -111,6 +113,7 @@ exports[`@button: matches snapshot * appearance * icon 1`] = `
exports[`@button: matches snapshot * appearance * icon and text 1`] = `
<TouchableOpacity
activeOpacity={1}
alignment="left"
appearance="default"
dispatch={[Function]}
icon={
Expand All @@ -125,14 +128,14 @@ exports[`@button: matches snapshot * appearance * icon and text 1`] = `
status="primary"
style={
Array [
undefined,
Object {
"borderRadius": 6,
"flexDirection": "row",
"minHeight": 24,
"minWidth": 24,
"padding": 4,
},
undefined,
Object {
"alignItems": "center",
"justifyContent": "space-evenly",
Expand Down Expand Up @@ -192,6 +195,7 @@ exports[`@button: matches snapshot * appearance * icon and text 1`] = `
exports[`@button: matches snapshot * appearance * text 1`] = `
<TouchableOpacity
activeOpacity={1}
alignment="left"
appearance="default"
dispatch={[Function]}
onPress={[Function]}
Expand All @@ -201,14 +205,14 @@ exports[`@button: matches snapshot * appearance * text 1`] = `
status="primary"
style={
Array [
undefined,
Object {
"borderRadius": 6,
"flexDirection": "row",
"minHeight": 24,
"minWidth": 24,
"padding": 4,
},
undefined,
Object {
"alignItems": "center",
"justifyContent": "space-evenly",
Expand Down Expand Up @@ -250,6 +254,7 @@ exports[`@button: matches snapshot * appearance * text 1`] = `
exports[`@button: matches snapshot * interaction * stateless 1`] = `
<TouchableOpacity
activeOpacity={1}
alignment="left"
appearance="default"
dispatch={[Function]}
onPress={[Function]}
Expand All @@ -259,14 +264,14 @@ exports[`@button: matches snapshot * interaction * stateless 1`] = `
status="primary"
style={
Array [
undefined,
Object {
"borderRadius": 6,
"flexDirection": "row",
"minHeight": 24,
"minWidth": 24,
"padding": 4,
},
undefined,
Object {
"alignItems": "center",
"justifyContent": "space-evenly",
Expand Down
99 changes: 99 additions & 0 deletions src/framework/ui/buttonGroup/buttonGroup.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import React from 'react';
import {
Group,
StyleSheet,
View,
ViewProps,
} from 'react-native';
import {
StyledComponentProps,
StyleType,
} from '@kitten/theme';
import { Props as ButtonProps } from '../button/button.component';
import {
ButtonStyleProvider,
ButtonStyleProviders,
} from './type';

type ButtonElement = React.ReactElement<ButtonProps>;

interface ButtonGroupProps {
children: ButtonElement | ButtonElement[];
size?: string;
}

export type Props = ButtonGroupProps & StyledComponentProps & ViewProps;

export class ButtonGroup extends React.Component<Props> {

static defaultProps: Partial<Props> = {
size: 'medium',
};

private styleProvider: ButtonStyleProvider = ButtonStyleProviders.DEFAULT;

private getComponentStyle = (style: StyleType): StyleType => {
const { button, ...container } = style;

return {
container: container,
button: button,
};
};

private getChildComponentStyle = (index: number, source: StyleType): StyleType => {
const { children } = this.props;

switch (index) {
case 0:
return this.styleProvider.start(source);
case React.Children.count(children) - 1:
return this.styleProvider.end(source);
default:
return this.styleProvider.center(source);
}
};

private createComponentChild = (element: ButtonElement, index: number, style: StyleType): ButtonElement => {
const { appearance, size, children } = this.props;
const { style: elementStyle, ...derivedProps } = element.props;

const isSingle: boolean = React.Children.count(children) === 1;
const positionedStyle: StyleType = isSingle ? style : this.getChildComponentStyle(index, style);

return React.cloneElement(element, {
...derivedProps,
style: [elementStyle, positionedStyle],
key: index,
appearance: appearance,
size: size,
});
};

private createComponentChildren = (source: ButtonElement | ButtonElement[], style: StyleType): ButtonElement[] => {
return React.Children.map(source, (element: ButtonElement, index: number): ButtonElement => {
return this.createComponentChild(element, index, style);
});
};

public render(): React.ReactElement<ViewProps> {
const { style, themedStyle, children, ...derivedProps } = this.props;
const { container, button } = this.getComponentStyle(themedStyle);

const componentChildren: ButtonElement[] = this.createComponentChildren(children, button);

return (
<View
{...derivedProps}
style={[container, style, strictStyles.container]}>
{componentChildren}
</View>
);
}
}

const strictStyles = StyleSheet.create({
container: {
flexDirection: 'row',
},
});
Loading

0 comments on commit 6a6a0ad

Please sign in to comment.