react-resizable 3.0.4 → 3.1.0

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.
@@ -2,275 +2,253 @@
2
2
 
3
3
  exports.__esModule = true;
4
4
  exports.default = void 0;
5
-
6
5
  var React = _interopRequireWildcard(require("react"));
7
-
8
6
  var _reactDraggable = require("react-draggable");
9
-
10
7
  var _utils = require("./utils");
11
-
12
8
  var _propTypes = require("./propTypes");
13
-
14
- var _excluded = ["children", "className", "draggableOpts", "width", "height", "handle", "handleSize", "lockAspectRatio", "axis", "minConstraints", "maxConstraints", "onResize", "onResizeStop", "onResizeStart", "resizeHandles", "transformScale"];
15
-
16
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
17
-
18
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
19
-
20
- function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
21
-
22
- function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
23
-
24
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
25
-
26
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
27
-
28
- 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; }
29
-
30
- function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
31
-
32
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
33
-
9
+ const _excluded = ["children", "className", "draggableOpts", "width", "height", "handle", "handleSize", "lockAspectRatio", "axis", "minConstraints", "maxConstraints", "onResize", "onResizeStop", "onResizeStart", "resizeHandles", "transformScale"];
10
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
11
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
12
+ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
13
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
14
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
15
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
16
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
17
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
18
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
34
19
  // The base <Resizable> component.
35
20
  // This component does not have state and relies on the parent to set its props based on callback data.
36
- var Resizable = /*#__PURE__*/function (_React$Component) {
37
- _inheritsLoose(Resizable, _React$Component);
38
-
39
- function Resizable() {
40
- var _this;
41
-
42
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
43
- args[_key] = arguments[_key];
44
- }
45
-
46
- _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;
47
- _this.handleRefs = {};
48
- _this.lastHandleRect = null;
49
- _this.slack = null;
50
- return _this;
21
+ class Resizable extends React.Component {
22
+ constructor() {
23
+ super(...arguments);
24
+ this.handleRefs = {};
25
+ this.lastHandleRect = null;
26
+ this.slack = null;
27
+ this.lastSize = null;
51
28
  }
52
-
53
- var _proto = Resizable.prototype;
54
-
55
- _proto.componentWillUnmount = function componentWillUnmount() {
29
+ componentWillUnmount() {
56
30
  this.resetData();
57
- };
58
-
59
- _proto.resetData = function resetData() {
60
- this.lastHandleRect = this.slack = null;
61
- } // Clamp width and height within provided constraints
62
- ;
63
-
64
- _proto.runConstraints = function runConstraints(width, height) {
65
- var _this$props = this.props,
66
- minConstraints = _this$props.minConstraints,
67
- maxConstraints = _this$props.maxConstraints,
68
- lockAspectRatio = _this$props.lockAspectRatio; // short circuit
69
-
70
- if (!minConstraints && !maxConstraints && !lockAspectRatio) return [width, height]; // If constraining to min and max, we need to also fit width and height to aspect ratio.
31
+ }
32
+ resetData() {
33
+ this.lastHandleRect = this.slack = this.lastSize = null;
34
+ }
71
35
 
36
+ // Clamp width and height within provided constraints
37
+ runConstraints(width, height) {
38
+ const {
39
+ minConstraints,
40
+ maxConstraints,
41
+ lockAspectRatio
42
+ } = this.props;
43
+ // short circuit
44
+ if (!minConstraints && !maxConstraints && !lockAspectRatio) return [width, height];
45
+
46
+ // If constraining to min and max, we need to also fit width and height to aspect ratio.
72
47
  if (lockAspectRatio) {
73
- var ratio = this.props.width / this.props.height;
74
- var deltaW = width - this.props.width;
75
- var deltaH = height - this.props.height; // Find which coordinate was greater and should push the other toward it.
48
+ const ratio = this.props.width / this.props.height;
49
+ const deltaW = width - this.props.width;
50
+ const deltaH = height - this.props.height;
51
+
52
+ // Find which coordinate was greater and should push the other toward it.
76
53
  // E.g.:
77
54
  // ratio = 1, deltaW = 10, deltaH = 5, deltaH should become 10.
78
55
  // ratio = 2, deltaW = 10, deltaH = 6, deltaW should become 12.
79
-
80
56
  if (Math.abs(deltaW) > Math.abs(deltaH * ratio)) {
81
57
  height = width / ratio;
82
58
  } else {
83
59
  width = height * ratio;
84
60
  }
85
61
  }
62
+ const [oldW, oldH] = [width, height];
86
63
 
87
- var oldW = width,
88
- oldH = height; // Add slack to the values used to calculate bound position. This will ensure that if
64
+ // Add slack to the values used to calculate bound position. This will ensure that if
89
65
  // we start removing slack, the element won't react to it right away until it's been
90
66
  // completely removed.
91
-
92
- var _ref = this.slack || [0, 0],
93
- slackW = _ref[0],
94
- slackH = _ref[1];
95
-
67
+ let [slackW, slackH] = this.slack || [0, 0];
96
68
  width += slackW;
97
69
  height += slackH;
98
-
99
70
  if (minConstraints) {
100
71
  width = Math.max(minConstraints[0], width);
101
72
  height = Math.max(minConstraints[1], height);
102
73
  }
103
-
104
74
  if (maxConstraints) {
105
75
  width = Math.min(maxConstraints[0], width);
106
76
  height = Math.min(maxConstraints[1], height);
107
- } // If the width or height changed, we must have introduced some slack. Record it for the next iteration.
108
-
77
+ }
109
78
 
79
+ // If the width or height changed, we must have introduced some slack. Record it for the next iteration.
110
80
  this.slack = [slackW + (oldW - width), slackH + (oldH - height)];
111
81
  return [width, height];
112
82
  }
83
+
113
84
  /**
114
85
  * Wrapper around drag events to provide more useful data.
115
86
  *
116
87
  * @param {String} handlerName Handler name to wrap.
117
88
  * @return {Function} Handler function.
118
89
  */
119
- ;
120
-
121
- _proto.resizeHandler = function resizeHandler(handlerName, axis) {
122
- var _this2 = this;
123
-
124
- return function (e, _ref2) {
125
- var node = _ref2.node,
126
- deltaX = _ref2.deltaX,
127
- deltaY = _ref2.deltaY;
90
+ resizeHandler(handlerName, axis) {
91
+ return (e, _ref) => {
92
+ let {
93
+ node,
94
+ deltaX,
95
+ deltaY
96
+ } = _ref;
128
97
  // Reset data in case it was left over somehow (should not be possible)
129
- if (handlerName === 'onResizeStart') _this2.resetData(); // Axis restrictions
98
+ if (handlerName === 'onResizeStart') this.resetData();
130
99
 
131
- var canDragX = (_this2.props.axis === 'both' || _this2.props.axis === 'x') && axis !== 'n' && axis !== 's';
132
- var canDragY = (_this2.props.axis === 'both' || _this2.props.axis === 'y') && axis !== 'e' && axis !== 'w'; // No dragging possible.
100
+ // Axis restrictions
101
+ const canDragX = (this.props.axis === 'both' || this.props.axis === 'x') && axis !== 'n' && axis !== 's';
102
+ const canDragY = (this.props.axis === 'both' || this.props.axis === 'y') && axis !== 'e' && axis !== 'w';
103
+ // No dragging possible.
104
+ if (!canDragX && !canDragY) return;
133
105
 
134
- if (!canDragX && !canDragY) return; // Decompose axis for later use
106
+ // Decompose axis for later use
107
+ const axisV = axis[0];
108
+ const axisH = axis[axis.length - 1]; // intentionally not axis[1], so that this catches axis === 'w' for example
135
109
 
136
- var axisV = axis[0];
137
- var axisH = axis[axis.length - 1]; // intentionally not axis[1], so that this catches axis === 'w' for example
138
110
  // Track the element being dragged to account for changes in position.
139
111
  // If a handle's position is changed between callbacks, we need to factor this in to the next callback.
140
112
  // Failure to do so will cause the element to "skip" when resized upwards or leftwards.
141
-
142
- var handleRect = node.getBoundingClientRect();
143
-
144
- if (_this2.lastHandleRect != null) {
113
+ const handleRect = node.getBoundingClientRect();
114
+ if (this.lastHandleRect != null) {
145
115
  // If the handle has repositioned on either axis since last render,
146
116
  // we need to increase our callback values by this much.
147
117
  // Only checking 'n', 'w' since resizing by 's', 'w' won't affect the overall position on page,
148
118
  if (axisH === 'w') {
149
- var deltaLeftSinceLast = handleRect.left - _this2.lastHandleRect.left;
119
+ const deltaLeftSinceLast = handleRect.left - this.lastHandleRect.left;
150
120
  deltaX += deltaLeftSinceLast;
151
121
  }
152
-
153
122
  if (axisV === 'n') {
154
- var deltaTopSinceLast = handleRect.top - _this2.lastHandleRect.top;
123
+ const deltaTopSinceLast = handleRect.top - this.lastHandleRect.top;
155
124
  deltaY += deltaTopSinceLast;
156
125
  }
157
- } // Storage of last rect so we know how much it has really moved.
158
-
159
-
160
- _this2.lastHandleRect = handleRect; // Reverse delta if using top or left drag handles.
126
+ }
127
+ // Storage of last rect so we know how much it has really moved.
128
+ this.lastHandleRect = handleRect;
161
129
 
130
+ // Reverse delta if using top or left drag handles.
162
131
  if (axisH === 'w') deltaX = -deltaX;
163
- if (axisV === 'n') deltaY = -deltaY; // Update w/h by the deltas. Also factor in transformScale.
164
-
165
- var width = _this2.props.width + (canDragX ? deltaX / _this2.props.transformScale : 0);
166
- var height = _this2.props.height + (canDragY ? deltaY / _this2.props.transformScale : 0); // Run user-provided constraints.
167
-
168
- var _this2$runConstraints = _this2.runConstraints(width, height);
169
-
170
- width = _this2$runConstraints[0];
171
- height = _this2$runConstraints[1];
172
- var dimensionsChanged = width !== _this2.props.width || height !== _this2.props.height; // Call user-supplied callback if present.
173
-
174
- var cb = typeof _this2.props[handlerName] === 'function' ? _this2.props[handlerName] : null; // Don't call 'onResize' if dimensions haven't changed.
175
-
176
- var shouldSkipCb = handlerName === 'onResize' && !dimensionsChanged;
132
+ if (axisV === 'n') deltaY = -deltaY;
133
+
134
+ // Update w/h by the deltas. Also factor in transformScale.
135
+ let width = this.props.width + (canDragX ? deltaX / this.props.transformScale : 0);
136
+ let height = this.props.height + (canDragY ? deltaY / this.props.transformScale : 0);
137
+
138
+ // Run user-provided constraints.
139
+ [width, height] = this.runConstraints(width, height);
140
+
141
+ // For onResizeStop, use the last size from onResize rather than recalculating.
142
+ // This avoids issues where props.width/height are stale due to React's batched updates.
143
+ if (handlerName === 'onResizeStop' && this.lastSize) {
144
+ ({
145
+ width,
146
+ height
147
+ } = this.lastSize);
148
+ }
149
+ const dimensionsChanged = width !== this.props.width || height !== this.props.height;
150
+
151
+ // Store the size for use in onResizeStop. We do this after the onResizeStop check
152
+ // above so we don't overwrite the stored value with a potentially stale calculation.
153
+ if (handlerName !== 'onResizeStop') {
154
+ this.lastSize = {
155
+ width,
156
+ height
157
+ };
158
+ }
177
159
 
160
+ // Call user-supplied callback if present.
161
+ const cb = typeof this.props[handlerName] === 'function' ? this.props[handlerName] : null;
162
+ // Don't call 'onResize' if dimensions haven't changed.
163
+ const shouldSkipCb = handlerName === 'onResize' && !dimensionsChanged;
178
164
  if (cb && !shouldSkipCb) {
179
- e.persist == null ? void 0 : e.persist();
165
+ e.persist?.();
180
166
  cb(e, {
181
- node: node,
167
+ node,
182
168
  size: {
183
- width: width,
184
- height: height
169
+ width,
170
+ height
185
171
  },
186
172
  handle: axis
187
173
  });
188
- } // Reset internal data
189
-
174
+ }
190
175
 
191
- if (handlerName === 'onResizeStop') _this2.resetData();
176
+ // Reset internal data
177
+ if (handlerName === 'onResizeStop') this.resetData();
192
178
  };
193
- } // Render a resize handle given an axis & DOM ref. Ref *must* be attached for
194
- // the underlying draggable library to work properly.
195
- ;
196
-
197
- _proto.renderResizeHandle = function renderResizeHandle(handleAxis, ref) {
198
- var handle = this.props.handle; // No handle provided, make the default
179
+ }
199
180
 
181
+ // Render a resize handle given an axis & DOM ref. Ref *must* be attached for
182
+ // the underlying draggable library to work properly.
183
+ renderResizeHandle(handleAxis, ref) {
184
+ const {
185
+ handle
186
+ } = this.props;
187
+ // No handle provided, make the default
200
188
  if (!handle) {
201
189
  return /*#__PURE__*/React.createElement("span", {
202
- className: "react-resizable-handle react-resizable-handle-" + handleAxis,
190
+ className: `react-resizable-handle react-resizable-handle-${handleAxis}`,
203
191
  ref: ref
204
192
  });
205
- } // Handle is a function, such as:
193
+ }
194
+ // Handle is a function, such as:
206
195
  // `handle={(handleAxis) => <span className={...} />}`
207
-
208
-
209
196
  if (typeof handle === 'function') {
210
197
  return handle(handleAxis, ref);
211
- } // Handle is a React component (composite or DOM).
212
-
213
-
214
- var isDOMElement = typeof handle.type === 'string';
215
-
216
- var props = _objectSpread({
217
- ref: ref
198
+ }
199
+ // Handle is a React component (composite or DOM).
200
+ const isDOMElement = typeof handle.type === 'string';
201
+ const props = _objectSpread({
202
+ ref
218
203
  }, isDOMElement ? {} : {
219
- handleAxis: handleAxis
204
+ handleAxis
220
205
  });
221
-
222
206
  return /*#__PURE__*/React.cloneElement(handle, props);
223
- };
224
-
225
- _proto.render = function render() {
226
- var _this3 = this;
227
-
207
+ }
208
+ render() {
228
209
  // Pass along only props not meant for the `<Resizable>`.`
229
210
  // eslint-disable-next-line no-unused-vars
230
- var _this$props2 = this.props,
231
- children = _this$props2.children,
232
- className = _this$props2.className,
233
- draggableOpts = _this$props2.draggableOpts,
234
- width = _this$props2.width,
235
- height = _this$props2.height,
236
- handle = _this$props2.handle,
237
- handleSize = _this$props2.handleSize,
238
- lockAspectRatio = _this$props2.lockAspectRatio,
239
- axis = _this$props2.axis,
240
- minConstraints = _this$props2.minConstraints,
241
- maxConstraints = _this$props2.maxConstraints,
242
- onResize = _this$props2.onResize,
243
- onResizeStop = _this$props2.onResizeStop,
244
- onResizeStart = _this$props2.onResizeStart,
245
- resizeHandles = _this$props2.resizeHandles,
246
- transformScale = _this$props2.transformScale,
247
- p = _objectWithoutPropertiesLoose(_this$props2, _excluded); // What we're doing here is getting the child of this element, and cloning it with this element's props.
211
+ const _this$props = this.props,
212
+ {
213
+ children,
214
+ className,
215
+ draggableOpts,
216
+ width,
217
+ height,
218
+ handle,
219
+ handleSize,
220
+ lockAspectRatio,
221
+ axis,
222
+ minConstraints,
223
+ maxConstraints,
224
+ onResize,
225
+ onResizeStop,
226
+ onResizeStart,
227
+ resizeHandles,
228
+ transformScale
229
+ } = _this$props,
230
+ p = _objectWithoutProperties(_this$props, _excluded);
231
+
232
+ // What we're doing here is getting the child of this element, and cloning it with this element's props.
248
233
  // We are then defining its children as:
249
234
  // 1. Its original children (resizable's child's children), and
250
235
  // 2. One or more draggable handles.
251
-
252
-
253
236
  return (0, _utils.cloneElement)(children, _objectSpread(_objectSpread({}, p), {}, {
254
- className: (className ? className + " " : '') + "react-resizable",
255
- children: [].concat(children.props.children, resizeHandles.map(function (handleAxis) {
256
- var _this3$handleRefs$han;
257
-
237
+ className: `${className ? `${className} ` : ''}react-resizable`,
238
+ children: [...children.props.children, ...resizeHandles.map(handleAxis => {
258
239
  // Create a ref to the handle so that `<DraggableCore>` doesn't have to use ReactDOM.findDOMNode().
259
- var ref = (_this3$handleRefs$han = _this3.handleRefs[handleAxis]) != null ? _this3$handleRefs$han : _this3.handleRefs[handleAxis] = /*#__PURE__*/React.createRef();
240
+ const ref = this.handleRefs[handleAxis] ?? (this.handleRefs[handleAxis] = /*#__PURE__*/React.createRef());
260
241
  return /*#__PURE__*/React.createElement(_reactDraggable.DraggableCore, _extends({}, draggableOpts, {
261
242
  nodeRef: ref,
262
- key: "resizableHandle-" + handleAxis,
263
- onStop: _this3.resizeHandler('onResizeStop', handleAxis),
264
- onStart: _this3.resizeHandler('onResizeStart', handleAxis),
265
- onDrag: _this3.resizeHandler('onResize', handleAxis)
266
- }), _this3.renderResizeHandle(handleAxis, ref));
267
- }))
243
+ key: `resizableHandle-${handleAxis}`,
244
+ onStop: this.resizeHandler('onResizeStop', handleAxis),
245
+ onStart: this.resizeHandler('onResizeStart', handleAxis),
246
+ onDrag: this.resizeHandler('onResize', handleAxis)
247
+ }), this.renderResizeHandle(handleAxis, ref));
248
+ })]
268
249
  }));
269
- };
270
-
271
- return Resizable;
272
- }(React.Component);
273
-
250
+ }
251
+ }
274
252
  exports.default = Resizable;
275
253
  Resizable.propTypes = _propTypes.resizableProps;
276
254
  Resizable.defaultProps = {
@@ -24,13 +24,14 @@ export default class Resizable extends React.Component<Props, void> {
24
24
  handleRefs: {[key: ResizeHandleAxis]: ReactRef<HTMLElement>} = {};
25
25
  lastHandleRect: ?ClientRect = null;
26
26
  slack: ?[number, number] = null;
27
+ lastSize: ?{width: number, height: number} = null;
27
28
 
28
29
  componentWillUnmount() {
29
30
  this.resetData();
30
31
  }
31
32
 
32
33
  resetData() {
33
- this.lastHandleRect = this.slack = null;
34
+ this.lastHandleRect = this.slack = this.lastSize = null;
34
35
  }
35
36
 
36
37
  // Clamp width and height within provided constraints
@@ -132,8 +133,20 @@ export default class Resizable extends React.Component<Props, void> {
132
133
  // Run user-provided constraints.
133
134
  [width, height] = this.runConstraints(width, height);
134
135
 
136
+ // For onResizeStop, use the last size from onResize rather than recalculating.
137
+ // This avoids issues where props.width/height are stale due to React's batched updates.
138
+ if (handlerName === 'onResizeStop' && this.lastSize) {
139
+ ({width, height} = this.lastSize);
140
+ }
141
+
135
142
  const dimensionsChanged = width !== this.props.width || height !== this.props.height;
136
143
 
144
+ // Store the size for use in onResizeStop. We do this after the onResizeStop check
145
+ // above so we don't overwrite the stored value with a potentially stale calculation.
146
+ if (handlerName !== 'onResizeStop') {
147
+ this.lastSize = {width, height};
148
+ }
149
+
137
150
  // Call user-supplied callback if present.
138
151
  const cb = typeof this.props[handlerName] === 'function' ? this.props[handlerName] : null;
139
152
  // Don't call 'onResize' if dimensions haven't changed.