Skip to content

Commit 995442c

Browse files
authored
Replace react-beautiful-dnd with @hello-pangea/dnd (#4410)
Swaps the now-archived `react-beautiful-dnd` for [`@hello-pangea/dnd`](https://github.com/hello-pangea/dnd), its maintained, API-compatible fork. Addresses #3918. ## Why - **Retires an abandoned dependency.** `react-beautiful-dnd` was archived in April 2025 and will receive no further updates — security or otherwise. `@hello-pangea/dnd` is the actively-maintained continuation with an identical API. - **Unblocks React 19.** `@hello-pangea/dnd` 18.0 officially declares support for `react@^18 || ^19`. The old package is capped at React 18, making it one of the hard blockers for an eventual React 19 upgrade. - **Shrinks the dependency tree.** `@hello-pangea/dnd` drops the `react-redux`/`redux` subtree that `react-beautiful-dnd` carried (net ~30 fewer lines in `yarn.lock`). - **Supply-chain hygiene, not a CVE fix.** `yarn audit` currently reports 0 vulnerabilities — this is preventative risk reduction (removing a frozen dependency before a future CVE lands in it), not an active-vulnerability patch. React 19 itself is *not* claimed as a security improvement here. ## Changes - Replaced the `react-beautiful-dnd` dependency with `@hello-pangea/dnd` `^18.0.1`. - Repointed the kit re-export (`kit/react-beautiful-dnd/index.ts`) at the new package. The runtime API is identical, so the **four consumers are untouched**: desktop & mobile `GroupingChooser`, desktop `DynamicTabSwitcher`, and mobile `ColChooser`. - One small type adjustment: `@hello-pangea/dnd` types `DragDropContext`'s `children` as *required* (the old bundled `@types` had it optional). Our `dragDropContext` call sites pass content via the element factory's `item` alias rather than a literal `children` key, so the kit marks `children` optional on just that factory's spec — via `SetOptional<DragDropContextProps, 'children'>` (type-fest), the existing Hoist idiom for this. `droppable`/`draggable` are unchanged; they take a required `children` render-prop supplied directly at every call site. ## Note — possibly a temporary step This is deliberately a low-churn, drop-in swap to remove the dead dependency and unblock React 19 **now**, independent of any larger migration. `@hello-pangea/dnd` is itself a community maintenance fork rather than a strategically-funded library. If we later decide to move off the `react-beautiful-dnd` lineage entirely (e.g. to Atlassian's [Pragmatic drag-and-drop](https://atlassian.design/components/pragmatic-drag-and-drop/)), the kit remains the single integration point to revisit. The kit directory name was intentionally left as-is to keep this diff minimal. ## Testing - `npx tsc --noEmit` — clean. - `yarn lint` — clean. - Smoke-tested in Toolbox (via `startWithHoist` / `inlineHoist`, compiling Hoist from source): - **Desktop** — confirmed `@hello-pangea/dnd` is the live library (DOM uses its `data-rfd-*` namespace; the old `data-rbd-*` namespace is gone). `GroupingChooser` reorders correctly via `onDragEnd` (verified a drag flipping `City › Win/Lose` → `Win/Lose › City`, with the grid re-grouping to match). `DynamicTabSwitcher` mounts and renders its tabs as draggables. No console errors. - **Mobile** — drag-and-drop verified working as-is.
1 parent d7c45d0 commit 995442c

4 files changed

Lines changed: 47 additions & 67 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@
123123
* Was included due to golden-layouts consumer, which now no longer needs the library.
124124
* Apps with previously required `"jquery": "3.x"` pin in package.json `resolutions` should now
125125
be able to remove that pin.
126+
* react-beautiful-dnd `removed`
127+
* Replaced by `@hello-pangea/dnd` 18.0, a maintained, React 19-ready, drop-in fork. The
128+
now-archived `react-beautiful-dnd` will receive no further updates. No Hoist or app API
129+
changes - drag-and-drop behavior is unchanged.
126130
* react-dropzone `10.x → 15.x`
127131
* See the `FileChooser` redesign note under Breaking Changes above.
128132
* react-select `4.3 → 5.10`

kit/react-beautiful-dnd/index.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,16 @@
55
* Copyright © 2026 Extremely Heavy Industries Inc.
66
*/
77
import {elementFactory} from '@xh/hoist/core';
8-
import {DragDropContext, Draggable, Droppable} from 'react-beautiful-dnd';
8+
import {SetOptional} from 'type-fest';
99

10-
export {DragDropContext, Droppable, Draggable};
1110

12-
export const dragDropContext = elementFactory(DragDropContext),
13-
droppable = elementFactory(Droppable),
11+
// Sourced from @hello-pangea/dnd, a maintained, React 19-ready, drop-in fork of the now-archived
12+
// react-beautiful-dnd. The runtime API is identical, except for type tweak to children below.
13+
import {DragDropContext, DragDropContextProps, Draggable, Droppable} from '@hello-pangea/dnd';
14+
15+
16+
export {DragDropContext, Droppable, Draggable};
17+
export const droppable = elementFactory(Droppable),
1418
draggable = elementFactory(Draggable);
19+
export const dragDropContext =
20+
elementFactory<SetOptional<DragDropContextProps, 'children'>>(DragDropContext);

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"@fortawesome/pro-solid-svg-icons": "^7.2.0",
5656
"@fortawesome/pro-thin-svg-icons": "^7.2.0",
5757
"@fortawesome/react-fontawesome": "^3.2.0",
58+
"@hello-pangea/dnd": "^18.0.1",
5859
"@modelcontextprotocol/sdk": "^1.26.0",
5960
"@uiw/codemirror-theme-github": "~4.25.10",
6061
"classnames": "~2.5.1",
@@ -74,7 +75,6 @@
7475
"numbro": "~2.5.0",
7576
"onsenui": "~2.12.8",
7677
"qs": "~6.15.0",
77-
"react-beautiful-dnd": "~13.1.0",
7878
"react-dates": "~21.8.0",
7979
"react-dropzone": "~15.0.0",
8080
"react-grid-layout": "~2.2.3",

yarn.lock

Lines changed: 32 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -906,7 +906,7 @@
906906
"@babel/plugin-transform-modules-commonjs" "^7.29.7"
907907
"@babel/plugin-transform-typescript" "^7.29.7"
908908

909-
"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.18.3", "@babel/runtime@^7.21.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
909+
"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.21.0", "@babel/runtime@^7.26.7", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7":
910910
version "7.29.7"
911911
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.29.7.tgz#12022450c45a4da6d8d8287b18a4ff2ddb23f768"
912912
integrity sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==
@@ -1806,6 +1806,17 @@
18061806
resolved "https://npm.fontawesome.com/@fortawesome/react-fontawesome/-/react-fontawesome-3.3.1.tgz#7fb1d1f4b48a15b9c6c4d88d579dacc478ebf3ef"
18071807
integrity sha512-wGnAPhfzivDwBWYmEG8MSrEXPruoiMMo48NnsRkj1NZkoaawgOijPNAiSHKMYEoCsqTBSgLTzL6EqTTWGaUR4w==
18081808

1809+
"@hello-pangea/dnd@^18.0.1":
1810+
version "18.0.1"
1811+
resolved "https://registry.yarnpkg.com/@hello-pangea/dnd/-/dnd-18.0.1.tgz#7d5ef7fe8bddf195307b16e03635b1be582b7b8d"
1812+
integrity sha512-xojVWG8s/TGrKT1fC8K2tIWeejJYTAeJuj36zM//yEm/ZrnZUSFGS15BpO+jGZT1ybWvyXmeDJwPYb4dhWlbZQ==
1813+
dependencies:
1814+
"@babel/runtime" "^7.26.7"
1815+
css-box-model "^1.2.1"
1816+
raf-schd "^4.0.3"
1817+
react-redux "^9.2.0"
1818+
redux "^5.0.1"
1819+
18091820
"@hono/node-server@^1.19.9":
18101821
version "1.19.14"
18111822
resolved "https://registry.yarnpkg.com/@hono/node-server/-/node-server-1.19.14.tgz#e30f844bc77e3ce7be442aac3b1f73ad8b58d181"
@@ -2641,13 +2652,6 @@
26412652
dependencies:
26422653
"@types/unist" "*"
26432654

2644-
"@types/hoist-non-react-statics@^3.3.0":
2645-
version "3.3.7"
2646-
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.7.tgz#306e3a3a73828522efa1341159da4846e7573a6c"
2647-
integrity sha512-PQTyIulDkIDro8P+IHbKCsw7U2xxBYflVzW/FgWdCAePD9xGSidgA76/GeJ6lBKoblyhf9pBY763gbrN+1dI8g==
2648-
dependencies:
2649-
hoist-non-react-statics "^3.3.0"
2650-
26512655
"@types/html-minifier-terser@^6.0.0":
26522656
version "6.1.0"
26532657
resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35"
@@ -2724,22 +2728,12 @@
27242728
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.7.tgz#b89ddf2cd83b4feafcc4e2ea41afdfb95a0d194f"
27252729
integrity sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==
27262730

2727-
"@types/react-redux@^7.1.20":
2728-
version "7.1.34"
2729-
resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.34.tgz#83613e1957c481521e6776beeac4fd506d11bd0e"
2730-
integrity sha512-GdFaVjEbYv4Fthm2ZLvj1VSCedV7TqE5y1kNwnjSdBOTXuRSgowux6J8TAct15T3CKBr63UMk+2CO7ilRhyrAQ==
2731-
dependencies:
2732-
"@types/hoist-non-react-statics" "^3.3.0"
2733-
"@types/react" "*"
2734-
hoist-non-react-statics "^3.3.0"
2735-
redux "^4.0.0"
2736-
27372731
"@types/react-transition-group@^4.4.0":
27382732
version "4.4.12"
27392733
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.12.tgz#b5d76568485b02a307238270bfe96cb51ee2a044"
27402734
integrity sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==
27412735

2742-
"@types/react@*", "@types/react@18.x":
2736+
"@types/react@18.x":
27432737
version "18.3.30"
27442738
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.30.tgz#e915809a3fb2bf752361d356b821bc754697e3cd"
27452739
integrity sha512-3ek6mwJL5/VBewBcY4S66cqlCtK3qi4WIq37Z0m/NHw1hjhI7274Mx1qz/+ggSzyBCOEf7eHjBN6INjPAWYfYw==
@@ -2813,6 +2807,11 @@
28132807
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.11.tgz#11af57b127e32487774841f7a4e54eab166d03c4"
28142808
integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==
28152809

2810+
"@types/use-sync-external-store@^0.0.6":
2811+
version "0.0.6"
2812+
resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz#60be8d21baab8c305132eb9cb912ed497852aadc"
2813+
integrity sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==
2814+
28162815
"@types/ws@^8.5.10":
28172816
version "8.18.1"
28182817
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9"
@@ -4125,7 +4124,7 @@ cross-spawn@^7.0.5, cross-spawn@^7.0.6:
41254124
shebang-command "^2.0.0"
41264125
which "^2.0.1"
41274126

4128-
css-box-model@^1.2.0:
4127+
css-box-model@^1.2.1:
41294128
version "1.2.1"
41304129
resolved "https://registry.yarnpkg.com/css-box-model/-/css-box-model-1.2.1.tgz#59951d3b81fd6b2074a62d49444415b0d2b4d7c1"
41314130
integrity sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==
@@ -5514,7 +5513,7 @@ header-case@^2.0.4:
55145513
capital-case "^1.0.4"
55155514
tslib "^2.0.3"
55165515

5517-
hoist-non-react-statics@^3.2.1, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2:
5516+
hoist-non-react-statics@^3.2.1, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2:
55185517
version "3.3.2"
55195518
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
55205519
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
@@ -6622,7 +6621,7 @@ memfs@^4.43.1:
66226621
tree-dump "^1.0.3"
66236622
tslib "^2.0.0"
66246623

6625-
"memoize-one@>=3.1.1 <6", memoize-one@^5.1.1:
6624+
"memoize-one@>=3.1.1 <6":
66266625
version "5.2.1"
66276626
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e"
66286627
integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==
@@ -7668,7 +7667,7 @@ queue-microtask@^1.2.2:
76687667
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
76697668
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
76707669

7671-
raf-schd@^4.0.2:
7670+
raf-schd@^4.0.3:
76727671
version "4.0.3"
76737672
resolved "https://registry.yarnpkg.com/raf-schd/-/raf-schd-4.0.3.tgz#5d6c34ef46f8b2a0e880a8fcdb743efc5bfdbc1a"
76747673
integrity sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==
@@ -7705,19 +7704,6 @@ raw-body@~2.5.3:
77057704
iconv-lite "~0.4.24"
77067705
unpipe "~1.0.0"
77077706

7708-
react-beautiful-dnd@~13.1.0:
7709-
version "13.1.1"
7710-
resolved "https://registry.yarnpkg.com/react-beautiful-dnd/-/react-beautiful-dnd-13.1.1.tgz#b0f3087a5840920abf8bb2325f1ffa46d8c4d0a2"
7711-
integrity sha512-0Lvs4tq2VcrEjEgDXHjT98r+63drkKEgqyxdA7qD3mvKwga6a5SscbdLPO2IExotU1jW8L0Ksdl0Cj2AF67nPQ==
7712-
dependencies:
7713-
"@babel/runtime" "^7.9.2"
7714-
css-box-model "^1.2.0"
7715-
memoize-one "^5.1.1"
7716-
raf-schd "^4.0.2"
7717-
react-redux "^7.2.0"
7718-
redux "^4.0.4"
7719-
use-memo-one "^1.1.1"
7720-
77217707
react-dates@~21.8.0:
77227708
version "21.8.0"
77237709
resolved "https://registry.yarnpkg.com/react-dates/-/react-dates-21.8.0.tgz#355c3c7a243a7c29568fe00aca96231e171a5e94"
@@ -7796,11 +7782,6 @@ react-is@^16.13.1, react-is@^16.7.0:
77967782
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
77977783
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
77987784

7799-
react-is@^17.0.2:
7800-
version "17.0.2"
7801-
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
7802-
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
7803-
78047785
react-markdown@~10.1.0:
78057786
version "10.1.0"
78067787
resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-10.1.0.tgz#e22bc20faddbc07605c15284255653c0f3bad5ca"
@@ -7858,17 +7839,13 @@ react-portal@^4.2.0:
78587839
dependencies:
78597840
prop-types "^15.5.8"
78607841

7861-
react-redux@^7.2.0:
7862-
version "7.2.9"
7863-
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.9.tgz#09488fbb9416a4efe3735b7235055442b042481d"
7864-
integrity sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==
7842+
react-redux@^9.2.0:
7843+
version "9.3.0"
7844+
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-9.3.0.tgz#a30113bb6d95c0a715d54dda4308d450fca6ce09"
7845+
integrity sha512-KQopgqFo/p/fgmAs5qz6p5RWaNAzq40WAu7fJIXnQpYxFPbJYtsJPWvGeF2rOBaY/kEuV77AVsX8TsQzKm+A/g==
78657846
dependencies:
7866-
"@babel/runtime" "^7.15.4"
7867-
"@types/react-redux" "^7.1.20"
7868-
hoist-non-react-statics "^3.3.2"
7869-
loose-envify "^1.4.0"
7870-
prop-types "^15.7.2"
7871-
react-is "^17.0.2"
7847+
"@types/use-sync-external-store" "^0.0.6"
7848+
use-sync-external-store "^1.4.0"
78727849

78737850
react-resizable@^3.1.3:
78747851
version "3.2.0"
@@ -8005,12 +7982,10 @@ rechoir@^0.8.0:
80057982
dependencies:
80067983
resolve "^1.20.0"
80077984

8008-
redux@^4.0.0, redux@^4.0.4:
8009-
version "4.2.1"
8010-
resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.1.tgz#c08f4306826c49b5e9dc901dee0452ea8fce6197"
8011-
integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==
8012-
dependencies:
8013-
"@babel/runtime" "^7.9.2"
7985+
redux@^5.0.1:
7986+
version "5.0.1"
7987+
resolved "https://registry.yarnpkg.com/redux/-/redux-5.0.1.tgz#97fa26881ce5746500125585d5642c77b6e9447b"
7988+
integrity sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==
80147989

80157990
reflect-metadata@^0.2.2:
80167991
version "0.2.2"
@@ -9575,11 +9550,6 @@ use-isomorphic-layout-effect@^1.2.0:
95759550
resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.1.tgz#2f11a525628f56424521c748feabc2ffcc962fce"
95769551
integrity sha512-tpZZ+EX0gaghDAiFR37hj5MgY6ZN55kLiPkJsKxBMZ6GZdOSPJXiOzPM984oPYZ5AnehYx5WQp1+ME8I/P/pRA==
95779552

9578-
use-memo-one@^1.1.1:
9579-
version "1.1.3"
9580-
resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.3.tgz#2fd2e43a2169eabc7496960ace8c79efef975e99"
9581-
integrity sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==
9582-
95839553
use-sync-external-store@^1.4.0:
95849554
version "1.6.0"
95859555
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz#b174bfa65cb2b526732d9f2ac0a408027876f32d"

0 commit comments

Comments
 (0)