victory-create-container 36.9.2-next.1 → 36.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,31 +3,30 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.createContainer = void 0;
7
- exports.makeCreateContainerFunction = makeCreateContainerFunction;
8
-
9
- var _toPairs2 = _interopRequireDefault(require("lodash/toPairs"));
6
+ exports.makeCreateContainerFunction = exports.createContainer = exports.combineContainerMixins = void 0;
10
7
 
11
8
  var _isEmpty2 = _interopRequireDefault(require("lodash/isEmpty"));
12
9
 
13
- var _groupBy2 = _interopRequireDefault(require("lodash/groupBy"));
10
+ var _flow2 = _interopRequireDefault(require("lodash/flow"));
14
11
 
15
12
  var _forOwn2 = _interopRequireDefault(require("lodash/forOwn"));
16
13
 
17
- var _victoryZoomContainer = require("victory-zoom-container");
18
-
19
- var _victorySelectionContainer = require("victory-selection-container");
14
+ var _groupBy2 = _interopRequireDefault(require("lodash/groupBy"));
20
15
 
21
- var _react = _interopRequireDefault(require("react"));
16
+ var _toPairs2 = _interopRequireDefault(require("lodash/toPairs"));
22
17
 
23
18
  var _victoryCore = require("victory-core");
24
19
 
25
20
  var _victoryVoronoiContainer = require("victory-voronoi-container");
26
21
 
27
- var _victoryCursorContainer = require("victory-cursor-container");
22
+ var _victoryZoomContainer = require("victory-zoom-container");
23
+
24
+ var _victorySelectionContainer = require("victory-selection-container");
28
25
 
29
26
  var _victoryBrushContainer = require("victory-brush-container");
30
27
 
28
+ var _victoryCursorContainer = require("victory-cursor-container");
29
+
31
30
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
32
31
 
33
32
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
@@ -44,6 +43,26 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
44
43
 
45
44
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
46
45
 
46
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
47
+
48
+ 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); } }
49
+
50
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
51
+
52
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
53
+
54
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
55
+
56
+ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
57
+
58
+ function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
59
+
60
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
61
+
62
+ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
63
+
64
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
65
+
47
66
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
48
67
 
49
68
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -111,63 +130,94 @@ var combineDefaultEvents = function (defaultEvents) {
111
130
  return events.filter(Boolean);
112
131
  };
113
132
 
114
- /**
115
- * Container hooks are used to provide the container logic to the container components through props and a modified children object
116
- * - These hooks contain shared logic for both web and Victory Native containers.
117
- * - In this utility, we call multiple of these hooks with the props returned by the previous to combine the container logic.
118
- */
119
- var CONTAINER_HOOKS = {
120
- zoom: _victoryZoomContainer.useVictoryZoomContainer,
121
- selection: _victorySelectionContainer.useVictorySelectionContainer,
122
- brush: _victoryBrushContainer.useVictoryBrushContainer,
123
- cursor: _victoryCursorContainer.useVictoryCursorContainer,
124
- voronoi: _victoryVoronoiContainer.useVictoryVoronoiContainer
133
+ var combineContainerMixins = function (mixins, Container) {
134
+ var _class;
135
+
136
+ // similar to Object.assign(A, B), this function will decide conflicts in favor mixinB.
137
+ // this applies to propTypes and defaultProps.
138
+ // getChildren will call A's getChildren() and pass the resulting children to B's.
139
+ // defaultEvents attempts to resolve any conflicts between A and B's defaultEvents.
140
+ var Classes = mixins.map(function (mixin) {
141
+ return mixin(Container);
142
+ });
143
+ var instances = Classes.map(function (Class) {
144
+ return new Class();
145
+ });
146
+ var NaiveCombinedContainer = (0, _flow2.default)(mixins)(Container);
147
+ var displayType = Classes.map(function (Class) {
148
+ var match = Class.displayName.match(/Victory(.*)Container/);
149
+ return match[1] || "";
150
+ }).join("");
151
+ return _class = /*#__PURE__*/function (_NaiveCombinedContain) {
152
+ _inherits(VictoryCombinedContainer, _NaiveCombinedContain);
153
+
154
+ var _super = _createSuper(VictoryCombinedContainer);
155
+
156
+ function VictoryCombinedContainer() {
157
+ _classCallCheck(this, VictoryCombinedContainer);
158
+
159
+ return _super.apply(this, arguments);
160
+ }
161
+
162
+ _createClass(VictoryCombinedContainer, [{
163
+ key: "getChildren",
164
+ value: function getChildren(props) {
165
+ return instances.reduce(function (children, instance) {
166
+ return instance.getChildren(_objectSpread(_objectSpread({}, props), {}, {
167
+ children: children
168
+ }));
169
+ }, props.children);
170
+ }
171
+ }]);
172
+
173
+ return VictoryCombinedContainer;
174
+ }(NaiveCombinedContainer), _class.displayName = "Victory".concat(displayType, "Container"), _class.propTypes = Classes.reduce(function (propTypes, Class) {
175
+ return _objectSpread(_objectSpread({}, propTypes), Class.propTypes);
176
+ }, {}), _class.defaultProps = Classes.reduce(function (defaultProps, Class) {
177
+ return _objectSpread(_objectSpread({}, defaultProps), Class.defaultProps);
178
+ }, {}), _class.defaultEvents = function (props) {
179
+ return combineDefaultEvents(Classes.reduce(function (defaultEvents, Class) {
180
+ var events = _victoryCore.Helpers.isFunction(Class.defaultEvents) ? Class.defaultEvents(props) : Class.defaultEvents;
181
+ return [].concat(_toConsumableArray(defaultEvents), _toConsumableArray(events));
182
+ }, []));
183
+ }, _class;
125
184
  };
126
- /**
127
- * Container hooks are wrappers that return a VictoryContainer with the props provided by their respective hooks, and the modified children.
128
- * - These containers are specific to the web. Victory Native has its own container components.
129
- * - For this utility, we only need the container components to extract the defaultEvents.
130
- */
131
-
132
- var CONTAINER_COMPONENTS = {
133
- zoom: _victoryZoomContainer.VictoryZoomContainer,
134
- selection: _victorySelectionContainer.VictorySelectionContainer,
135
- brush: _victoryBrushContainer.VictoryBrushContainer,
136
- cursor: _victoryCursorContainer.VictoryCursorContainer,
137
- voronoi: _victoryVoronoiContainer.VictoryVoronoiContainer
185
+
186
+ exports.combineContainerMixins = combineContainerMixins;
187
+
188
+ var checkBehaviorName = function (behavior, behaviors) {
189
+ if (behavior && !behaviors.includes(behavior)) {
190
+ _victoryCore.Log.warn("\"".concat(behavior, "\" is not a valid behavior. Choose from [").concat(behaviors.join(", "), "]."));
191
+ }
138
192
  };
139
193
 
140
- function makeCreateContainerFunction(containerComponents, VictoryContainerBase) {
141
- return function combineContainers(containerA, containerB) {
142
- var ContainerA = containerComponents[containerA];
143
- var ContainerB = containerComponents[containerB];
144
- var useContainerA = CONTAINER_HOOKS[containerA];
145
- var useContainerB = CONTAINER_HOOKS[containerB];
146
-
147
- var CombinedContainer = function (props) {
148
- var _useContainerA = useContainerA(props),
149
- childrenA = _useContainerA.children,
150
- propsA = _useContainerA.props;
151
-
152
- var _useContainerB = useContainerB(_objectSpread(_objectSpread({}, propsA), {}, {
153
- children: childrenA
154
- })),
155
- combinedChildren = _useContainerB.children,
156
- combinedProps = _useContainerB.props;
157
-
158
- return /*#__PURE__*/_react.default.createElement(VictoryContainerBase, combinedProps, combinedChildren);
159
- };
194
+ var makeCreateContainerFunction = function (mixinMap, Container) {
195
+ return function (behaviorA, behaviorB) {
196
+ var behaviors = Object.keys(mixinMap);
197
+ checkBehaviorName(behaviorA, behaviors);
198
+ checkBehaviorName(behaviorB, behaviors);
160
199
 
161
- CombinedContainer.displayName = "Victory".concat(containerA).concat(containerB, "Container");
162
- CombinedContainer.role = "container";
200
+ if (arguments.length <= 2 ? 0 : arguments.length - 2) {
201
+ _victoryCore.Log.warn("too many arguments given to createContainer (maximum accepted: 2).");
202
+ }
163
203
 
164
- CombinedContainer.defaultEvents = function (props) {
165
- return combineDefaultEvents([].concat(_toConsumableArray(ContainerA.defaultEvents(props)), _toConsumableArray(ContainerB.defaultEvents(props))));
166
- };
204
+ var firstMixins = mixinMap[behaviorA];
205
+ var secondMixins = mixinMap[behaviorB] || [];
167
206
 
168
- return CombinedContainer;
207
+ if (!firstMixins) {
208
+ return Container;
209
+ }
210
+
211
+ return combineContainerMixins([].concat(_toConsumableArray(firstMixins), _toConsumableArray(secondMixins)), Container);
169
212
  };
170
- }
213
+ };
171
214
 
172
- var createContainer = makeCreateContainerFunction(CONTAINER_COMPONENTS, _victoryCore.VictoryContainer);
215
+ exports.makeCreateContainerFunction = makeCreateContainerFunction;
216
+ var createContainer = makeCreateContainerFunction({
217
+ zoom: [_victoryZoomContainer.zoomContainerMixin],
218
+ voronoi: [_victoryVoronoiContainer.voronoiContainerMixin],
219
+ selection: [_victorySelectionContainer.selectionContainerMixin],
220
+ cursor: [_victoryCursorContainer.cursorContainerMixin],
221
+ brush: [_victoryBrushContainer.brushContainerMixin]
222
+ }, _victoryCore.VictoryContainer);
173
223
  exports.createContainer = createContainer;
package/lib/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export * from "./create-container";
1
+ export * from "./create-container";
2
2
  //# sourceMappingURL=index.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "victory-create-container",
3
- "version": "36.9.2-next.1",
3
+ "version": "36.9.2",
4
4
  "description": "Container Helper for Victory",
5
5
  "keywords": [
6
6
  "data visualization",
@@ -12,7 +12,7 @@
12
12
  "type": "git",
13
13
  "url": "https://github.com/FormidableLabs/victory"
14
14
  },
15
- "homepage": "https://formidable.com/open-source/victory",
15
+ "homepage": "https://commerce.nearform.com/open-source/victory",
16
16
  "sideEffects": false,
17
17
  "main": "lib/index.js",
18
18
  "module": "es/index.js",
@@ -21,16 +21,19 @@
21
21
  "license": "MIT",
22
22
  "dependencies": {
23
23
  "lodash": "^4.17.19",
24
- "victory-brush-container": "^36.9.2-next.1",
25
- "victory-core": "^36.9.2-next.1",
26
- "victory-cursor-container": "^36.9.2-next.1",
27
- "victory-selection-container": "^36.9.2-next.1",
28
- "victory-voronoi-container": "^36.9.2-next.1",
29
- "victory-zoom-container": "^36.9.2-next.1"
24
+ "victory-brush-container": "^36.9.2",
25
+ "victory-core": "^36.9.2",
26
+ "victory-cursor-container": "^36.9.2",
27
+ "victory-selection-container": "^36.9.2",
28
+ "victory-voronoi-container": "^36.9.2",
29
+ "victory-zoom-container": "^36.9.2"
30
30
  },
31
31
  "peerDependencies": {
32
32
  "react": ">=16.6.0"
33
33
  },
34
+ "publishConfig": {
35
+ "provenance": true
36
+ },
34
37
  "wireit": {
35
38
  "### THESE WIREIT CONFIGS ARE GENERATED ####": {},
36
39
  "### DO NOT MODIFY THESE MANUALLY ####": {},
@@ -0,0 +1,173 @@
1
+ import React from "react";
2
+ import { toPairs, groupBy, forOwn, flow, isEmpty } from "lodash";
3
+ import { Helpers, VictoryContainer, Log } from "victory-core";
4
+ import { voronoiContainerMixin } from "victory-voronoi-container";
5
+ import { zoomContainerMixin } from "victory-zoom-container";
6
+ import { selectionContainerMixin } from "victory-selection-container";
7
+ import { brushContainerMixin } from "victory-brush-container";
8
+ import { cursorContainerMixin } from "victory-cursor-container";
9
+
10
+ export type ContainerType =
11
+ | "brush"
12
+ | "cursor"
13
+ | "selection"
14
+ | "voronoi"
15
+ | "zoom";
16
+
17
+ type MixinFunction = (...args: any[]) => any;
18
+
19
+ function ensureArray<T>(thing: T): [] | T | T[] {
20
+ if (!thing) {
21
+ return [];
22
+ } else if (!Array.isArray(thing)) {
23
+ return [thing];
24
+ }
25
+ return thing;
26
+ }
27
+
28
+ const combineEventHandlers = (eventHandlersArray: any[]) => {
29
+ // takes an array of event handler objects and produces one eventHandlers object
30
+ // creates a custom combinedHandler() for events with multiple conflicting handlers
31
+ return eventHandlersArray.reduce((localHandlers, finalHandlers) => {
32
+ forOwn(localHandlers, (localHandler, eventName) => {
33
+ const existingHandler = finalHandlers[eventName];
34
+ if (existingHandler) {
35
+ // create new handler for event that concats the existing handler's mutations with new ones
36
+ finalHandlers[eventName] = function combinedHandler(...params) {
37
+ // named for debug clarity
38
+ // sometimes handlers return undefined; use empty array instead, for concat()
39
+ const existingMutations = ensureArray(existingHandler(...params));
40
+ const localMutations = ensureArray(localHandler(...params));
41
+ return existingMutations.concat(localMutations);
42
+ };
43
+ } else {
44
+ finalHandlers[eventName] = localHandler;
45
+ }
46
+ });
47
+ return finalHandlers;
48
+ });
49
+ };
50
+
51
+ const combineDefaultEvents = (defaultEvents: any[]) => {
52
+ // takes a defaultEvents array and returns one equal or lesser length,
53
+ // by combining any events that have the same target
54
+ const eventsByTarget = groupBy(defaultEvents, "target");
55
+ const events = toPairs(eventsByTarget).map(([target, eventsArray]) => {
56
+ const newEventsArray = eventsArray.filter(Boolean);
57
+ return isEmpty(newEventsArray)
58
+ ? null
59
+ : {
60
+ target,
61
+ eventHandlers: combineEventHandlers(
62
+ eventsArray.map((event) => event.eventHandlers),
63
+ ),
64
+ // note: does not currently handle eventKey or childName
65
+ };
66
+ });
67
+ return events.filter(Boolean);
68
+ };
69
+
70
+ export const combineContainerMixins = (
71
+ mixins: MixinFunction[],
72
+ Container: React.ComponentType<any>,
73
+ ) => {
74
+ // similar to Object.assign(A, B), this function will decide conflicts in favor mixinB.
75
+ // this applies to propTypes and defaultProps.
76
+ // getChildren will call A's getChildren() and pass the resulting children to B's.
77
+ // defaultEvents attempts to resolve any conflicts between A and B's defaultEvents.
78
+ const Classes = mixins.map((mixin) => mixin(Container));
79
+ const instances = Classes.map((Class) => new Class());
80
+ const NaiveCombinedContainer = flow(mixins)(Container);
81
+
82
+ const displayType = Classes.map((Class) => {
83
+ const match = Class.displayName.match(/Victory(.*)Container/);
84
+ return match[1] || "";
85
+ }).join("");
86
+
87
+ return class VictoryCombinedContainer extends NaiveCombinedContainer {
88
+ static displayName = `Victory${displayType}Container`;
89
+
90
+ static propTypes = Classes.reduce(
91
+ (propTypes, Class) => ({ ...propTypes, ...Class.propTypes }),
92
+ {},
93
+ );
94
+
95
+ static defaultProps = Classes.reduce(
96
+ (defaultProps, Class) => ({ ...defaultProps, ...Class.defaultProps }),
97
+ {},
98
+ );
99
+
100
+ static defaultEvents = (props) => {
101
+ return combineDefaultEvents(
102
+ Classes.reduce((defaultEvents, Class) => {
103
+ const events = Helpers.isFunction(Class.defaultEvents)
104
+ ? Class.defaultEvents(props)
105
+ : Class.defaultEvents;
106
+ return [...defaultEvents, ...events];
107
+ }, []),
108
+ );
109
+ };
110
+
111
+ getChildren(props) {
112
+ return instances.reduce(
113
+ (children, instance) => instance.getChildren({ ...props, children }),
114
+ props.children,
115
+ );
116
+ }
117
+ };
118
+ };
119
+
120
+ const checkBehaviorName = (
121
+ behavior: ContainerType,
122
+ behaviors: ContainerType[],
123
+ ) => {
124
+ if (behavior && !behaviors.includes(behavior)) {
125
+ Log.warn(
126
+ `"${behavior}" is not a valid behavior. Choose from [${behaviors.join(
127
+ ", ",
128
+ )}].`,
129
+ );
130
+ }
131
+ };
132
+
133
+ export const makeCreateContainerFunction =
134
+ (
135
+ mixinMap: Record<ContainerType, MixinFunction[]>,
136
+ Container: React.ComponentType<any>,
137
+ ) =>
138
+ (
139
+ behaviorA: ContainerType,
140
+ behaviorB: ContainerType,
141
+ ...invalid: ContainerType[]
142
+ ) => {
143
+ const behaviors = Object.keys(mixinMap) as ContainerType[];
144
+
145
+ checkBehaviorName(behaviorA, behaviors);
146
+ checkBehaviorName(behaviorB, behaviors);
147
+
148
+ if (invalid.length) {
149
+ Log.warn(
150
+ "too many arguments given to createContainer (maximum accepted: 2).",
151
+ );
152
+ }
153
+
154
+ const firstMixins = mixinMap[behaviorA];
155
+ const secondMixins = mixinMap[behaviorB] || [];
156
+
157
+ if (!firstMixins) {
158
+ return Container;
159
+ }
160
+
161
+ return combineContainerMixins([...firstMixins, ...secondMixins], Container);
162
+ };
163
+
164
+ export const createContainer = makeCreateContainerFunction(
165
+ {
166
+ zoom: [zoomContainerMixin],
167
+ voronoi: [voronoiContainerMixin],
168
+ selection: [selectionContainerMixin],
169
+ cursor: [cursorContainerMixin],
170
+ brush: [brushContainerMixin],
171
+ },
172
+ VictoryContainer,
173
+ );
@@ -1,19 +0,0 @@
1
- /**
2
- * @license React
3
- * react-dom.production.min.js
4
- *
5
- * Copyright (c) Facebook, Inc. and its affiliates.
6
- *
7
- * This source code is licensed under the MIT license found in the
8
- * LICENSE file in the root directory of this source tree.
9
- */
10
-
11
- /**
12
- * @license React
13
- * scheduler.production.min.js
14
- *
15
- * Copyright (c) Facebook, Inc. and its affiliates.
16
- *
17
- * This source code is licensed under the MIT license found in the
18
- * LICENSE file in the root directory of this source tree.
19
- */
@@ -1,169 +0,0 @@
1
- import {
2
- VictoryZoomContainer,
3
- useVictoryZoomContainer,
4
- } from "victory-zoom-container";
5
- import {
6
- VictorySelectionContainer,
7
- useVictorySelectionContainer,
8
- } from "victory-selection-container";
9
- import React from "react";
10
- import { VictoryContainer } from "victory-core";
11
- import { forOwn, groupBy, isEmpty, toPairs } from "lodash";
12
- import {
13
- VictoryVoronoiContainer,
14
- useVictoryVoronoiContainer,
15
- } from "victory-voronoi-container";
16
- import {
17
- VictoryCursorContainer,
18
- useVictoryCursorContainer,
19
- } from "victory-cursor-container";
20
- import {
21
- VictoryBrushContainer,
22
- useVictoryBrushContainer,
23
- } from "victory-brush-container";
24
-
25
- function ensureArray<T>(thing: T): [] | T | T[] {
26
- if (!thing) {
27
- return [];
28
- } else if (!Array.isArray(thing)) {
29
- return [thing];
30
- }
31
- return thing;
32
- }
33
-
34
- const combineEventHandlers = (eventHandlersArray: any[]) => {
35
- // takes an array of event handler objects and produces one eventHandlers object
36
- // creates a custom combinedHandler() for events with multiple conflicting handlers
37
- return eventHandlersArray.reduce((localHandlers, finalHandlers) => {
38
- forOwn(localHandlers, (localHandler, eventName) => {
39
- const existingHandler = finalHandlers[eventName];
40
- if (existingHandler) {
41
- // create new handler for event that concats the existing handler's mutations with new ones
42
- finalHandlers[eventName] = function combinedHandler(...params) {
43
- // named for debug clarity
44
- // sometimes handlers return undefined; use empty array instead, for concat()
45
- const existingMutations = ensureArray(existingHandler(...params));
46
- const localMutations = ensureArray(localHandler(...params));
47
- return existingMutations.concat(localMutations);
48
- };
49
- } else {
50
- finalHandlers[eventName] = localHandler;
51
- }
52
- });
53
- return finalHandlers;
54
- });
55
- };
56
-
57
- const combineDefaultEvents = (defaultEvents: any[]) => {
58
- // takes a defaultEvents array and returns one equal or lesser length,
59
- // by combining any events that have the same target
60
- const eventsByTarget = groupBy(defaultEvents, "target");
61
- const events = toPairs(eventsByTarget).map(([target, eventsArray]) => {
62
- const newEventsArray = eventsArray.filter(Boolean);
63
- return isEmpty(newEventsArray)
64
- ? null
65
- : {
66
- target,
67
- eventHandlers: combineEventHandlers(
68
- eventsArray.map((event) => event.eventHandlers),
69
- ),
70
- // note: does not currently handle eventKey or childName
71
- };
72
- });
73
- return events.filter(Boolean);
74
- };
75
-
76
- export type ContainerType =
77
- | "zoom"
78
- | "selection"
79
- | "brush"
80
- | "cursor"
81
- | "voronoi";
82
-
83
- /**
84
- * Container hooks are used to provide the container logic to the container components through props and a modified children object
85
- * - These hooks contain shared logic for both web and Victory Native containers.
86
- * - In this utility, we call multiple of these hooks with the props returned by the previous to combine the container logic.
87
- */
88
- const CONTAINER_HOOKS = {
89
- zoom: useVictoryZoomContainer,
90
- selection: useVictorySelectionContainer,
91
- brush: useVictoryBrushContainer,
92
- cursor: useVictoryCursorContainer,
93
- voronoi: useVictoryVoronoiContainer,
94
- };
95
-
96
- /**
97
- * Container hooks are wrappers that return a VictoryContainer with the props provided by their respective hooks, and the modified children.
98
- * - These containers are specific to the web. Victory Native has its own container components.
99
- * - For this utility, we only need the container components to extract the defaultEvents.
100
- */
101
- const CONTAINER_COMPONENTS = {
102
- zoom: VictoryZoomContainer,
103
- selection: VictorySelectionContainer,
104
- brush: VictoryBrushContainer,
105
- cursor: VictoryCursorContainer,
106
- voronoi: VictoryVoronoiContainer,
107
- };
108
-
109
- type ContainerComponents = Record<
110
- ContainerType,
111
- React.ComponentType<any> & {
112
- defaultEvents: (props: any) => any[];
113
- }
114
- >;
115
-
116
- export function makeCreateContainerFunction<
117
- TContainerComponents extends ContainerComponents,
118
- >(
119
- containerComponents: TContainerComponents,
120
- VictoryContainerBase: typeof VictoryContainer,
121
- ) {
122
- type ContainerProps<T extends ContainerType> = React.ComponentProps<
123
- TContainerComponents[T]
124
- >;
125
-
126
- return function combineContainers<
127
- TContainerA extends ContainerType,
128
- TContainerB extends ContainerType,
129
- >(containerA: TContainerA, containerB: TContainerB) {
130
- const ContainerA = containerComponents[containerA];
131
- const ContainerB = containerComponents[containerB];
132
- const useContainerA = CONTAINER_HOOKS[containerA];
133
- const useContainerB = CONTAINER_HOOKS[containerB];
134
-
135
- const CombinedContainer = (
136
- props: ContainerProps<TContainerA> & ContainerProps<TContainerB>,
137
- ) => {
138
- const { children: childrenA, props: propsA } = useContainerA(props);
139
- const { children: combinedChildren, props: combinedProps } =
140
- useContainerB({
141
- ...propsA,
142
- children: childrenA,
143
- });
144
-
145
- return (
146
- <VictoryContainerBase {...combinedProps}>
147
- {combinedChildren}
148
- </VictoryContainerBase>
149
- );
150
- };
151
-
152
- CombinedContainer.displayName = `Victory${containerA}${containerB}Container`;
153
- CombinedContainer.role = "container";
154
- CombinedContainer.defaultEvents = (
155
- props: ContainerProps<TContainerA> & ContainerProps<TContainerB>,
156
- ) =>
157
- combineDefaultEvents([
158
- ...ContainerA.defaultEvents(props),
159
- ...ContainerB.defaultEvents(props),
160
- ]);
161
-
162
- return CombinedContainer;
163
- };
164
- }
165
-
166
- export const createContainer = makeCreateContainerFunction(
167
- CONTAINER_COMPONENTS,
168
- VictoryContainer,
169
- );