kitchensink
Version:
Dispatch's awesome components and style guide
128 lines (107 loc) • 4.06 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _mouseUpListener = require('./mouse-up-listener');
var _mouseUpListener2 = _interopRequireDefault(_mouseUpListener);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _isInteractiveStyleField = function _isInteractiveStyleField(styleFieldName) {
return styleFieldName === ':hover' || styleFieldName === ':active' || styleFieldName === ':focus';
};
var resolveInteractionStyles = function resolveInteractionStyles(config) {
var ExecutionEnvironment = config.ExecutionEnvironment;
var getComponentField = config.getComponentField;
var getState = config.getState;
var mergeStyles = config.mergeStyles;
var props = config.props;
var setState = config.setState;
var style = config.style;
var newComponentFields = {};
var newProps = {};
// Only add handlers if necessary
if (style[':hover']) {
(function () {
// Always call the existing handler if one is already defined.
// This code, and the very similar ones below, could be abstracted a bit
// more, but it hurts readability IMO.
var existingOnMouseEnter = props.onMouseEnter;
newProps.onMouseEnter = function (e) {
existingOnMouseEnter && existingOnMouseEnter(e);
setState(':hover', true);
};
var existingOnMouseLeave = props.onMouseLeave;
newProps.onMouseLeave = function (e) {
existingOnMouseLeave && existingOnMouseLeave(e);
setState(':hover', false);
};
})();
}
if (style[':active']) {
(function () {
var existingOnMouseDown = props.onMouseDown;
newProps.onMouseDown = function (e) {
existingOnMouseDown && existingOnMouseDown(e);
newComponentFields._lastMouseDown = Date.now();
setState(':active', 'viamousedown');
};
var existingOnKeyDown = props.onKeyDown;
newProps.onKeyDown = function (e) {
existingOnKeyDown && existingOnKeyDown(e);
if (e.key === ' ' || e.key === 'Enter') {
setState(':active', 'viakeydown');
}
};
var existingOnKeyUp = props.onKeyUp;
newProps.onKeyUp = function (e) {
existingOnKeyUp && existingOnKeyUp(e);
if (e.key === ' ' || e.key === 'Enter') {
setState(':active', false);
}
};
})();
}
if (style[':focus']) {
(function () {
var existingOnFocus = props.onFocus;
newProps.onFocus = function (e) {
existingOnFocus && existingOnFocus(e);
setState(':focus', true);
};
var existingOnBlur = props.onBlur;
newProps.onBlur = function (e) {
existingOnBlur && existingOnBlur(e);
setState(':focus', false);
};
})();
}
if (style[':active'] && !getComponentField('_radiumMouseUpListener') && ExecutionEnvironment.canUseEventListeners) {
newComponentFields._radiumMouseUpListener = _mouseUpListener2.default.subscribe(function () {
Object.keys(getComponentField('state')._radiumStyleState).forEach(function (key) {
if (getState(':active', key) === 'viamousedown') {
setState(':active', false, key);
}
});
});
}
// Merge the styles in the order they were defined
var interactionStyles = props.disabled ? [style[':disabled']] : Object.keys(style).filter(function (name) {
return _isInteractiveStyleField(name) && getState(name);
}).map(function (name) {
return style[name];
});
var newStyle = mergeStyles([style].concat(interactionStyles));
// Remove interactive styles
newStyle = Object.keys(newStyle).reduce(function (styleWithoutInteractions, name) {
if (!_isInteractiveStyleField(name) && name !== ':disabled') {
styleWithoutInteractions[name] = newStyle[name];
}
return styleWithoutInteractions;
}, {});
return {
componentFields: newComponentFields,
props: newProps,
style: newStyle
};
};
exports.default = resolveInteractionStyles;
module.exports = exports['default'];