carbon-react
Version:
A library of reusable React components and an interface for easily building user interfaces based on Flux.
438 lines (359 loc) • 10.8 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react2 = require('react');
var _react3 = _interopRequireDefault(_react2);
var _babelTransform = require('livereactload/babel-transform');
var _babelTransform2 = _interopRequireDefault(_babelTransform);
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _class, _temp;
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _classnames = require('classnames');
var _classnames2 = _interopRequireDefault(_classnames);
var _lodash = require('lodash');
var _icon = require('./../icon');
var _icon2 = _interopRequireDefault(_icon);
var _reactRouter = require('react-router');
var _ether = require('../../utils/ether');
var _events = require('./../../utils/helpers/events');
var _events2 = _interopRequireDefault(_events);
var _tags = require('../../utils/helpers/tags');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var _components = {
_Link: {
displayName: '_Link'
}
};
var _livereactloadBabelTransform2 = (0, _babelTransform2.default)({
filename: 'src/components/link/link.js',
components: _components,
locals: [],
imports: [_react3.default]
});
function _wrapComponent(id) {
return function (Component) {
return _livereactloadBabelTransform2(Component, id);
};
}
/**
* A link widget.
*
* == How to use a Link in a component:
*
* In your file:
*
* import Link from 'carbon/lib/components/link';
*
* To render the Link:
*
* <Link href='foo'>Main Page</Link>
*
* For additional properties specific to this component, see propTypes.
*
* @class Link
* @constructor
*/
var _Link = _wrapComponent('_Link')((_temp = _class = function (_React$Component) {
_inherits(_Link, _React$Component);
function _Link() {
_classCallCheck(this, _Link);
var _this = _possibleConstructorReturn(this, (_Link.__proto__ || Object.getPrototypeOf(_Link)).call(this));
_this.onKeyDown = _this.onKeyDown.bind(_this);
return _this;
}
_createClass(_Link, [{
key: 'onKeyDown',
/**
* Triggers the onClick event for the enter key
*
* @method onKeyDown
* @param {Object} ev
*/
value: function onKeyDown(ev) {
if (this.props.onKeyDown) {
this.props.onKeyDown(ev);
}
// return early if there is no onClick or there is a href prop
if (!this.props.onClick || this.props.href) {
return;
}
// return early if the event is not an enter key
if (!_events2.default.isEnterKey(ev)) {
return;
}
this.props.onClick(ev);
}
/**
* Renders the component.
*
* @method render
*/
}, {
key: 'render',
value: function render() {
return _react3.default.createElement(this.linkType.component, this.componentProps, _react3.default.createElement(
'span',
null,
this.iconLeft,
_react3.default.createElement(
'span',
{ className: 'carbon-link__content' },
this.props.children
),
this.iconRight
));
}
}, {
key: 'componentProps',
/**
* Getter for component properties.
*
* @method componentProps
* @return {Object} props
*/
get: function get() {
var _validProps = (0, _ether.validProps)(this),
props = _objectWithoutProperties(_validProps, []);
props.tabIndex = this.tabIndex;
props = (0, _lodash.assign)({}, props, (0, _tags.tagComponent)('link', this.props));
delete props.href;
delete props.tabbable;
delete props.to;
props.className = this.componentClasses;
props[this.linkType.prop] = this.url;
props.onKeyDown = this.onKeyDown;
return props;
}
/**
* Getter for componet classes.
*
* @method componentClasses
* @return {String} class names
*/
}, {
key: 'componentClasses',
get: function get() {
return (0, _classnames2.default)('carbon-link__anchor', this.props.className, { 'carbon-link__anchor--disabled': this.props.disabled });
}
/**
* Returns the icon if enabled and aligned to the left.
*
* @method iconLeft
* @return {Object} JSX
*/
}, {
key: 'iconLeft',
get: function get() {
if (!this.props.icon || this.props.iconAlign !== 'left') {
return null;
}
return this.icon;
}
/**
* Returns the icon if enabled and aligned to the right.
*
* @method iconRight
* @return {Object} JSX
*/
}, {
key: 'iconRight',
get: function get() {
if (!this.props.icon || this.props.iconAlign !== 'right') {
return null;
}
return this.icon;
}
/**
* Returns the markup for the icon.
*
* @method icon
* @return {Object} JSX
*/
}, {
key: 'icon',
get: function get() {
var classes = (0, _classnames2.default)("carbon-link__icon", 'carbon-link__icon--align-' + this.props.iconAlign);
return _react3.default.createElement(_icon2.default, {
type: this.props.icon,
className: classes,
tooltipMessage: this.props.tooltipMessage,
tooltipAlign: this.props.tooltipAlign,
tooltipPosition: this.props.tooltipPosition
});
}
/**
* Returns 0 or -1 for tabindex
*
* @method tabIndex
* @return {String} 0 or -1
*/
}, {
key: 'tabIndex',
get: function get() {
return this.props.tabbable && !this.props.disabled ? '0' : '-1';
}
/**
* Regex for finding 'href:' or 'to:',
*
* @method typeRegex
* @return {Regex}
*/
}, {
key: 'typeRegex',
get: function get() {
return (/^href:|^to:/
);
}
/**
* A hash of the different link types.
*
* @method linkTypes
* @return {Object}
*/
}, {
key: 'linkTypes',
get: function get() {
return {
to: {
prop: "to",
component: _reactRouter.Link
},
href: {
prop: "href",
component: "a"
}
};
}
/**
* Returns the correct link type based on the given props.
*
* @method linkType
* @return {Object}
*/
}, {
key: 'linkType',
get: function get() {
var url = this.props.href || this.props.to,
type = "href";
if (url) {
var match = url.match(this.typeRegex);
if (match) {
type = match[0].substr(0, match[0].length - 1);
} else if (this.props.href) {
type = "href";
} else {
type = "to";
}
}
return this.linkTypes[type];
}
/**
* Returns the parsed URL for the link.
*
* @method url
* @return {String}
*/
}, {
key: 'url',
get: function get() {
var url = this.props.href || this.props.to;
if (!url) {
return null;
}
return url.replace(this.typeRegex, "");
}
}]);
return _Link;
}(_react3.default.Component), _class.propTypes = {
/**
* Children elements
*
* @property children
* @type {Node}
*/
children: _propTypes2.default.node,
/**
* Gives the link a disabled state.
*
* @property disabled
* @type {Boolean}
* @default undefined
*/
disabled: _propTypes2.default.bool,
/**
* Use `href` to use a generic anchor. You can also prefix your value
* with `to:` or `href:` to override the prop type.
*
* @property href
* @type {String}
* @default undefined
*/
href: _propTypes2.default.string,
/**
* Renders an icon inline with the link.
*
* @property icon
* @type {String}
* @default undefined
*/
icon: _propTypes2.default.string,
/**
* Configures the alignment of the icon (left or right).
*
* @property iconAlign
* @type {String}
* @default left
*/
iconAlign: _propTypes2.default.string,
/**
* Allows the <a> tag to be set in or out of the tab order of the page
* Boolean is used as tabindex > 0 is not really necessary, HTML order should
* take precedence
*
* @property tabbable
* @type {Boolean}
* @default true
*/
tabbable: _propTypes2.default.bool,
/**
* Use `to` to use the React Router link. You can also prefix your value
* with `to:` or `href:` to override the prop type.
*
* @property to
* @type {String}
* @default undefined
*/
to: _propTypes2.default.string,
/**
* The message for this tooltip
*
* @property
* @type {String}
*/
tooltipMessage: _propTypes2.default.string,
/**
* The position of this tooltip: top, bottom, left or right
*
* @property
* @default top
* @type {String}
*/
tooltipPosition: _propTypes2.default.string,
/**
* The alignment of this tooltip: left, right or center
*
* @property
* @default center
* @type {String}
*/
tooltipAlign: _propTypes2.default.string
}, _class.defaultProps = {
iconAlign: 'left',
tabbable: true }, _temp));
exports.default = _Link;