Skip to content

Commit ab0bc4f

Browse files
committed
chore(release): prep 4.0.0 — changelog, readme, CI, integration tests
- CHANGELOG.md: add 4.0.0 entry covering the Flow->TS migration. Mark the types-delivery change as breaking and point Flow users at the last Flow-annotated source by SHA (db2e37e, the 3.2.0 tag). Backfill the missing 3.2.0 entry (PR #255 fix + ESLint pin). - README.md: new TypeScript section (bundled types ship from build/*.d.ts, remove @types/react-resizable). Flow-removal note with the same SHA link. Refresh lib/*.js references to *.tsx. Rewrite the Flow-flavored Props block in TypeScript. Compatibility table gains a Types column. - CI (.github/workflows/test.yml): now runs lint, typecheck, test, build, and a build-artifact smoke test on every push and PR. Bump checkout/ setup-node to v4 and add yarn caching. - __tests__/integration/smoke.cjs: plain CJS smoke test for the published shape — root entry resolves, named exports are constructible, defaultProps and propTypes preserved, bundled .d.ts files exist with expected symbols, legacy require()() guard throws, files whitelist correct. - __tests__/integration/end-to-end.test.tsx: 32 Jest integration tests driving real DOM events through DraggableCore. Same suite runs twice — against the TS source and against the built CJS root entry (gated on build/ existing). Covers drag-driven size changes, controlled-mode callbacks, the #255 regression (mid-drag prop staleness), zero-delta suppression, min/max constraints, lockAspectRatio, axis restrictions, transformScale, all 8 handle axes, and custom-function handles. Coverage on Resizable.tsx is now 98.76% lines, ResizableBox.tsx 100%.
1 parent c79b84b commit ab0bc4f

5 files changed

Lines changed: 651 additions & 33 deletions

File tree

.github/workflows/test.yml

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,28 @@ jobs:
1313
runs-on: ubuntu-latest
1414
steps:
1515
- name: Check out Git repository
16-
uses: actions/checkout@v2
16+
uses: actions/checkout@v4
1717

1818
- name: Set up Node.js
19-
uses: actions/setup-node@v2
19+
uses: actions/setup-node@v4
2020
with:
2121
node-version: 24
22+
cache: yarn
2223

2324
- name: Install Node.js dependencies
24-
run: yarn
25+
run: yarn install --frozen-lockfile
26+
27+
- name: Lint
28+
run: yarn lint
29+
30+
- name: Type-check
31+
run: yarn typecheck
2532

2633
- name: Run tests
2734
run: yarn test
35+
36+
- name: Build (verify .d.ts emission)
37+
run: yarn build
38+
39+
- name: Smoke-test built artifact
40+
run: node ./__tests__/integration/smoke.cjs

CHANGELOG.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,60 @@
11
# Changelog
22

3+
### 4.0.0 (May 12, 2026)
4+
5+
This release converts the library from Flow to TypeScript and ships bundled
6+
type declarations. The runtime API and on-screen behavior are unchanged. The
7+
major version bump is to flag two things consumers may need to act on.
8+
9+
**Breaking — types delivery**
10+
11+
- The library is now authored in TypeScript. Bundled type declarations ship
12+
in `build/*.d.ts` and are resolved via the `"types"` field in
13+
`package.json`. No `@types/react-resizable` install is needed; if you have
14+
one installed, remove it — TypeScript prefers the bundled types and the
15+
DefinitelyTyped package is no longer required.
16+
- The `*.js.flow` shims previously emitted by `build.sh` have been removed.
17+
Flow is no longer supported.
18+
19+
Flow users who still need types can copy the last Flow-annotated source
20+
from the `3.2.0` tag:
21+
[`react-grid-layout/react-resizable@db2e37e/lib`](https://github.com/react-grid-layout/react-resizable/tree/db2e37eda85fb21b1864e36b01c4922452f28418/lib)
22+
([`lib/Resizable.js`](https://github.com/react-grid-layout/react-resizable/blob/db2e37eda85fb21b1864e36b01c4922452f28418/lib/Resizable.js),
23+
[`lib/ResizableBox.js`](https://github.com/react-grid-layout/react-resizable/blob/db2e37eda85fb21b1864e36b01c4922452f28418/lib/ResizableBox.js),
24+
[`lib/propTypes.js`](https://github.com/react-grid-layout/react-resizable/blob/db2e37eda85fb21b1864e36b01c4922452f28418/lib/propTypes.js),
25+
[`lib/utils.js`](https://github.com/react-grid-layout/react-resizable/blob/db2e37eda85fb21b1864e36b01c4922452f28418/lib/utils.js)).
26+
These files were the input to the published `.js.flow` artifacts in
27+
`react-resizable@3.2.0` on npm; you can vendor them as a local Flow shim.
28+
They will not be updated, and any fix landing on `master` after `4.0.0`
29+
will not be backported into a Flow form.
30+
31+
**Internal**
32+
33+
- ✏ Chore: Migrate `lib/` and `__tests__/` from Flow to TypeScript
34+
(`*.ts`/`*.tsx`). Public runtime API unchanged.
35+
- ✏ Chore: Replace `@babel/preset-flow` with `@babel/preset-typescript`;
36+
drop `flow-bin`, `flow-typed/`, `.flowconfig`.
37+
- ✏ Chore: Add `tsconfig.json` (typecheck), `tsconfig.build.json`
38+
(declaration emit), `tsconfig.test.json`.
39+
- ✏ Chore: `build.sh` now runs `babel` for the JS transform and
40+
`tsc --emitDeclarationOnly` for the `.d.ts` files.
41+
- ✏ Chore: ESLint now uses `@typescript-eslint/parser`.
42+
- ✏ Chore: CI now runs `yarn lint`, `yarn typecheck`, `yarn test`, and a
43+
build-artifact smoke test on every push and PR.
44+
- ✏ Chore: Add an integration smoke test that imports the built CJS entry
45+
point and asserts the public surface (`Resizable`, `ResizableBox`).
46+
47+
### 3.2.0 (May 11, 2026)
48+
49+
- 🐛 Bugfix: Prevent resize drift caused by stale props between renders.
50+
The component now accumulates deltas from `lastSize` rather than
51+
`this.props.width/height`, and `dimensionsChanged` is compared against
52+
that same base so zero-delta callbacks are still suppressed correctly.
53+
[#255](https://github.com/react-grid-layout/react-resizable/pull/255)
54+
- ✏ Chore: Pin ESLint to `^9.x`. ESLint 10 removes `scopeManager.addGlobals`,
55+
which `@babel/eslint-parser` 7.x still calls; the parser fix is only
56+
available in unreleased v8 RCs that require an unreleased Babel core v8.
57+
358
### 3.1.3 (Jan 1, 2026)
459

560
- ✏ Chore: Add `files` whitelist to package.json to reduce package size and exclude unnecessary files.

README.md

Lines changed: 73 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ A simple widget that can be resized via one or more handles.
1111
You can either use the `<Resizable>` element directly, or use the much simpler `<ResizableBox>` element.
1212

1313
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.
1515

1616
## Table of Contents
1717

1818
- [Installation](#installation)
19+
- [TypeScript](#typescript)
1920
- [Compatibility](#compatibility)
2021
- [Usage](#usage)
2122
- [Resizable](#resizable)
@@ -47,20 +48,59 @@ Or import it in your CSS:
4748

4849
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.
4950

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+
5089
## Compatibility
5190

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 |
5797

5898
## Usage
5999

60100
This package has two major exports:
61101

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.
64104

65105
### `<Resizable>`
66106

@@ -124,43 +164,46 @@ class Example extends React.Component {
124164

125165
These props apply to both `<Resizable>` and `<ResizableBox>`. Unknown props that are not in the list below will be passed to the child component.
126166

127-
```js
167+
```ts
128168
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;
132172
};
133173

134174
type ResizeHandleAxis = 's' | 'w' | 'e' | 'n' | 'sw' | 'nw' | 'se' | 'ne';
135175

136176
type ResizableProps = {
137-
children: React.Element<any>,
138-
width: number,
139-
height: number,
177+
children: React.ReactElement<any>;
178+
width: number;
179+
height: number;
140180
// Either a ReactElement to be used as handle, or a function
141181
// 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']
154197
// If `transform: scale(n)` is set on the parent, this should be set to `n`.
155-
transformScale?: number = 1
198+
transformScale?: number; // default: 1
156199
};
157200
```
158201

159202
The following props can also be used on `<ResizableBox>`:
160203

161-
```js
204+
```ts
162205
{
163-
style?: Object // styles the returned <div />
206+
style?: React.CSSProperties; // styles the returned <div />
164207
}
165208
```
166209

0 commit comments

Comments
 (0)