victory-create-container
Version:
Container Helper for Victory
118 lines (115 loc) • 5.52 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createContainer = void 0;
exports.makeCreateContainerFunction = makeCreateContainerFunction;
var _react = _interopRequireDefault(require("react"));
var _forOwn = _interopRequireDefault(require("lodash/forOwn"));
var _groupBy = _interopRequireDefault(require("lodash/groupBy"));
var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
var _toPairs = _interopRequireDefault(require("lodash/toPairs"));
var _victoryZoomContainer = require("victory-zoom-container");
var _victorySelectionContainer = require("victory-selection-container");
var _victoryCore = require("victory-core");
var _victoryVoronoiContainer = require("victory-voronoi-container");
var _victoryCursorContainer = require("victory-cursor-container");
var _victoryBrushContainer = require("victory-brush-container");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function ensureArray(thing) {
if (!thing) {
return [];
} else if (!Array.isArray(thing)) {
return [thing];
}
return thing;
}
const combineEventHandlers = eventHandlersArray => {
// takes an array of event handler objects and produces one eventHandlers object
// creates a custom combinedHandler() for events with multiple conflicting handlers
return eventHandlersArray.reduce((localHandlers, finalHandlers) => {
(0, _forOwn.default)(localHandlers, (localHandler, eventName) => {
const existingHandler = finalHandlers[eventName];
if (existingHandler) {
// create new handler for event that concats the existing handler's mutations with new ones
finalHandlers[eventName] = function combinedHandler() {
// named for debug clarity
// sometimes handlers return undefined; use empty array instead, for concat()
const existingMutations = ensureArray(existingHandler(...arguments));
const localMutations = ensureArray(localHandler(...arguments));
return existingMutations.concat(localMutations);
};
} else {
finalHandlers[eventName] = localHandler;
}
});
return finalHandlers;
});
};
const combineDefaultEvents = defaultEvents => {
// takes a defaultEvents array and returns one equal or lesser length,
// by combining any events that have the same target
const eventsByTarget = (0, _groupBy.default)(defaultEvents, "target");
const events = (0, _toPairs.default)(eventsByTarget).map(_ref => {
let [target, eventsArray] = _ref;
const newEventsArray = eventsArray.filter(Boolean);
return (0, _isEmpty.default)(newEventsArray) ? null : {
target,
eventHandlers: combineEventHandlers(eventsArray.map(event => event.eventHandlers))
// note: does not currently handle eventKey or childName
};
});
return events.filter(Boolean);
};
/**
* Container hooks are used to provide the container logic to the container components through props and a modified children object
* - These hooks contain shared logic for both web and Victory Native containers.
* - In this utility, we call multiple of these hooks with the props returned by the previous to combine the container logic.
*/
const CONTAINER_HOOKS = {
zoom: _victoryZoomContainer.useVictoryZoomContainer,
selection: _victorySelectionContainer.useVictorySelectionContainer,
brush: _victoryBrushContainer.useVictoryBrushContainer,
cursor: _victoryCursorContainer.useVictoryCursorContainer,
voronoi: _victoryVoronoiContainer.useVictoryVoronoiContainer
};
/**
* Container hooks are wrappers that return a VictoryContainer with the props provided by their respective hooks, and the modified children.
* - These containers are specific to the web. Victory Native has its own container components.
* - For this utility, we only need the container components to extract the defaultEvents.
*/
const CONTAINER_COMPONENTS_WEB = {
zoom: _victoryZoomContainer.VictoryZoomContainer,
selection: _victorySelectionContainer.VictorySelectionContainer,
brush: _victoryBrushContainer.VictoryBrushContainer,
cursor: _victoryCursorContainer.VictoryCursorContainer,
voronoi: _victoryVoronoiContainer.VictoryVoronoiContainer
};
function makeCreateContainerFunction(containerComponents, VictoryContainerBase) {
// Helper type to support backwards compatibility with old types
return function combineContainers(containerA, containerB) {
const ContainerA = containerComponents[containerA];
const ContainerB = containerComponents[containerB];
const useContainerA = CONTAINER_HOOKS[containerA];
const useContainerB = CONTAINER_HOOKS[containerB];
const CombinedContainer = props => {
const {
children: childrenA,
props: propsA
} = useContainerA(props);
const {
children: combinedChildren,
props: combinedProps
} = useContainerB({
...propsA,
children: childrenA
});
return /*#__PURE__*/_react.default.createElement(VictoryContainerBase, combinedProps, combinedChildren);
};
CombinedContainer.displayName = `Victory${containerA}${containerB}Container`;
CombinedContainer.role = "container";
CombinedContainer.defaultEvents = props => combineDefaultEvents([...ContainerA.defaultEvents(props), ...ContainerB.defaultEvents(props)]);
return CombinedContainer;
};
}
const createContainer = exports.createContainer = makeCreateContainerFunction(CONTAINER_COMPONENTS_WEB, _victoryCore.VictoryContainer);