@retailmenot/anchor
Version:
A React UI Library by RetailMeNot
291 lines (261 loc) • 11.2 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var __chunk_1 = require('./anchor-chunk-24f232e7.js');
var __chunk_2 = require('./anchor-chunk-9d9a5df6.js');
var __chunk_9 = require('./anchor-chunk-f296150d.js');
var __chunk_11 = require('./anchor-chunk-044b0898.js');
var rxjs = require('rxjs');
var operators = require('rxjs/operators');
var React = require('react');
var classNames = _interopDefault(require('classnames'));
var styled = require('@xstyled/styled-components');
var styled__default = _interopDefault(styled);
var system = require('@xstyled/system');
function _templateObject() {
var data = __chunk_1._taggedTemplateLiteral(["\n box-sizing: border-box;\n font-family: base;\n position: relative;\n cursor: pointer;\n display: inline-flex;\n justify-content: center;\n align-items: center;\n min-height: 1rem;\n min-width: 1rem;\n\n ", ";\n\n ", "\n"]);
_templateObject = function _templateObject() {
return data;
};
return data;
}
var StyledDropDown = styled__default('div')(_templateObject(), function (_ref) {
var position = _ref.position,
spacing = _ref.spacing;
if (!spacing) {
return null;
}
switch (position) {
case 'bottom':
case 'bottomStart':
case 'bottomEnd':
return styled.css({
paddingBottom: spacing,
// this won't work for a negative spacing values. if we fix
// these we could allow negative values
marginBottom: "-".concat(spacing)
});
case 'right':
case 'rightStart':
case 'rightEnd':
return styled.css({
paddingRight: spacing,
marginRight: "-".concat(spacing)
});
case 'left':
case 'leftStart':
case 'leftEnd':
return styled.css({
paddingLeft: spacing,
marginLeft: "-".concat(spacing)
});
case 'top':
case 'topStart':
case 'topEnd':
return styled.css({
paddingTop: spacing,
marginTop: "-".concat(spacing)
});
}
return null;
}, system.space);
var DropDown = /*#__PURE__*/function (_React$Component) {
__chunk_1._inherits(DropDown, _React$Component);
var _super = __chunk_1._createSuper(DropDown);
function DropDown() {
var _this;
__chunk_1._classCallCheck(this, DropDown);
_this = _super.apply(this, arguments); // State
_this.state = {
hovered: false,
clicked: false
}; // Instance Reference
_this.dropDownReference = React.createRef();
_this.containerReference = React.createRef();
return _this;
}
__chunk_1._createClass(DropDown, [{
key: "isOpen",
value: function isOpen() {
var _this$props = this.props,
open = _this$props.open,
_this$props$trigger = _this$props.trigger,
trigger = _this$props$trigger === void 0 ? 'both' : _this$props$trigger;
var _this$state = this.state,
clicked = _this$state.clicked,
hovered = _this$state.hovered;
return open !== undefined ? open : trigger === 'click' && clicked || trigger === 'hover' && hovered || trigger === 'both' && (hovered || clicked);
}
}, {
key: "componentDidMount",
value: function componentDidMount() {
var _this2 = this;
var dropDown = this.dropDownReference.current;
var container = this.containerReference.current;
this.setState({
height: __chunk_9.get(dropDown, 'clientHeight', 0),
width: __chunk_9.get(dropDown, 'clientWidth', 0),
containerHeight: __chunk_9.get(container, 'clientHeight', 0),
containerWidth: __chunk_9.get(container, 'clientWidth', 0)
}); // Dropdown Instance
this.rootElement = dropDown && dropDown.getRootNode ? dropDown.getRootNode() : document;
var outsideClick$ = rxjs.merge(rxjs.fromEvent(this.rootElement, 'click'), rxjs.fromEvent(this.rootElement, 'touchstart')).pipe(operators.filter(function () {
return _this2.isOpen();
}), operators.filter(function (_ref2) {
var target = _ref2.target;
return !dropDown.contains(target);
}), operators.throttleTime(500));
var dropDownClick$ = rxjs.merge(rxjs.fromEvent(dropDown, 'click'), rxjs.fromEvent(dropDown, 'touchstart')).pipe(operators.throttleTime(500));
var escapeKey$ = rxjs.fromEvent(this.rootElement, 'keyup').pipe(operators.filter(function () {
return _this2.isOpen();
}), operators.filter(function (keyEvent) {
return keyEvent.key === 'Escape';
}));
var mouseEnter$ = rxjs.fromEvent(dropDown, 'mouseenter');
var mouseLeave$ = rxjs.fromEvent(dropDown, 'mouseleave');
this.clickedSub = rxjs.merge(outsideClick$.pipe(operators.mapTo(false)), escapeKey$.pipe(operators.mapTo(false)), dropDownClick$.pipe(operators.map(function () {
return !_this2.state.clicked;
}))).subscribe(function (clicked) {
_this2.setState(function (_ref3) {
var height = _ref3.height,
width = _ref3.width;
return {
clicked: clicked,
height: clicked ? __chunk_9.get(dropDown, 'clientHeight', 0) : height,
width: clicked ? __chunk_9.get(dropDown, 'clientWidth', 0) : width
};
});
if (_this2.props.onTriggered) {
_this2.props.onTriggered(clicked, 'click');
}
});
this.escapeSub = escapeKey$.subscribe(function (event) {
if (_this2.props.onEscapeKey) {
_this2.props.onEscapeKey(event);
}
});
this.outsideClickSub = outsideClick$.subscribe(function (event) {
if (_this2.props.onOutsideClick) {
_this2.props.onOutsideClick(event);
}
});
this.hoveredSub = rxjs.merge(mouseEnter$.pipe(operators.mapTo(true)), mouseLeave$.pipe(operators.mapTo(false)), escapeKey$.pipe(operators.mapTo(false)), dropDownClick$.pipe(operators.mapTo(false))).pipe(operators.filter(function () {
return _this2.props.trigger === 'hover' || _this2.props.trigger === 'both';
}), operators.distinctUntilChanged()).subscribe(function (hovered) {
_this2.setState(function (_ref4) {
var height = _ref4.height,
width = _ref4.width;
return {
hovered: hovered,
height: hovered ? __chunk_9.get(dropDown, 'clientHeight', 0) : height,
width: hovered ? __chunk_9.get(dropDown, 'clientWidth', 0) : width
};
});
if (_this2.props.onTriggered) {
_this2.props.onTriggered(hovered, 'hover');
}
});
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
this.hoveredSub.unsubscribe();
this.clickedSub.unsubscribe();
this.escapeSub.unsubscribe();
this.outsideClickSub.unsubscribe();
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
var prevShowArrow = prevProps.showArrow,
prevPosition = prevProps.position,
prevSpacing = prevProps.spacing;
var _this$props2 = this.props,
showArrow = _this$props2.showArrow,
position = _this$props2.position,
spacing = _this$props2.spacing;
if (showArrow !== prevShowArrow || position !== prevPosition || spacing !== prevSpacing) {
var dropDown = this.dropDownReference.current;
var container = this.containerReference.current;
if (container) {
this.setState({
height: __chunk_9.get(dropDown, 'clientHeight', 0),
width: __chunk_9.get(dropDown, 'clientWidth', 0),
containerHeight: __chunk_9.get(container, 'clientHeight', 0),
containerWidth: __chunk_9.get(container, 'clientWidth', 0)
});
}
}
}
}, {
key: "render",
value: function render() {
var _a = this.props,
children = _a.children,
className = _a.className,
overlay = _a.overlay,
spacing = _a.spacing,
arrowSize = _a.arrowSize,
debug = _a.debug,
_a$trigger = _a.trigger,
arrowIndent = _a.arrowIndent,
_a$showArrow = _a.showArrow,
showArrow = _a$showArrow === void 0 ? true : _a$showArrow,
_a$position = _a.position,
position = _a$position === void 0 ? 'bottom' : _a$position,
_a$shadow = _a.shadow,
shadow = _a$shadow === void 0 ? '0 0 0.5rem 0 rgba(0,0,0,0.2)' : _a$shadow,
_a$border = _a.border,
border = _a$border === void 0 ? 'light' : _a$border,
_a$borderRadius = _a.borderRadius,
borderRadius = _a$borderRadius === void 0 ? 'base' : _a$borderRadius,
_a$background = _a.background,
background = _a$background === void 0 ? 'white' : _a$background,
_a$onTriggered = _a.onTriggered,
_a$onEscapeKey = _a.onEscapeKey,
_a$onOutsideClick = _a.onOutsideClick,
props = __chunk_2.__rest(_a, ["children", "className", "overlay", "spacing", "arrowSize", "debug", "trigger", "arrowIndent", "showArrow", "position", "shadow", "border", "borderRadius", "background", "onTriggered", "onEscapeKey", "onOutsideClick"]);
var _this$state2 = this.state,
_this$state2$height = _this$state2.height,
height = _this$state2$height === void 0 ? 0 : _this$state2$height,
_this$state2$width = _this$state2.width,
width = _this$state2$width === void 0 ? 0 : _this$state2$width,
_this$state2$containe = _this$state2.containerHeight,
containerHeight = _this$state2$containe === void 0 ? 0 : _this$state2$containe,
_this$state2$containe2 = _this$state2.containerWidth,
containerWidth = _this$state2$containe2 === void 0 ? 0 : _this$state2$containe2;
var showDropdown = this.isOpen(); // if they don't specify a spacing then we'll default
// based on whether the arrow is there or not
var spacingWithDefault = typeof spacing === 'undefined' ? showArrow ? '0.75rem' : '0' : spacing;
return React.createElement(StyledDropDown, Object.assign({
ref: this.dropDownReference,
className: classNames('anchor-drop-down', className),
showArrow: showArrow,
shadow: shadow,
position: position,
spacing: spacingWithDefault
}, props), children, React.createElement(__chunk_11.PositionContainer, {
ref: this.containerReference,
active: showDropdown,
arrowIndent: arrowIndent,
arrowSize: arrowSize,
background: background,
border: border,
borderRadius: borderRadius,
children: overlay,
className: "anchor-drop-down-container",
containerHeight: containerHeight,
containerWidth: containerWidth,
height: height,
width: width,
position: position,
shadow: shadow,
showArrow: showArrow,
debug: debug
}));
}
}]);
return DropDown;
}(React.Component);
exports.DropDown = DropDown;
//# sourceMappingURL=dropdown.js.map