Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@skava/packages / ui / Button / BaseButtonAtom / BaseButtonAtom.js
Size: Mime:
import React from 'react';
import toClassName from 'classnames';
import { Link } from '@skava/link';
import { isFunction, isString } from 'exotic';
import { toCommonState } from '@skava/state';
import { toIdentifier } from '@skava/identifier';
import { Image } from '@skava/packages/ui';
import { classes } from './fixture';
import { StyledButton, StyledDiv, StyledInputButton, StyledButtonText } from './styled';
import { isImage } from './deps';
class Button extends React.Component {
    constructor() {
        super(...arguments);
        this.state = toCommonState(this.props);
        /**
         * @description handles keydown enter - auto works with isFocused
         */
        this.handleKeyDown = (event) => {
            if (event.key === 'Enter') {
                const baseButtonOnClick = this.props.onClick;
                if (!isFunction(baseButtonOnClick)) {
                    this.handleClick(event);
                }
                // this.state.activate()
            }
            else if (event.key === 'Space' || event.key === ' ') {
                // ada
                if (this.isLink === true) {
                    this.handleClick(event);
                    // this.state.activate()
                }
            }
            else {
                console.log(event.key);
                // @Note this causes errors on Tabbing through modals
                // this.state.deactivate()
            }
        };
        this.handleClick = (event) => {
            console.log('BUTTON_CLICK');
            const baseButtonOnClick = this.props.handleClick || this.props.onClick;
            if (isFunction(baseButtonOnClick)) {
                baseButtonOnClick(event);
            }
        };
    }
    /**
     * @todo - state does not have these
     */
    get isDisabled() {
        // || this.state.isDisabled
        return this.props.states === 'disabled' || this.props.isDisabled;
    }
    get isSelected() {
        return this.props.states === 'selected' || this.props.isSelected || this.state.isSelected;
    }
    get isFocused() {
        return this.props.states === 'focused' || this.props.isFocused || this.state.isFocused;
    }
    get isResting() {
        return this.props.states === 'resting' || this.props.isResting || this.state.isResting;
    }
    get isPushed() {
        return this.props.states === 'pushed' || this.props.isPushed || this.state.isPushed;
    }
    /**
     * @alias isSecondary
     * ^ (on a secondary button color......)
     *
     * @description makes it gray but not disabled, or less attention
     * @return {Boolean}
     */
    get isLowPriority() {
        return this.props.isLowPriority;
    }
    /**
     * @todo right, left... ?
     */
    get className() {
        const extendedClassName = this.extendedClassName || this.props.extendedClassName || '';
        const defaultClassName = this.props.defaultClassName || '';
        const className = this.props.className || '';
        const isSquare = this.props.isSquare;
        const squareClass = isSquare ? classes.default : '';
        const iconOrder = this.props.iconOrder;
        const dynamic = {
            [classes.isIconLeft]: iconOrder === 'left' || !!iconOrder,
            [classes.isIconRight]: iconOrder === 'right' || !!iconOrder,
            [classes.isGhost]: this.props.ghost === true,
            [classes.isLowPriority]: this.isLowPriority,
            [classes.isSelected]: this.isSelected,
            [classes.isDisabled]: this.isDisabled,
            [classes.isFocused]: this.isFocused,
            [classes.isResting]: this.isResting,
            [classes.isPushed]: this.isPushed,
            [classes.center]: this.props.center,
        };
        return toClassName(defaultClassName, squareClass, className, dynamic, extendedClassName);
    }
    /* eslint-disable brace-style */
    get icon() {
        const IconComponentOrView = this.props.icon;
        // do we have one?
        if (IconComponentOrView === undefined) {
            return '';
        }
        // did we already render it?
        else if (React.isValidElement(IconComponentOrView)) {
            return IconComponentOrView;
        }
        // is a class/function/component
        else if (isFunction(IconComponentOrView)) {
            return React.createElement(IconComponentOrView, Object.assign({}, this.props, { key: "icon" }));
        }
        else if (isImage(IconComponentOrView)) {
            return React.createElement(Image, { src: IconComponentOrView });
        }
        else {
            /**
             * @todo depending on event system - @see ReactEvents
             */
            return '';
        }
    }
    get isLink() {
        return this.props.to !== undefined || this.props.isLink === true;
    }
    get role() {
        return isString(this.props.role) ? this.props.role : this.isLink === true ? 'link' : 'button';
    }
    get target() {
        return this.props.target;
    }
    get type() {
        return this.props.type;
    }
    get identifier() {
        return this.props.identifier || this.props.id || toIdentifier(this, 'button');
    }
    get children() {
        return this.props.text || this.props.value || this.props.children;
    }
    get label() {
        // || humanize(this.props.className) || throw new Error()
        return this.props['aria-label'] || this.props.label || this.children;
    }
    // @todo tabindex for -1 inside of expandable divs
    //
    // @todo aria-flowto for compare & modal
    // https://www.w3.org/TR/wai-aria/states_and_properties#aria-flowto
    //
    // @todo aria-controls
    // https://www.w3.org/TR/wai-aria/states_and_properties#aria-controls
    //
    // @todo aria-busy
    // https://www.w3.org/TR/wai-aria/states_and_properties#aria-busy
    get accessibleAttributes() {
        const accessibleAttributes = {
            // @todo isToggle for toggle states
            // 'aria-label': this.label,
            // can use for controlledby and controls
            id: this.identifier,
        };
        if (isString(this.label)) {
            accessibleAttributes['aria-label'] = this.label;
        }
        if (this.role !== 'link') {
            accessibleAttributes['aria-pressed'] = this.state.isActive;
        }
        if (isString(this.props.qa) || isString(this.props['data-qa'])) {
            accessibleAttributes['data-qa'] = this.props.qa || this.props['data-qa'];
        }
        if (isString(this.props.form)) {
            accessibleAttributes.form = this.props.form;
        }
        return accessibleAttributes;
    }
    get attributes() {
        // should not use this.props.class ever as class is a js reserved word
        // and also className is the React convection
        const { className, icon, children, target, role } = this;
        const { elementType } = this.props;
        let text = isString(children) ? React.createElement(StyledButtonText, null, children) : children;
        // const accessibleArea = <span className="button-accessible" />
        // we may pass in a link element manually
        if (this.isLink === true && this.props.to !== undefined) {
            // @todo - linkClassName
            text = (React.createElement(Link, { to: this.props.to, target: target }, text));
        }
        // @todo - text select none with just an icon
        const hasIconAndText = icon && text;
        // add icon if we have one
        // to put icon after, either use `order` or we extend this
        let value = hasIconAndText
            ? // both
                [icon, text]
            : icon
                ? // just icon
                    icon
                : // just text
                    text;
        if (elementType === 'inputButton') {
            value = children;
        }
        return {
            ...this.props,
            className,
            value,
            role: this.role,
            tabIndex: this.tabIndex,
        };
    }
    get tabIndex() {
        if (this.props.tabIndex !== undefined) {
            return this.props.tabIndex;
        }
        else if (this.props.isPresentational === true) {
            /**
             * @example a list of images like on the carousell,
             *          you want to tab each image,
             *          not tab the navigation
             */
            return undefined;
        }
        else {
            return '0';
        }
    }
    get attributeProps() {
        const { className, style, role, tabIndex } = this.attributes;
        const attributes = {
            className,
        };
        if (tabIndex !== undefined) {
            attributes.style = style;
            attributes.tabIndex = tabIndex;
        }
        if (this.props.onSubmit !== undefined) {
            attributes.onSubmit = this.props.onSubmit;
        }
        // next will be <link
        if (role !== 'button') {
            attributes.role = role;
        }
        return attributes;
    }
    render() {
        const { role, styles, value } = this.attributes;
        const { elementType } = this.props;
        const attributes = this.attributeProps;
        const propsToPass = {
            onFocus: this.state.handleFocus,
            onBlur: this.state.handleBlur,
            onKeyDown: this.handleKeyDown,
            onClick: this.handleClick,
        };
        if (elementType === 'inputButton') {
            return (React.createElement(StyledInputButton, Object.assign({ type: this.type, value: value }, propsToPass, attributes, this.accessibleAttributes)));
        }
        return role === 'button' || role !== 'link' ? (React.createElement(StyledButton, Object.assign({}, propsToPass, attributes, this.accessibleAttributes),
            ' ',
            value,
            ' ')) : (React.createElement(StyledDiv, Object.assign({}, propsToPass, attributes, this.accessibleAttributes),
            ' ',
            value,
            ' '));
    }
}
Button.defaultProps = {
    className: 'button-atom',
    defaultClassName: '',
    timeout: 60,
    shouldAnimate: false,
    isActive: false,
    target: '',
};
export default Button;
export { Button };
//# sourceMappingURL=BaseButtonAtom.js.map