UNPKG

3.46 kBJavaScriptView Raw
1import _extends from "@babel/runtime-corejs2/helpers/esm/extends";
2import _objectWithoutPropertiesLoose from "@babel/runtime-corejs2/helpers/esm/objectWithoutPropertiesLoose";
3import _inheritsLoose from "@babel/runtime-corejs2/helpers/esm/inheritsLoose";
4import _assertThisInitialized from "@babel/runtime-corejs2/helpers/esm/assertThisInitialized";
5import React from 'react';
6import PropTypes from 'prop-types';
7import elementType from 'prop-types-extra/lib/elementType';
8import createChainedFunction from './utils/createChainedFunction';
9var propTypes = {
10 href: PropTypes.string,
11 onClick: PropTypes.func,
12 onKeyDown: PropTypes.func,
13 disabled: PropTypes.bool,
14 role: PropTypes.string,
15 tabIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
16
17 /**
18 * this is sort of silly but needed for Button
19 */
20 componentClass: elementType
21};
22var defaultProps = {
23 componentClass: 'a'
24};
25
26function isTrivialHref(href) {
27 return !href || href.trim() === '#';
28}
29/**
30 * There are situations due to browser quirks or Bootstrap CSS where
31 * an anchor tag is needed, when semantically a button tag is the
32 * better choice. SafeAnchor ensures that when an anchor is used like a
33 * button its accessible. It also emulates input `disabled` behavior for
34 * links, which is usually desirable for Buttons, NavItems, MenuItems, etc.
35 */
36
37
38var SafeAnchor =
39/*#__PURE__*/
40function (_React$Component) {
41 _inheritsLoose(SafeAnchor, _React$Component);
42
43 function SafeAnchor(props, context) {
44 var _this;
45
46 _this = _React$Component.call(this, props, context) || this;
47 _this.handleClick = _this.handleClick.bind(_assertThisInitialized(_assertThisInitialized(_this)));
48 _this.handleKeyDown = _this.handleKeyDown.bind(_assertThisInitialized(_assertThisInitialized(_this)));
49 return _this;
50 }
51
52 var _proto = SafeAnchor.prototype;
53
54 _proto.handleClick = function handleClick(event) {
55 var _this$props = this.props,
56 disabled = _this$props.disabled,
57 href = _this$props.href,
58 onClick = _this$props.onClick;
59
60 if (disabled || isTrivialHref(href)) {
61 event.preventDefault();
62 }
63
64 if (disabled) {
65 event.stopPropagation();
66 return;
67 }
68
69 if (onClick) {
70 onClick(event);
71 }
72 };
73
74 _proto.handleKeyDown = function handleKeyDown(event) {
75 if (event.key === ' ') {
76 event.preventDefault();
77 this.handleClick(event);
78 }
79 };
80
81 _proto.render = function render() {
82 var _this$props2 = this.props,
83 Component = _this$props2.componentClass,
84 disabled = _this$props2.disabled,
85 onKeyDown = _this$props2.onKeyDown,
86 props = _objectWithoutPropertiesLoose(_this$props2, ["componentClass", "disabled", "onKeyDown"]);
87
88 if (isTrivialHref(props.href)) {
89 props.role = props.role || 'button'; // we want to make sure there is a href attribute on the node
90 // otherwise, the cursor incorrectly styled (except with role='button')
91
92 props.href = props.href || '#';
93 }
94
95 if (disabled) {
96 props.tabIndex = -1;
97 props.style = _extends({
98 pointerEvents: 'none'
99 }, props.style);
100 }
101
102 return React.createElement(Component, _extends({}, props, {
103 onClick: this.handleClick,
104 onKeyDown: createChainedFunction(this.handleKeyDown, onKeyDown)
105 }));
106 };
107
108 return SafeAnchor;
109}(React.Component);
110
111SafeAnchor.propTypes = propTypes;
112SafeAnchor.defaultProps = defaultProps;
113export default SafeAnchor;
\No newline at end of file