react-resizable 3.1.3 → 4.0.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.
package/README.md CHANGED
@@ -11,11 +11,12 @@ A simple widget that can be resized via one or more handles.
11
11
  You can either use the `<Resizable>` element directly, or use the much simpler `<ResizableBox>` element.
12
12
 
13
13
  See the example and associated code in [ExampleLayout](https://github.com/react-grid-layout/react-resizable/blob/master/examples/ExampleLayout.js) and
14
- [ResizableBox](https://github.com/react-grid-layout/react-resizable/blob/master/lib/ResizableBox.js) for more details.
14
+ [ResizableBox](https://github.com/react-grid-layout/react-resizable/blob/master/lib/ResizableBox.tsx) for more details.
15
15
 
16
16
  ## Table of Contents
17
17
 
18
18
  - [Installation](#installation)
19
+ - [TypeScript](#typescript)
19
20
  - [Compatibility](#compatibility)
20
21
  - [Usage](#usage)
21
22
  - [Resizable](#resizable)
@@ -47,20 +48,59 @@ Or import it in your CSS:
47
48
 
48
49
  If you're using a bundler that doesn't support CSS imports, you can find the styles at `node_modules/react-resizable/css/styles.css` and include them manually.
49
50
 
51
+ ## TypeScript
52
+
53
+ As of `4.0.0`, the library is authored in TypeScript and ships bundled type
54
+ declarations in `build/*.d.ts`. You **do not** need to install
55
+ `@types/react-resizable`; if you previously installed it, remove it so the
56
+ bundled types take precedence:
57
+
58
+ ```bash
59
+ npm uninstall @types/react-resizable
60
+ # or
61
+ yarn remove @types/react-resizable
62
+ ```
63
+
64
+ Public types are re-exported from the package root:
65
+
66
+ ```ts
67
+ import {
68
+ Resizable,
69
+ ResizableBox,
70
+ // types
71
+ type ResizeCallbackData,
72
+ type ResizeHandleAxis,
73
+ type Axis,
74
+ type Props as ResizableProps,
75
+ } from 'react-resizable';
76
+ ```
77
+
78
+ ### Flow
79
+
80
+ Flow is no longer supported as of `4.0.0`. Earlier versions shipped
81
+ `*.js.flow` sidecar files generated from the Flow-annotated source; those
82
+ have been removed.
83
+
84
+ If you still need Flow types, you can vendor the last Flow-annotated source
85
+ locally from the [`3.2.0` tag](https://github.com/react-grid-layout/react-resizable/tree/db2e37eda85fb21b1864e36b01c4922452f28418/lib).
86
+ They will not be updated to reflect changes landing after `4.0.0`. The
87
+ official recommendation is to migrate to TypeScript.
88
+
50
89
  ## Compatibility
51
90
 
52
- | Version | React Version |
53
- |---------|---------------|
54
- | [3.x](https://github.com/react-grid-layout/react-resizable/blob/master/CHANGELOG.md#300-may-10-2021) | `>= 16.3` |
55
- | 2.x | Skipped |
56
- | [1.x](https://github.com/react-grid-layout/react-resizable/blob/master/CHANGELOG.md#1111-mar-5-2021) | `14 - 17` |
91
+ | Version | React Version | Types |
92
+ |---------|---------------|----------------|
93
+ | [4.x](https://github.com/react-grid-layout/react-resizable/blob/master/CHANGELOG.md#400-may-12-2026) | `>= 16.3` | TypeScript (bundled) |
94
+ | [3.x](https://github.com/react-grid-layout/react-resizable/blob/master/CHANGELOG.md#300-may-10-2021) | `>= 16.3` | Flow (`*.js.flow`) |
95
+ | 2.x | Skipped | |
96
+ | [1.x](https://github.com/react-grid-layout/react-resizable/blob/master/CHANGELOG.md#1111-mar-5-2021) | `14 - 17` | Flow |
57
97
 
58
98
  ## Usage
59
99
 
60
100
  This package has two major exports:
61
101
 
62
- * [`<Resizable>`](https://github.com/react-grid-layout/react-resizable/blob/master/lib/Resizable.js): A raw component that does not have state. Use as a building block for larger components, by listening to its callbacks and setting its props.
63
- * [`<ResizableBox>`](https://github.com/react-grid-layout/react-resizable/blob/master/lib/ResizableBox.js): A simple `<div {...props} />` element that manages basic state. Convenient for simple use-cases.
102
+ * [`<Resizable>`](https://github.com/react-grid-layout/react-resizable/blob/master/lib/Resizable.tsx): A raw component that does not have state. Use as a building block for larger components, by listening to its callbacks and setting its props.
103
+ * [`<ResizableBox>`](https://github.com/react-grid-layout/react-resizable/blob/master/lib/ResizableBox.tsx): A simple `<div {...props} />` element that manages basic state. Convenient for simple use-cases.
64
104
 
65
105
  ### `<Resizable>`
66
106
 
@@ -124,43 +164,46 @@ class Example extends React.Component {
124
164
 
125
165
  These props apply to both `<Resizable>` and `<ResizableBox>`. Unknown props that are not in the list below will be passed to the child component.
126
166
 
127
- ```js
167
+ ```ts
128
168
  type ResizeCallbackData = {
129
- node: HTMLElement,
130
- size: {width: number, height: number},
131
- handle: ResizeHandleAxis
169
+ node: HTMLElement;
170
+ size: {width: number; height: number};
171
+ handle: ResizeHandleAxis;
132
172
  };
133
173
 
134
174
  type ResizeHandleAxis = 's' | 'w' | 'e' | 'n' | 'sw' | 'nw' | 'se' | 'ne';
135
175
 
136
176
  type ResizableProps = {
137
- children: React.Element<any>,
138
- width: number,
139
- height: number,
177
+ children: React.ReactElement<any>;
178
+ width: number;
179
+ height: number;
140
180
  // Either a ReactElement to be used as handle, or a function
141
181
  // returning an element that is fed the handle's location as its first argument.
142
- handle: ReactElement<any> | (resizeHandle: ResizeHandleAxis, ref: ReactRef<HTMLElement>) => ReactElement<any>,
143
- // If you change this, be sure to update your css
144
- handleSize: [number, number] = [10, 10],
145
- lockAspectRatio: boolean = false,
146
- axis: 'both' | 'x' | 'y' | 'none' = 'both',
147
- minConstraints: [number, number] = [10, 10],
148
- maxConstraints: [number, number] = [Infinity, Infinity],
149
- onResizeStop?: ?(e: SyntheticEvent, data: ResizeCallbackData) => any,
150
- onResizeStart?: ?(e: SyntheticEvent, data: ResizeCallbackData) => any,
151
- onResize?: ?(e: SyntheticEvent, data: ResizeCallbackData) => any,
152
- draggableOpts?: ?Object,
153
- resizeHandles?: ?Array<ResizeHandleAxis> = ['se'],
182
+ handle?:
183
+ | React.ReactElement<any>
184
+ | ((resizeHandle: ResizeHandleAxis, ref: React.RefObject<HTMLElement>) => React.ReactElement<any>);
185
+ // If you change this, be sure to update your css. Default: [20, 20].
186
+ handleSize?: [number, number];
187
+ lockAspectRatio?: boolean; // default: false
188
+ axis?: 'both' | 'x' | 'y' | 'none'; // default: 'both'
189
+ minConstraints?: [number, number]; // default: [20, 20]
190
+ maxConstraints?: [number, number]; // default: [Infinity, Infinity]
191
+ onResizeStop?: (e: React.SyntheticEvent, data: ResizeCallbackData) => any;
192
+ onResizeStart?: (e: React.SyntheticEvent, data: ResizeCallbackData) => any;
193
+ onResize?: (e: React.SyntheticEvent, data: ResizeCallbackData) => any;
194
+ // Forwarded to react-draggable's <DraggableCore>.
195
+ draggableOpts?: Partial<React.ComponentProps<typeof import('react-draggable').DraggableCore>>;
196
+ resizeHandles?: ResizeHandleAxis[]; // default: ['se']
154
197
  // If `transform: scale(n)` is set on the parent, this should be set to `n`.
155
- transformScale?: number = 1
198
+ transformScale?: number; // default: 1
156
199
  };
157
200
  ```
158
201
 
159
202
  The following props can also be used on `<ResizableBox>`:
160
203
 
161
- ```js
204
+ ```ts
162
205
  {
163
- style?: Object // styles the returned <div />
206
+ style?: React.CSSProperties; // styles the returned <div />
164
207
  }
165
208
  ```
166
209
 
@@ -0,0 +1,29 @@
1
+ import * as React from 'react';
2
+ import type { ResizeHandleAxis, DefaultProps, Props, DragCallbackData } from './propTypes';
3
+ export default class Resizable extends React.Component<Props, {}> {
4
+ static propTypes: {
5
+ [key: string]: any;
6
+ };
7
+ static defaultProps: DefaultProps;
8
+ handleRefs: {
9
+ [key in ResizeHandleAxis]?: React.RefObject<HTMLElement>;
10
+ };
11
+ lastHandleRect: DOMRect | null;
12
+ slack: [number, number] | null;
13
+ lastSize: {
14
+ width: number;
15
+ height: number;
16
+ } | null;
17
+ componentWillUnmount(): void;
18
+ resetData(): void;
19
+ runConstraints(width: number, height: number): [number, number];
20
+ /**
21
+ * Wrapper around drag events to provide more useful data.
22
+ *
23
+ * @param {String} handlerName Handler name to wrap.
24
+ * @return {Function} Handler function.
25
+ */
26
+ resizeHandler(handlerName: 'onResize' | 'onResizeStart' | 'onResizeStop', axis: ResizeHandleAxis): (e: React.SyntheticEvent, data: DragCallbackData) => void;
27
+ renderResizeHandle(handleAxis: ResizeHandleAxis, ref: React.RefObject<HTMLElement>): React.ReactNode;
28
+ render(): React.ReactNode;
29
+ }
@@ -9,7 +9,6 @@ var _propTypes = require("./propTypes");
9
9
  const _excluded = ["children", "className", "draggableOpts", "width", "height", "handle", "handleSize", "lockAspectRatio", "axis", "minConstraints", "maxConstraints", "onResize", "onResizeStop", "onResizeStart", "resizeHandles", "transformScale"];
10
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
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
12
  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
13
  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
14
  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; }
@@ -35,11 +34,10 @@ class Resizable extends React.Component {
35
34
 
36
35
  // Clamp width and height within provided constraints
37
36
  runConstraints(width, height) {
38
- const {
39
- minConstraints,
40
- maxConstraints,
41
- lockAspectRatio
42
- } = this.props;
37
+ const _this$props = this.props,
38
+ minConstraints = _this$props.minConstraints,
39
+ maxConstraints = _this$props.maxConstraints,
40
+ lockAspectRatio = _this$props.lockAspectRatio;
43
41
  // short circuit
44
42
  if (!minConstraints && !maxConstraints && !lockAspectRatio) return [width, height];
45
43
 
@@ -59,12 +57,15 @@ class Resizable extends React.Component {
59
57
  width = height * ratio;
60
58
  }
61
59
  }
62
- const [oldW, oldH] = [width, height];
60
+ const oldW = width,
61
+ oldH = height;
63
62
 
64
63
  // Add slack to the values used to calculate bound position. This will ensure that if
65
64
  // we start removing slack, the element won't react to it right away until it's been
66
65
  // completely removed.
67
- let [slackW, slackH] = this.slack || [0, 0];
66
+ const _ref = this.slack || [0, 0],
67
+ slackW = _ref[0],
68
+ slackH = _ref[1];
68
69
  width += slackW;
69
70
  height += slackH;
70
71
  if (minConstraints) {
@@ -88,12 +89,11 @@ class Resizable extends React.Component {
88
89
  * @return {Function} Handler function.
89
90
  */
90
91
  resizeHandler(handlerName, axis) {
91
- return (e, _ref) => {
92
- let {
93
- node,
94
- deltaX,
95
- deltaY
96
- } = _ref;
92
+ return (e, _ref2) => {
93
+ var _this$lastSize$width, _this$lastSize, _this$lastSize$height, _this$lastSize2;
94
+ let node = _ref2.node,
95
+ deltaX = _ref2.deltaX,
96
+ deltaY = _ref2.deltaY;
97
97
  // Reset data in case it was left over somehow (should not be possible)
98
98
  if (handlerName === 'onResizeStart') this.resetData();
99
99
 
@@ -132,21 +132,29 @@ class Resizable extends React.Component {
132
132
  if (axisV === 'n') deltaY = -deltaY;
133
133
 
134
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);
135
+ // Use lastSize (if available) instead of props to avoid losing deltas
136
+ // when React can't re-render between consecutive mouse events.
137
+ const baseWidth = (_this$lastSize$width = (_this$lastSize = this.lastSize) == null ? void 0 : _this$lastSize.width) != null ? _this$lastSize$width : this.props.width;
138
+ const baseHeight = (_this$lastSize$height = (_this$lastSize2 = this.lastSize) == null ? void 0 : _this$lastSize2.height) != null ? _this$lastSize$height : this.props.height;
139
+ let width = baseWidth + (canDragX ? deltaX / this.props.transformScale : 0);
140
+ let height = baseHeight + (canDragY ? deltaY / this.props.transformScale : 0);
137
141
 
138
142
  // Run user-provided constraints.
139
- [width, height] = this.runConstraints(width, height);
140
-
141
143
  // For onResizeStop, use the last size from onResize rather than recalculating.
142
144
  // This avoids issues where props.width/height are stale due to React's batched updates.
145
+ var _this$runConstraints = this.runConstraints(width, height);
146
+ width = _this$runConstraints[0];
147
+ height = _this$runConstraints[1];
143
148
  if (handlerName === 'onResizeStop' && this.lastSize) {
144
- ({
145
- width,
146
- height
147
- } = this.lastSize);
149
+ var _this$lastSize3 = this.lastSize;
150
+ width = _this$lastSize3.width;
151
+ height = _this$lastSize3.height;
148
152
  }
149
- const dimensionsChanged = width !== this.props.width || height !== this.props.height;
153
+
154
+ // Compare against the base (lastSize-or-props) so that callbacks correctly
155
+ // suppress when the net delta is zero, even if props are stale relative to
156
+ // the accumulated lastSize.
157
+ const dimensionsChanged = width !== baseWidth || height !== baseHeight;
150
158
 
151
159
  // Store the size for use in onResizeStop. We do this after the onResizeStop check
152
160
  // above so we don't overwrite the stored value with a potentially stale calculation.
@@ -162,7 +170,7 @@ class Resizable extends React.Component {
162
170
  // Don't call 'onResize' if dimensions haven't changed.
163
171
  const shouldSkipCb = handlerName === 'onResize' && !dimensionsChanged;
164
172
  if (cb && !shouldSkipCb) {
165
- e.persist?.();
173
+ e.persist == null || e.persist();
166
174
  cb(e, {
167
175
  node,
168
176
  size: {
@@ -181,13 +189,11 @@ class Resizable extends React.Component {
181
189
  // Render a resize handle given an axis & DOM ref. Ref *must* be attached for
182
190
  // the underlying draggable library to work properly.
183
191
  renderResizeHandle(handleAxis, ref) {
184
- const {
185
- handle
186
- } = this.props;
192
+ const handle = this.props.handle;
187
193
  // No handle provided, make the default
188
194
  if (!handle) {
189
195
  return /*#__PURE__*/React.createElement("span", {
190
- className: `react-resizable-handle react-resizable-handle-${handleAxis}`,
196
+ className: "react-resizable-handle react-resizable-handle-" + handleAxis,
191
197
  ref: ref
192
198
  });
193
199
  }
@@ -207,40 +213,38 @@ class Resizable extends React.Component {
207
213
  }
208
214
  render() {
209
215
  // Pass along only props not meant for the `<Resizable>`.`
210
- // eslint-disable-next-line no-unused-vars
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);
216
+ const _this$props2 = this.props,
217
+ children = _this$props2.children,
218
+ className = _this$props2.className,
219
+ draggableOpts = _this$props2.draggableOpts,
220
+ width = _this$props2.width,
221
+ height = _this$props2.height,
222
+ handle = _this$props2.handle,
223
+ handleSize = _this$props2.handleSize,
224
+ lockAspectRatio = _this$props2.lockAspectRatio,
225
+ axis = _this$props2.axis,
226
+ minConstraints = _this$props2.minConstraints,
227
+ maxConstraints = _this$props2.maxConstraints,
228
+ onResize = _this$props2.onResize,
229
+ onResizeStop = _this$props2.onResizeStop,
230
+ onResizeStart = _this$props2.onResizeStart,
231
+ resizeHandles = _this$props2.resizeHandles,
232
+ transformScale = _this$props2.transformScale,
233
+ p = _objectWithoutPropertiesLoose(_this$props2, _excluded);
231
234
 
232
235
  // What we're doing here is getting the child of this element, and cloning it with this element's props.
233
236
  // We are then defining its children as:
234
237
  // 1. Its original children (resizable's child's children), and
235
238
  // 2. One or more draggable handles.
236
239
  return (0, _utils.cloneElement)(children, _objectSpread(_objectSpread({}, p), {}, {
237
- className: `${className ? `${className} ` : ''}react-resizable`,
240
+ className: (className ? className + " " : '') + "react-resizable",
238
241
  children: [...React.Children.toArray(children.props.children), ...resizeHandles.map(handleAxis => {
242
+ var _this$handleRefs$hand;
239
243
  // Create a ref to the handle so that `<DraggableCore>` doesn't have to use ReactDOM.findDOMNode().
240
- const ref = this.handleRefs[handleAxis] ?? (this.handleRefs[handleAxis] = /*#__PURE__*/React.createRef());
244
+ const ref = (_this$handleRefs$hand = this.handleRefs[handleAxis]) != null ? _this$handleRefs$hand : this.handleRefs[handleAxis] = /*#__PURE__*/React.createRef();
241
245
  return /*#__PURE__*/React.createElement(_reactDraggable.DraggableCore, _extends({}, draggableOpts, {
242
246
  nodeRef: ref,
243
- key: `resizableHandle-${handleAxis}`,
247
+ key: "resizableHandle-" + handleAxis,
244
248
  onStop: this.resizeHandler('onResizeStop', handleAxis),
245
249
  onStart: this.resizeHandler('onResizeStart', handleAxis),
246
250
  onDrag: this.resizeHandler('onResize', handleAxis)
@@ -0,0 +1,18 @@
1
+ import * as React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import type { Props as ResizableProps, ResizeCallbackData, ResizableBoxState } from './propTypes';
4
+ type ResizableBoxProps = Omit<ResizableProps, 'children'> & {
5
+ style?: React.CSSProperties;
6
+ children?: React.ReactElement<any>;
7
+ className?: string | null;
8
+ };
9
+ export default class ResizableBox extends React.Component<ResizableBoxProps, ResizableBoxState> {
10
+ static propTypes: {
11
+ children: PropTypes.Requireable<PropTypes.ReactElementLike>;
12
+ };
13
+ state: ResizableBoxState;
14
+ static getDerivedStateFromProps(props: ResizableBoxProps, state: ResizableBoxState): ResizableBoxState | null;
15
+ onResize: (e: React.SyntheticEvent, data: ResizeCallbackData) => void;
16
+ render(): React.ReactNode;
17
+ }
18
+ export {};
@@ -15,12 +15,9 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
15
15
  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; }
16
16
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
17
17
  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); }
18
- 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; }
19
18
  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; }
20
- // ElementConfig gives us an object type where all items present in `defaultProps` are made optional.
21
- // <ResizableBox> does not have defaultProps, so we can use this type to tell Flow that we don't
22
- // care about that and will handle it in <Resizable> instead.
23
- // A <ResizableBox> can also have a `style` property.
19
+ // <ResizableBox> does not have defaultProps, so we make all of <Resizable>'s defaults optional here
20
+ // and add an optional `style` property.
24
21
 
25
22
  class ResizableBox extends React.Component {
26
23
  constructor() {
@@ -32,11 +29,9 @@ class ResizableBox extends React.Component {
32
29
  propsHeight: this.props.height
33
30
  };
34
31
  this.onResize = (e, data) => {
35
- const {
36
- size
37
- } = data;
32
+ const size = data.size;
38
33
  if (this.props.onResize) {
39
- e.persist?.();
34
+ e.persist == null || e.persist();
40
35
  this.setState(size, () => this.props.onResize && this.props.onResize(e, data));
41
36
  } else {
42
37
  this.setState(size);
@@ -60,24 +55,22 @@ class ResizableBox extends React.Component {
60
55
  // If you use Resizable directly, you are responsible for updating the child component
61
56
  // with a new width and height.
62
57
  const _this$props = this.props,
63
- {
64
- handle,
65
- handleSize,
66
- onResize,
67
- onResizeStart,
68
- onResizeStop,
69
- draggableOpts,
70
- minConstraints,
71
- maxConstraints,
72
- lockAspectRatio,
73
- axis,
74
- width,
75
- height,
76
- resizeHandles,
77
- style,
78
- transformScale
79
- } = _this$props,
80
- props = _objectWithoutProperties(_this$props, _excluded);
58
+ handle = _this$props.handle,
59
+ handleSize = _this$props.handleSize,
60
+ onResize = _this$props.onResize,
61
+ onResizeStart = _this$props.onResizeStart,
62
+ onResizeStop = _this$props.onResizeStop,
63
+ draggableOpts = _this$props.draggableOpts,
64
+ minConstraints = _this$props.minConstraints,
65
+ maxConstraints = _this$props.maxConstraints,
66
+ lockAspectRatio = _this$props.lockAspectRatio,
67
+ axis = _this$props.axis,
68
+ width = _this$props.width,
69
+ height = _this$props.height,
70
+ resizeHandles = _this$props.resizeHandles,
71
+ style = _this$props.style,
72
+ transformScale = _this$props.transformScale,
73
+ props = _objectWithoutPropertiesLoose(_this$props, _excluded);
81
74
  return /*#__PURE__*/React.createElement(_Resizable.default, {
82
75
  axis: axis,
83
76
  draggableOpts: draggableOpts,
@@ -0,0 +1,3 @@
1
+ export { default as Resizable } from './Resizable';
2
+ export { default as ResizableBox } from './ResizableBox';
3
+ export type { Axis, DefaultProps, DragCallbackData, Props, ReactRef, ResizableBoxState, ResizableState, ResizeCallbackData, ResizeHandleAxis, } from './propTypes';
package/build/index.js ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.ResizableBox = exports.Resizable = void 0;
5
+ var _Resizable = _interopRequireDefault(require("./Resizable"));
6
+ exports.Resizable = _Resizable.default;
7
+ var _ResizableBox = _interopRequireDefault(require("./ResizableBox"));
8
+ exports.ResizableBox = _ResizableBox.default;
9
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -0,0 +1,55 @@
1
+ import type * as React from 'react';
2
+ import type { DraggableCore } from 'react-draggable';
3
+ export type ReactRef<T extends HTMLElement> = {
4
+ current: T | null;
5
+ };
6
+ export type Axis = 'both' | 'x' | 'y' | 'none';
7
+ export type ResizeHandleAxis = 's' | 'w' | 'e' | 'n' | 'sw' | 'nw' | 'se' | 'ne';
8
+ export type ResizableState = {};
9
+ export type ResizableBoxState = {
10
+ width: number;
11
+ height: number;
12
+ propsWidth: number;
13
+ propsHeight: number;
14
+ };
15
+ export type DragCallbackData = {
16
+ node: HTMLElement;
17
+ x: number;
18
+ y: number;
19
+ deltaX: number;
20
+ deltaY: number;
21
+ lastX: number;
22
+ lastY: number;
23
+ };
24
+ export type ResizeCallbackData = {
25
+ node: HTMLElement;
26
+ size: {
27
+ width: number;
28
+ height: number;
29
+ };
30
+ handle: ResizeHandleAxis;
31
+ };
32
+ export type DefaultProps = {
33
+ axis: Axis;
34
+ handleSize: [number, number];
35
+ lockAspectRatio: boolean;
36
+ minConstraints: [number, number];
37
+ maxConstraints: [number, number];
38
+ resizeHandles: ResizeHandleAxis[];
39
+ transformScale: number;
40
+ };
41
+ export type ResizeHandleFn = (resizeHandleAxis: ResizeHandleAxis, ref: React.RefObject<HTMLElement>) => React.ReactElement<any>;
42
+ export type Props = DefaultProps & {
43
+ children: React.ReactElement<any>;
44
+ className?: string | null;
45
+ draggableOpts?: Partial<React.ComponentProps<typeof DraggableCore>> | null;
46
+ height: number;
47
+ handle?: React.ReactElement<any> | ResizeHandleFn;
48
+ onResizeStop?: ((e: React.SyntheticEvent, data: ResizeCallbackData) => any) | null;
49
+ onResizeStart?: ((e: React.SyntheticEvent, data: ResizeCallbackData) => any) | null;
50
+ onResize?: ((e: React.SyntheticEvent, data: ResizeCallbackData) => any) | null;
51
+ width: number;
52
+ };
53
+ export declare const resizableProps: {
54
+ [key: string]: any;
55
+ };
@@ -3,10 +3,9 @@
3
3
  exports.__esModule = true;
4
4
  exports.resizableProps = void 0;
5
5
  var _propTypes = _interopRequireDefault(require("prop-types"));
6
- var _reactDraggable = require("react-draggable");
7
6
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
8
- /* global Element */
9
7
  // <Resizable>
8
+
10
9
  const resizableProps = exports.resizableProps = {
11
10
  /*
12
11
  * Restricts resizing to a particular axis (default: 'both')
@@ -48,7 +47,7 @@ const resizableProps = exports.resizableProps = {
48
47
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
49
48
  args[_key] = arguments[_key];
50
49
  }
51
- const [props] = args;
50
+ const props = args[0];
52
51
  // Required if resizing height or both
53
52
  if (props.axis === 'both' || props.axis === 'y') {
54
53
  return _propTypes.default.number.isRequired(...args);
@@ -107,7 +106,7 @@ const resizableProps = exports.resizableProps = {
107
106
  for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
108
107
  args[_key2] = arguments[_key2];
109
108
  }
110
- const [props] = args;
109
+ const props = args[0];
111
110
  // Required if resizing width or both
112
111
  if (props.axis === 'both' || props.axis === 'x') {
113
112
  return _propTypes.default.number.isRequired(...args);
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare function cloneElement(element: React.ReactElement<any>, props: Record<string, any>): React.ReactElement<any>;
package/build/utils.js CHANGED
@@ -15,7 +15,7 @@ function cloneElement(element, props) {
15
15
  props.style = _objectSpread(_objectSpread({}, element.props.style), props.style);
16
16
  }
17
17
  if (props.className && element.props.className) {
18
- props.className = `${element.props.className} ${props.className}`;
18
+ props.className = element.props.className + " " + props.className;
19
19
  }
20
20
  return /*#__PURE__*/_react.default.cloneElement(element, props);
21
21
  }
package/package.json CHANGED
@@ -1,25 +1,26 @@
1
1
  {
2
2
  "name": "react-resizable",
3
- "version": "3.1.3",
3
+ "version": "4.0.0",
4
4
  "description": "A component that is resizable with handles.",
5
5
  "main": "index.js",
6
+ "types": "./build/index.d.ts",
6
7
  "files": [
7
8
  "build/",
8
9
  "css/",
9
10
  "index.js"
10
11
  ],
11
12
  "scripts": {
12
- "lint": "eslint lib/ __tests__/ setupTests/; flow",
13
+ "lint": "eslint lib/ __tests__/ setupTests/",
14
+ "typecheck": "tsc --noEmit",
13
15
  "test": "jest --coverage",
14
16
  "unit": "jest --watch --verbose",
15
17
  "build": "bash build.sh",
16
18
  "build-example": "webpack",
17
19
  "dev": "webpack serve --open",
18
20
  "prepublishOnly": "npm run build",
19
- "preversion": "npm run lint",
21
+ "preversion": "npm run lint && npm run typecheck",
20
22
  "version": "git add CHANGELOG.md",
21
- "postversion": "git push && git push --tags",
22
- "flow": "flow"
23
+ "postversion": "git push && git push --tags"
23
24
  },
24
25
  "repository": {
25
26
  "type": "git",
@@ -37,35 +38,41 @@
37
38
  },
38
39
  "homepage": "https://github.com/react-grid-layout/react-resizable",
39
40
  "devDependencies": {
40
- "@babel/cli": "^7.28.3",
41
- "@babel/core": "^7.28.5",
42
- "@babel/eslint-parser": "^7.28.5",
41
+ "@babel/cli": "^7.28.6",
42
+ "@babel/core": "^7.29.0",
43
43
  "@babel/plugin-proposal-class-properties": "^7.18.6",
44
44
  "@babel/plugin-proposal-object-rest-spread": "^7.20.7",
45
- "@babel/preset-env": "^7.28.5",
46
- "@babel/preset-flow": "^7.27.1",
45
+ "@babel/preset-env": "^7.29.5",
47
46
  "@babel/preset-react": "^7.28.5",
47
+ "@babel/preset-typescript": "^7.28.5",
48
+ "@eslint/js": "^9.39.4",
48
49
  "@testing-library/dom": "^10.4.1",
49
50
  "@testing-library/jest-dom": "^6.1.0",
50
- "@testing-library/react": "^16.3.1",
51
+ "@testing-library/react": "^16.3.2",
51
52
  "@testing-library/user-event": "^14.5.0",
52
- "babel-loader": "^10.0.0",
53
+ "@types/jest": "^30.0.0",
54
+ "@types/prop-types": "^15.7.0",
55
+ "@types/react": "^19.2.0",
56
+ "@types/react-dom": "^19.2.0",
57
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
58
+ "@typescript-eslint/parser": "^8.0.0",
59
+ "babel-loader": "^10.1.1",
53
60
  "cross-env": "^10.1.0",
54
- "css-loader": "^7.1.2",
55
- "eslint": "^9.39.2",
56
- "eslint-plugin-jest": "^29.11.3",
61
+ "css-loader": "^7.1.4",
62
+ "eslint": "^9.39.4",
63
+ "eslint-plugin-jest": "^29.15.2",
57
64
  "eslint-plugin-react": "^7.37.5",
58
- "flow-bin": "^0.153.0",
59
- "jest": "^30.2.0",
60
- "jest-environment-jsdom": "^30.2.0",
61
- "lodash": "^4.17.20",
65
+ "jest": "^30.4.2",
66
+ "jest-environment-jsdom": "^30.4.1",
67
+ "lodash": "^4.18.1",
62
68
  "pre-commit": "^1.1.2",
63
- "react": "^19.2.3",
64
- "react-dom": "^19.2.3",
69
+ "react": "^19.2.6",
70
+ "react-dom": "^19.2.6",
65
71
  "style-loader": "^4.0.0",
66
- "webpack": "^5.104.1",
67
- "webpack-cli": "^6.0.1",
68
- "webpack-dev-server": "^5.2.2"
72
+ "typescript": "^5.6.0",
73
+ "webpack": "^5.106.2",
74
+ "webpack-cli": "^7.0.2",
75
+ "webpack-dev-server": "^5.2.4"
69
76
  },
70
77
  "dependencies": {
71
78
  "prop-types": "15.x",
@@ -1,224 +0,0 @@
1
- // @flow
2
- import * as React from 'react';
3
- import type {Node as ReactNode} from 'react';
4
- import {DraggableCore} from 'react-draggable';
5
- import {cloneElement} from './utils';
6
- import {resizableProps} from "./propTypes";
7
- import type {ResizeHandleAxis, DefaultProps, Props, ReactRef, DragCallbackData} from './propTypes';
8
-
9
- // The base <Resizable> component.
10
- // This component does not have state and relies on the parent to set its props based on callback data.
11
- export default class Resizable extends React.Component<Props, void> {
12
- static propTypes = resizableProps;
13
-
14
- static defaultProps: DefaultProps = {
15
- axis: 'both',
16
- handleSize: [20, 20],
17
- lockAspectRatio: false,
18
- minConstraints: [20, 20],
19
- maxConstraints: [Infinity, Infinity],
20
- resizeHandles: ['se'],
21
- transformScale: 1
22
- };
23
-
24
- handleRefs: {[key: ResizeHandleAxis]: ReactRef<HTMLElement>} = {};
25
- lastHandleRect: ?ClientRect = null;
26
- slack: ?[number, number] = null;
27
- lastSize: ?{width: number, height: number} = null;
28
-
29
- componentWillUnmount() {
30
- this.resetData();
31
- }
32
-
33
- resetData() {
34
- this.lastHandleRect = this.slack = this.lastSize = null;
35
- }
36
-
37
- // Clamp width and height within provided constraints
38
- runConstraints(width: number, height: number): [number, number] {
39
- const {minConstraints, maxConstraints, lockAspectRatio} = this.props;
40
- // short circuit
41
- if (!minConstraints && !maxConstraints && !lockAspectRatio) return [width, height];
42
-
43
- // If constraining to min and max, we need to also fit width and height to aspect ratio.
44
- if (lockAspectRatio) {
45
- const ratio = this.props.width / this.props.height;
46
- const deltaW = width - this.props.width;
47
- const deltaH = height - this.props.height;
48
-
49
- // Find which coordinate was greater and should push the other toward it.
50
- // E.g.:
51
- // ratio = 1, deltaW = 10, deltaH = 5, deltaH should become 10.
52
- // ratio = 2, deltaW = 10, deltaH = 6, deltaW should become 12.
53
- if (Math.abs(deltaW) > Math.abs(deltaH * ratio)) {
54
- height = width / ratio;
55
- } else {
56
- width = height * ratio;
57
- }
58
- }
59
-
60
- const [oldW, oldH] = [width, height];
61
-
62
- // Add slack to the values used to calculate bound position. This will ensure that if
63
- // we start removing slack, the element won't react to it right away until it's been
64
- // completely removed.
65
- let [slackW, slackH] = this.slack || [0, 0];
66
- width += slackW;
67
- height += slackH;
68
-
69
- if (minConstraints) {
70
- width = Math.max(minConstraints[0], width);
71
- height = Math.max(minConstraints[1], height);
72
- }
73
- if (maxConstraints) {
74
- width = Math.min(maxConstraints[0], width);
75
- height = Math.min(maxConstraints[1], height);
76
- }
77
-
78
- // If the width or height changed, we must have introduced some slack. Record it for the next iteration.
79
- this.slack = [slackW + (oldW - width), slackH + (oldH - height)];
80
-
81
- return [width, height];
82
- }
83
-
84
- /**
85
- * Wrapper around drag events to provide more useful data.
86
- *
87
- * @param {String} handlerName Handler name to wrap.
88
- * @return {Function} Handler function.
89
- */
90
- resizeHandler(handlerName: 'onResize' | 'onResizeStart' | 'onResizeStop', axis: ResizeHandleAxis): Function {
91
- return (e: SyntheticEvent<>, {node, deltaX, deltaY}: DragCallbackData) => {
92
- // Reset data in case it was left over somehow (should not be possible)
93
- if (handlerName === 'onResizeStart') this.resetData();
94
-
95
- // Axis restrictions
96
- const canDragX = (this.props.axis === 'both' || this.props.axis === 'x') && axis !== 'n' && axis !== 's';
97
- const canDragY = (this.props.axis === 'both' || this.props.axis === 'y') && axis !== 'e' && axis !== 'w';
98
- // No dragging possible.
99
- if (!canDragX && !canDragY) return;
100
-
101
- // Decompose axis for later use
102
- const axisV = axis[0];
103
- const axisH = axis[axis.length - 1]; // intentionally not axis[1], so that this catches axis === 'w' for example
104
-
105
- // Track the element being dragged to account for changes in position.
106
- // If a handle's position is changed between callbacks, we need to factor this in to the next callback.
107
- // Failure to do so will cause the element to "skip" when resized upwards or leftwards.
108
- const handleRect = node.getBoundingClientRect();
109
- if (this.lastHandleRect != null) {
110
- // If the handle has repositioned on either axis since last render,
111
- // we need to increase our callback values by this much.
112
- // Only checking 'n', 'w' since resizing by 's', 'w' won't affect the overall position on page,
113
- if (axisH === 'w') {
114
- const deltaLeftSinceLast = handleRect.left - this.lastHandleRect.left;
115
- deltaX += deltaLeftSinceLast;
116
- }
117
- if (axisV === 'n') {
118
- const deltaTopSinceLast = handleRect.top - this.lastHandleRect.top;
119
- deltaY += deltaTopSinceLast;
120
- }
121
- }
122
- // Storage of last rect so we know how much it has really moved.
123
- this.lastHandleRect = handleRect;
124
-
125
- // Reverse delta if using top or left drag handles.
126
- if (axisH === 'w') deltaX = -deltaX;
127
- if (axisV === 'n') deltaY = -deltaY;
128
-
129
- // Update w/h by the deltas. Also factor in transformScale.
130
- let width = this.props.width + (canDragX ? deltaX / this.props.transformScale : 0);
131
- let height = this.props.height + (canDragY ? deltaY / this.props.transformScale : 0);
132
-
133
- // Run user-provided constraints.
134
- [width, height] = this.runConstraints(width, height);
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
-
142
- const dimensionsChanged = width !== this.props.width || height !== this.props.height;
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
-
150
- // Call user-supplied callback if present.
151
- const cb = typeof this.props[handlerName] === 'function' ? this.props[handlerName] : null;
152
- // Don't call 'onResize' if dimensions haven't changed.
153
- const shouldSkipCb = handlerName === 'onResize' && !dimensionsChanged;
154
- if (cb && !shouldSkipCb) {
155
- e.persist?.();
156
- cb(e, {node, size: {width, height}, handle: axis});
157
- }
158
-
159
- // Reset internal data
160
- if (handlerName === 'onResizeStop') this.resetData();
161
- };
162
- }
163
-
164
- // Render a resize handle given an axis & DOM ref. Ref *must* be attached for
165
- // the underlying draggable library to work properly.
166
- renderResizeHandle(handleAxis: ResizeHandleAxis, ref: ReactRef<HTMLElement>): ReactNode {
167
- const {handle} = this.props;
168
- // No handle provided, make the default
169
- if (!handle) {
170
- return <span className={`react-resizable-handle react-resizable-handle-${handleAxis}`} ref={ref} />;
171
- }
172
- // Handle is a function, such as:
173
- // `handle={(handleAxis) => <span className={...} />}`
174
- if (typeof handle === 'function') {
175
- return handle(handleAxis, ref);
176
- }
177
- // Handle is a React component (composite or DOM).
178
- const isDOMElement = typeof handle.type === 'string';
179
- const props = {
180
- ref,
181
- // Add `handleAxis` prop iff this is not a DOM element,
182
- // otherwise we'll get an unknown property warning
183
- ...(isDOMElement ? {} : {handleAxis})
184
- };
185
- return React.cloneElement(handle, props);
186
-
187
- }
188
-
189
- render(): ReactNode {
190
- // Pass along only props not meant for the `<Resizable>`.`
191
- // eslint-disable-next-line no-unused-vars
192
- const {children, className, draggableOpts, width, height, handle, handleSize,
193
- lockAspectRatio, axis, minConstraints, maxConstraints, onResize,
194
- onResizeStop, onResizeStart, resizeHandles, transformScale, ...p} = this.props;
195
-
196
- // What we're doing here is getting the child of this element, and cloning it with this element's props.
197
- // We are then defining its children as:
198
- // 1. Its original children (resizable's child's children), and
199
- // 2. One or more draggable handles.
200
- return cloneElement(children, {
201
- ...p,
202
- className: `${className ? `${className} ` : ''}react-resizable`,
203
- children: [
204
- ...React.Children.toArray(children.props.children),
205
- ...resizeHandles.map((handleAxis) => {
206
- // Create a ref to the handle so that `<DraggableCore>` doesn't have to use ReactDOM.findDOMNode().
207
- const ref = (this.handleRefs[handleAxis]) ?? (this.handleRefs[handleAxis] = React.createRef());
208
- return (
209
- <DraggableCore
210
- {...draggableOpts}
211
- nodeRef={ref}
212
- key={`resizableHandle-${handleAxis}`}
213
- onStop={this.resizeHandler('onResizeStop', handleAxis)}
214
- onStart={this.resizeHandler('onResizeStart', handleAxis)}
215
- onDrag={this.resizeHandler('onResize', handleAxis)}
216
- >
217
- {this.renderResizeHandle(handleAxis, ref)}
218
- </DraggableCore>
219
- );
220
- })
221
- ]
222
- });
223
- }
224
- }
@@ -1,98 +0,0 @@
1
- // @flow
2
- import * as React from 'react';
3
- import type {Node as ReactNode, Element as ReactElement} from 'react';
4
- import PropTypes from 'prop-types';
5
-
6
- import Resizable from './Resizable';
7
- import {resizableProps} from "./propTypes";
8
- import type {ResizeCallbackData, ResizableBoxState} from './propTypes';
9
-
10
- // ElementConfig gives us an object type where all items present in `defaultProps` are made optional.
11
- // <ResizableBox> does not have defaultProps, so we can use this type to tell Flow that we don't
12
- // care about that and will handle it in <Resizable> instead.
13
- // A <ResizableBox> can also have a `style` property.
14
- type ResizableBoxProps = {|...React.ElementConfig<typeof Resizable>, style?: Object, children?: ReactElement<any>|};
15
-
16
- export default class ResizableBox extends React.Component<ResizableBoxProps, ResizableBoxState> {
17
-
18
- // PropTypes are identical to <Resizable>, except that children are not strictly required to be present.
19
- static propTypes = {
20
- ...resizableProps,
21
- children: PropTypes.element,
22
- };
23
-
24
- state: ResizableBoxState = {
25
- width: this.props.width,
26
- height: this.props.height,
27
- propsWidth: this.props.width,
28
- propsHeight: this.props.height,
29
- };
30
-
31
- static getDerivedStateFromProps(props: ResizableBoxProps, state: ResizableBoxState): ?ResizableBoxState {
32
- // If parent changes height/width, set that in our state.
33
- if (state.propsWidth !== props.width || state.propsHeight !== props.height) {
34
- return {
35
- width: props.width,
36
- height: props.height,
37
- propsWidth: props.width,
38
- propsHeight: props.height,
39
- };
40
- }
41
- return null;
42
- }
43
-
44
- onResize: (e: SyntheticEvent<>, data: ResizeCallbackData) => void = (e, data) => {
45
- const {size} = data;
46
- if (this.props.onResize) {
47
- e.persist?.();
48
- this.setState(size, () => this.props.onResize && this.props.onResize(e, data));
49
- } else {
50
- this.setState(size);
51
- }
52
- };
53
-
54
- render(): ReactNode {
55
- // Basic wrapper around a Resizable instance.
56
- // If you use Resizable directly, you are responsible for updating the child component
57
- // with a new width and height.
58
- const {
59
- handle,
60
- handleSize,
61
- onResize,
62
- onResizeStart,
63
- onResizeStop,
64
- draggableOpts,
65
- minConstraints,
66
- maxConstraints,
67
- lockAspectRatio,
68
- axis,
69
- width,
70
- height,
71
- resizeHandles,
72
- style,
73
- transformScale,
74
- ...props
75
- } = this.props;
76
-
77
- return (
78
- <Resizable
79
- axis={axis}
80
- draggableOpts={draggableOpts}
81
- handle={handle}
82
- handleSize={handleSize}
83
- height={this.state.height}
84
- lockAspectRatio={lockAspectRatio}
85
- maxConstraints={maxConstraints}
86
- minConstraints={minConstraints}
87
- onResizeStart={onResizeStart}
88
- onResize={this.onResize}
89
- onResizeStop={onResizeStop}
90
- resizeHandles={resizeHandles}
91
- transformScale={transformScale}
92
- width={this.state.width}
93
- >
94
- <div {...props} style={{...style, width: this.state.width + 'px', height: this.state.height + 'px'}} />
95
- </Resizable>
96
- );
97
- }
98
- }
@@ -1,161 +0,0 @@
1
- // @flow
2
- /* global Element */
3
- import PropTypes from 'prop-types';
4
- import {DraggableCore} from "react-draggable";
5
- import type {Element as ReactElement, ElementConfig} from 'react';
6
-
7
- export type ReactRef<T: HTMLElement> = {
8
- current: T | null
9
- };
10
-
11
- export type Axis = 'both' | 'x' | 'y' | 'none';
12
- export type ResizeHandleAxis = 's' | 'w' | 'e' | 'n' | 'sw' | 'nw' | 'se' | 'ne';
13
- export type ResizableState = void;
14
- export type ResizableBoxState = {
15
- width: number, height: number,
16
- propsWidth: number, propsHeight: number
17
- };
18
- export type DragCallbackData = {
19
- node: HTMLElement,
20
- x: number, y: number,
21
- deltaX: number, deltaY: number,
22
- lastX: number, lastY: number
23
- };
24
- export type ResizeCallbackData = {
25
- node: HTMLElement,
26
- size: {width: number, height: number},
27
- handle: ResizeHandleAxis
28
- };
29
-
30
- // <Resizable>
31
- export type DefaultProps = {
32
- axis: Axis,
33
- handleSize: [number, number],
34
- lockAspectRatio: boolean,
35
- minConstraints: [number, number],
36
- maxConstraints: [number, number],
37
- resizeHandles: ResizeHandleAxis[],
38
- transformScale: number,
39
- };
40
-
41
- export type Props = {
42
- ...DefaultProps,
43
- children: ReactElement<any>,
44
- className?: ?string,
45
- draggableOpts?: ?ElementConfig<typeof DraggableCore>,
46
- height: number,
47
- handle?: ReactElement<any> | (resizeHandleAxis: ResizeHandleAxis, ref: ReactRef<HTMLElement>) => ReactElement<any>,
48
- onResizeStop?: ?(e: SyntheticEvent<>, data: ResizeCallbackData) => any,
49
- onResizeStart?: ?(e: SyntheticEvent<>, data: ResizeCallbackData) => any,
50
- onResize?: ?(e: SyntheticEvent<>, data: ResizeCallbackData) => any,
51
- width: number,
52
- };
53
-
54
-
55
-
56
- export const resizableProps: Object = {
57
- /*
58
- * Restricts resizing to a particular axis (default: 'both')
59
- * 'both' - allows resizing by width or height
60
- * 'x' - only allows the width to be changed
61
- * 'y' - only allows the height to be changed
62
- * 'none' - disables resizing altogether
63
- * */
64
- axis: PropTypes.oneOf(['both', 'x', 'y', 'none']),
65
- className: PropTypes.string,
66
- /*
67
- * Require that one and only one child be present.
68
- * */
69
- children: PropTypes.element.isRequired,
70
- /*
71
- * These will be passed wholesale to react-draggable's DraggableCore
72
- * */
73
- draggableOpts: PropTypes.shape({
74
- allowAnyClick: PropTypes.bool,
75
- cancel: PropTypes.string,
76
- children: PropTypes.node,
77
- disabled: PropTypes.bool,
78
- enableUserSelectHack: PropTypes.bool,
79
- // #251: Check for Element to support SSR environments where DOM globals don't exist
80
- offsetParent: typeof Element !== 'undefined' ? PropTypes.instanceOf(Element) : PropTypes.any,
81
- grid: PropTypes.arrayOf(PropTypes.number),
82
- handle: PropTypes.string,
83
- nodeRef: PropTypes.object,
84
- onStart: PropTypes.func,
85
- onDrag: PropTypes.func,
86
- onStop: PropTypes.func,
87
- onMouseDown: PropTypes.func,
88
- scale: PropTypes.number,
89
- }),
90
- /*
91
- * Initial height
92
- * */
93
- height: (...args) => {
94
- const [props] = args;
95
- // Required if resizing height or both
96
- if (props.axis === 'both' || props.axis === 'y') {
97
- return PropTypes.number.isRequired(...args);
98
- }
99
- return PropTypes.number(...args);
100
- },
101
- /*
102
- * Customize cursor resize handle
103
- * */
104
- handle: PropTypes.oneOfType([
105
- PropTypes.node,
106
- PropTypes.func
107
- ]),
108
- /*
109
- * If you change this, be sure to update your css
110
- * */
111
- handleSize: PropTypes.arrayOf(PropTypes.number),
112
- lockAspectRatio: PropTypes.bool,
113
- /*
114
- * Max X & Y measure
115
- * */
116
- maxConstraints: PropTypes.arrayOf(PropTypes.number),
117
- /*
118
- * Min X & Y measure
119
- * */
120
- minConstraints: PropTypes.arrayOf(PropTypes.number),
121
- /*
122
- * Called on stop resize event
123
- * */
124
- onResizeStop: PropTypes.func,
125
- /*
126
- * Called on start resize event
127
- * */
128
- onResizeStart: PropTypes.func,
129
- /*
130
- * Called on resize event
131
- * */
132
- onResize: PropTypes.func,
133
- /*
134
- * Defines which resize handles should be rendered (default: 'se')
135
- * 's' - South handle (bottom-center)
136
- * 'w' - West handle (left-center)
137
- * 'e' - East handle (right-center)
138
- * 'n' - North handle (top-center)
139
- * 'sw' - Southwest handle (bottom-left)
140
- * 'nw' - Northwest handle (top-left)
141
- * 'se' - Southeast handle (bottom-right)
142
- * 'ne' - Northeast handle (top-center)
143
- * */
144
- resizeHandles: PropTypes.arrayOf(PropTypes.oneOf(['s', 'w', 'e', 'n', 'sw', 'nw', 'se', 'ne'])),
145
-
146
- /*
147
- * If `transform: scale(n)` is set on the parent, this should be set to `n`.
148
- * */
149
- transformScale: PropTypes.number,
150
- /*
151
- * Initial width
152
- */
153
- width: (...args) => {
154
- const [props] = args;
155
- // Required if resizing width or both
156
- if (props.axis === 'both' || props.axis === 'x') {
157
- return PropTypes.number.isRequired(...args);
158
- }
159
- return PropTypes.number(...args);
160
- },
161
- };
@@ -1,14 +0,0 @@
1
- // @flow
2
- import React from 'react';
3
- import type {Element as ReactElement} from 'react';
4
-
5
- // React.addons.cloneWithProps look-alike that merges style & className.
6
- export function cloneElement(element: ReactElement<any>, props: Object): ReactElement<any> {
7
- if (props.style && element.props.style) {
8
- props.style = {...element.props.style, ...props.style};
9
- }
10
- if (props.className && element.props.className) {
11
- props.className = `${element.props.className} ${props.className}`;
12
- }
13
- return React.cloneElement(element, props);
14
- }