X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=skyquake%2Fframework%2Fwidgets%2Fbutton%2Frw.button.js;fp=skyquake%2Fframework%2Fwidgets%2Fbutton%2Frw.button.js;h=41730eb86aa0c450e3e0292cdf1b076e20661f22;hb=e29efc315df33d546237e270470916e26df391d6;hp=0000000000000000000000000000000000000000;hpb=9c5e457509ba5a1822c316635c6308874e61b4b9;p=osm%2FUI.git diff --git a/skyquake/framework/widgets/button/rw.button.js b/skyquake/framework/widgets/button/rw.button.js new file mode 100644 index 000000000..41730eb86 --- /dev/null +++ b/skyquake/framework/widgets/button/rw.button.js @@ -0,0 +1,261 @@ + +/* + * + * Copyright 2016 RIFT.IO Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +import './button.scss'; +import Loader from '../loading-indicator/loadingIndicator.jsx'; +var React = require('react'); +var ButtonEventListenerMixin = require('../mixins/ButtonEventListener.js'); + + +/** + * A generic button component. + * It's props values and a brief description below + * + * Label: The label of the button. What it displays at any given time. + * Icon: A url for an icon that will be displayed on the button. Leave blank if no icon required. + * Class: Css Classes applied to the element. + * sizeOfButton: The preset sizes for the button (small, default, large, xlarge, expand). + * minWidth: Minimum Width of the button. + * maxWidth: Maximum Width of the button. + **/ +module.exports = React.createClass({ + displayName: "Button", + mixins:[ButtonEventListenerMixin], + propTypes: { + label: React.PropTypes.string, + icon: React.PropTypes.array, + className: React.PropTypes.string, + //sizeOfButton: React.PropTypes.string, + minWidth: React.PropTypes.string, + maxWidth: React.PropTypes.string, + //isActive: React.PropTypes.bool, + //isFocused: React.PropTypes.bool, + //isHovered: React.PropTypes.bool, + isDisabled: React.PropTypes.bool + }, + + + /** + * Defines default state. + * sizeOfButton: See Prop type definitions. + * class: See Prop type definitions. + * label: See Prop type definitions. + * isActive: Boolean to indicate if button is active. + * isHovered: Boolean to indicate if the button is being hovered over. + * isFocused: Boolean to indicate if the button has been focused. + * isDisabled: Boolean to indicate if button has been disabled. + * @returns {{sizeOfButton: (*|string), class: *, isActive: boolean, isHovered: boolean, + * isFocused: boolean, isDisabled: (*|boolean), label: *}} + */ + getInitialState: function() { + return { + //sizeOfButton: this.props.size || '', //There is no Medium value in CSS, default size is the absence of a value + className: this.props.className || 'rw-button-primary', //Default value is 'rw-button-primary' which is the primary one + label: this.props.label, + isActive: false, + isHovered: false, + isFocused: false, + isLoading: this.props.isLoading || false, + isDisabled: this.props.isDisabled || false + } + }, + + + /** + * If any of the state variables have changed, the component should update. + * "nextProps" and "nextState" hold the state and property variables as they will be after the update. + * "this.props" and "this.state" hold the state and property variables as they were before the update. + * returns true if the state have changed. Otherwise returns false. + * @param nextProps + * @param nextState + * @returns {boolean} + */ + shouldComponentUpdate: function(nextProps, nextState) { + var currentStateString = this.state.label + this.state.isDisabled + this.state.isActive + this.state.isFocused + + this.state.isHovered + this.props.isLoading; + var nextStateString = nextState.label + nextState.isDisabled + nextState.isActive + nextState.isFocused + + nextState.isHovered + nextProps.isLoading; + + if (currentStateString == nextStateString) { + return false; + } + return true; + }, + + + /** + * Returns a string reflecting the current state of the button. + * If the button state "isDisabled" is true, returns a string "disabled". + * Otherwise returns a string containing a word for each state that has been set to true. + * (ie "active focused" if the states active and focused are true, but hovered is false). + * @returns {string} + */ + setButtonState: function() { + var ret = ""; + if (this.state.isDisabled) { + return "disabled"; + } + if (this.state.isActive) { + ret += "active "; + } + if (this.state.isHovered) { + ret += "hovered "; + } + if (this.state.isFocused) { + ret += "focused "; + } + return ret; + }, + + + + /** + * Track the width if set and write into markup using Style attribute + * Returns the minWidth and maxWidth prop in a string + * @returns {{}} + */ + setButtonWidth:function(){
 + var width = {};

 + + if (this.props.minWidth) {
 + width.minWidth = String(this.props.minWidth);
 + }
 + if (this.props.maxWidth) {
 + width.maxWidth = String(this.props.maxWidth);
 + }
 + + return width;
 + }, + + + + /** + * Apply the size of the button to the icon directly + * Returns a string indicating the icon size. + * @returns {string} + */ + /* + setIconSize:function(){ + + var iconClass = "rw-icon"; + + if(this.props.size){ + iconClass += "-" + this.props.size; + } + return iconClass; + }, + */ + + + + /** + * Builds the list of classes. + * Returns a string holding each class seperated by a space. + * @returns {string} + */ + /* + setButtonClass:function() { + var buttonClass = ""; + var buttonClassType = "rw-button-primary"; + // If the size is declared, add it in + if (this.state.sizeOfButton) { + buttonClass += this.state.sizeOfButton; + } + // + if (typeof(this.props.className) != "undefined") { + this.props.className.push("rw-button-secondary"); + + // Run through the array and check all the values + for (var i = 0; i < this.props.className.length; i++) { + + if (this.props.className[i].indexOf("secondary") > -1) { + buttonClassType = "rw-button-secondary"; // If the value of the array is equal to the string "secondary", add a predefined string + } else { + buttonClass += " " + this.props.className[i]; // Else just write the value of the array + } + } + } + buttonClass += " " + buttonClassType; //Add the button style type either primary or secondary + return buttonClass; + }, + */ + + /** + * Builds an array of html elements for the icons and returns them. + * @returns {Array} + */ + setIconElement: function() { + var button_icon = []; + + if (typeof(this.props.icon) != "undefined") { + for (var i = 0; i < this.props.icon.length; i++) { + button_icon.push(React.createElement('svg', { + className: "rw-button__icon", + key: i, + dangerouslySetInnerHTML: {__html: ''} //Using a React method to drop in a hack since React does not support xlink:href yet + })); + } + } + return button_icon; + }, + + /** + * Renders the Button Component + * Returns a react component that constructs the html that houses the button component. + * @returns {*} + */ + render: function() { + var button = null; + var button_style = this.setButtonWidth(); + var button_state = this.setButtonState(); + var button_class = this.state.className; + var button_icon = this.setIconElement(); + var display = this.state.label; + if (this.props.isLoading) { + display = React.createElement(Loader, {show: true, size: '1rem', color: this.props.loadingColor}); + } + + button = React.createElement("button", { + className: button_class, + "data-state": button_state, + style: button_style, + + // onClick: this.onClick, + onClick: this.props.onClick, + onMouseUp: this.onMouseUp, + onMouseDown: this.onMouseDown, + onMouseOver: this.onMouseOver, + onMouseEnter: this.onMouseEnter, + onMouseLeave: this.onMouseLeave, + onMouseOut: this.onMouseOut, + onTouchCancel: this.onTouchCancel, + onTouchEnd: this.onTouchEnd, + onTouchMove: this.onTouchMove, + onTouchStart: this.onTouchStart, + onKeyDown: this.onKeyDown, + onKeyPress: this.onKeyPress, + onKeyUp: this.onKeyUp, + onFocus: this.onFocus, + onBlur: this.onBlur + }, + button_icon, + React.createElement("span", {className: "rw-button__label"}, display) + ); + return button; + } +});