Skip to content

Commit

Permalink
button idea
Browse files Browse the repository at this point in the history
  • Loading branch information
kimjoar authored and cjcenizal committed Mar 28, 2017
1 parent a9a4652 commit d1eed94
Showing 1 changed file with 89 additions and 99 deletions.
188 changes: 89 additions & 99 deletions ui_framework/components/button/button.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import React, {
PropTypes,
} from 'react';

import classNames from 'classnames';
import keyMirror from 'keymirror';

import { KuiButtonIcon } from './button_icon/button_icon';

Expand All @@ -13,63 +11,38 @@ const BUTTON_TYPES = [
'danger',
'primary',
];
const ICON_POSITIONS = [
'left',
'right',
];
const defaultIconPosition = ICON_POSITIONS[0];

const commonPropTypes = {
type: PropTypes.oneOf(BUTTON_TYPES),
'data-test-subj': PropTypes.string,
isDisabled: PropTypes.bool,
onClick: PropTypes.func,
data: PropTypes.any,
className: PropTypes.string,
};

// KuiSubmitButton is an `input` element, which is a void element and can't contain children. But
// the regular KuiButton and KuiLink button are non-void elements, so they can contain children.
// These propTypes will only apply to these components.
const nonVoidPropTypes = {
icon: PropTypes.node,
iconPosition: PropTypes.oneOf([
'left',
'right',
]),
children: PropTypes.node,
isLoading: PropTypes.bool,
const buttonTypeToClassNameMap = {
basic: 'kuiButton--basic',
hollow: 'kuiButton--hollow',
danger: 'kuiButton--danger',
primary: 'kuiButton--primary',
};

const nonVoidDefaultProps = {
iconPosition: 'left',
};
const getClassName = ({ className, type, icon }) =>
classNames('kuiButton', className, buttonTypeToClassNameMap[type], {
'kuiButton--iconText': icon != null,
});

const getIcon = props => (
props.isLoading
const ContentWithIcon = ({ children, icon, iconPosition, isLoading }) => {
const iconOrLoading = isLoading
? <KuiButtonIcon type="loading" />
: props.icon
);

const getClassName = (props, icon) => {
const typeToClassNameMap = {
basic: 'kuiButton--basic',
hollow: 'kuiButton--hollow',
danger: 'kuiButton--danger',
primary: 'kuiButton--primary',
};

return classNames('kuiButton', props.className, {
[typeToClassNameMap[props.type]]: props.type,
'kuiButton--iconText': icon,
});
};
: icon;

const getChildren = (props, icon) => {
// We need to wrap the text so that the icon's :first-child etc. seudo-selectors get applied
// We need to wrap the children so that the icon's :first-child etc. pseudo-selectors get applied
// correctly.
const wrappedChildren = props.children ? <span>{props.children}</span> : undefined;
const wrappedChildren = children ? <span>{children}</span> : undefined;

switch(props.iconPosition) {
switch(iconPosition) {
case 'left':
return (
<span>
{icon}
{iconOrLoading}
{wrappedChildren}
</span>
);
Expand All @@ -78,89 +51,106 @@ const getChildren = (props, icon) => {
return (
<span>
{wrappedChildren}
{icon}
{iconOrLoading}
</span>
);
}
};

const getOnClick = props => (
// onClick is optional, so don't even call it if it's not passed in, or if we're disabled.
props.onClick && !props.isDisabled
? () => props.onClick(props.data)
: () => {}
);

const getCommonProps = (props, icon) => ({
'data-test-subj': props['data-test-subj'],
className: getClassName(props, icon),
onClick: getOnClick(props),
disabled: props.isDisabled,
});

const KuiButton = props => {
const icon = getIcon(props);
const children = getChildren(props, icon);
const commonProps = getCommonProps(props, icon);

const KuiButton = ({
isLoading,
iconPosition = defaultIconPosition,
className,
type,
icon,
onClick,
children,
...rest
}) => {
return (
<button {...commonProps}>
{children}
<button
className={getClassName({ className, type, icon })}
onClick={onClick}
{ ...rest }
>
<ContentWithIcon
icon={icon}
iconPosition={iconPosition}
isLoading={ isLoading }
>
{ children }
</ContentWithIcon>
</button>
);
};

KuiButton.propTypes = {
...nonVoidPropTypes,
...commonPropTypes,
};

KuiButton.defaultProps = {
...nonVoidDefaultProps,
icon: PropTypes.node,
iconPosition: PropTypes.oneOf(ICON_POSITIONS),
children: PropTypes.node,
isLoading: PropTypes.bool,
type: PropTypes.oneOf(BUTTON_TYPES),
onClick: PropTypes.func,
className: PropTypes.string,
};

const KuiLinkButton = props => {
const icon = getIcon(props);
const children = getChildren(props, icon);
const commonProps = getCommonProps(props, icon);

const KuiLinkButton = ({
isLoading,
icon,
iconPosition = defaultIconPosition,
className,
type,
children,
...rest
}) => {
return (
<a
href={props.href}
target={props.target}
{...commonProps}
className={getClassName({ className, type, icon })}
{...rest}
>
{children}
<ContentWithIcon
icon={icon}
iconPosition={iconPosition}
isLoading={ isLoading }
>
{children}
</ContentWithIcon>
</a>
);
};

KuiLinkButton.propTypes = {
href: PropTypes.string,
target: PropTypes.string,
...nonVoidPropTypes,
...commonPropTypes,
};

KuiLinkButton.defaultProps = {
...nonVoidDefaultProps,
icon: PropTypes.node,
iconPosition: PropTypes.oneOf(ICON_POSITIONS),
isLoading: PropTypes.bool,
type: PropTypes.oneOf(BUTTON_TYPES),
className: PropTypes.string,
children: PropTypes.node,
};

const KuiSubmitButton = props => {
const commonProps = getCommonProps(props);

const KuiSubmitButton = ({
className,
type,
onClick,
children,
...rest
}) => {
return (
<input
type="submit"
value={props.children}
{...commonProps}
value={children}
className={getClassName({ className, type })}
onClick={onClick}
{ ...rest }
/>
);
};

KuiSubmitButton.propTypes = {
children: PropTypes.string,
...commonPropTypes,
type: PropTypes.oneOf(BUTTON_TYPES),
onClick: PropTypes.func,
className: PropTypes.string,
};

export {
Expand Down

0 comments on commit d1eed94

Please sign in to comment.