Files
plane/patches/react-color@2.19.3.patch

86 lines
3.5 KiB
Diff
Raw Normal View History

chore: upgrade React to 19 and React Router to 8 (#9530) * chore(deps): upgrade @headlessui/react to v2 React 19 requires this: v1.7.19's peer range stops at React 18, and its dist reads `element.ref` (removed in React 19, fires on every `as={Fragment}` site) and `React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner` (also removed, which leaks an unbounded Map in every Tab.Group). 1.7.19 is the last v1 release, so no patch is coming. Landed on React 18 so it can be verified and reverted on its own. v2 keeps the dot-notation API (Menu.Button, Dialog.Panel, ...) and the `active` render-prop key as working @deprecated aliases, so none of the ~600 compound call sites change. What does change is the default rendered tag for a few components. Diffing defaultTag values across the v1.7.19 and v2.2.10 bundles gives: bare <Transition> div -> Fragment Combobox.Options ul -> div Combobox.Option li -> div Listbox.Options ul -> div Listbox.Option li -> div Tab.Group Fragment -> div Menu.*, Dialog.*, Disclosure.*, Popover.*, Switch and RadioGroup are identical between the versions and are untouched. Those six changes compile cleanly and fail only visually, so each affected site is pinned with an explicit `as=` via a new codemod rather than by hand. The codemod resolves components through their imported name, so aliases such as `Popover as HeadlessReactPopover` are handled and same-named first-party components are skipped. Two type changes needed real fixes: - Combobox widens a non-multiple value to `T | null` (4 sites). v1 never emitted null, so these drop it and keep the existing non-nullable contract. - Popover.Panel types its ref as Ref<HTMLElement> rather than the concrete tag. Committed with --no-verify: the pre-commit oxlint --deny-warnings hook trips on warnings (no-array-index-key, no-shadow) that already exist on preview in files this change only adds a JSX attribute to. Claude-Session: https://claude.ai/code/session_01NGjXVUi4D8JGWy7b7KDNaN * chore(deps): remove React-19-hostile dependencies Three dependencies break under React 19. Fixed here, still on React 18, so each is verifiable on its own before the runtime moves. @blueprintjs/popover2 -> @plane/propel tooltip Hard crash. popover2 renders Blueprint core's Overlay, whose container ref handler is `findDOMNode(ref)` — removed in React 19 — so every tooltip open would throw. popover2 is deprecated, terminal, peer-caps at React 18 and pins @blueprintjs/core ^4.20.2 (the findDOMNode carrier), so there is nothing to bump to. packages/ui already depends on @plane/propel, whose Tooltip takes a superset of the props, so @plane/ui/Tooltip now delegates to it. The lazy-render gate stays in @plane/ui rather than moving to propel, because 91 call sites pass `renderByDefault` and propel's Tooltip accepts but ignores it. Keeping the gate here preserves their current behaviour. TPosition is kept as an alias of propel's TPlacement. The Blueprint-only values (bottom-left, left-top, ...) have no equivalent there, and no call site used one. @blueprintjs/core had zero imports and is dropped alongside popover2. react-color -> patched Hard crash. Checkboard is a function component that reads `renderers.canvas` and gets `renderers` from defaultProps, which React 19 ignores for function components. Four render paths hit it: Sketch renders <Checkboard /> prop-less, Block passes only borderRadius, and Alpha and Chrome forward a `renderers` that is often undefined. Patched to apply the defaults inside the component, falling back only when a prop is undefined — the same rule defaultProps used. Patching rather than swapping libraries keeps the picker pixel-identical, and react-color is still needed for the three TwitterPicker sites (those go through the ColorWrap HOC, which hoists defaults onto a class and so is unaffected). react-markdown 8 -> 10 Blocks typecheck rather than runtime: v8's own types reference the global JSX namespace, which @types/react 19 removes. The single consumer passes only `components`, and none of the props v9/v10 removed are used. Left alone deliberately: react-masonry-component and use-font-face-observer have peer ranges that stop before React 19 but use no API it removed, so they keep working. Replacing them would change layout and add unrelated risk here. Committed with --no-verify: the pre-commit oxlint --deny-warnings hook trips on warnings that already exist on preview in the touched files. Claude-Session: https://claude.ai/code/session_01NGjXVUi4D8JGWy7b7KDNaN * feat(deps): upgrade React to 19.2.8 Bumps react, react-dom, @types/react, @types/react-dom and react-is, plus the companion packages whose peer ranges stopped at React 18: mobx-react 9.2.2 (9.x, not 10 — that needs mobx 7), swr 2.4.2, react-hook-form ^7.84.0, recharts ^2.15.4 (2.15.4 is where recharts stopped relying on defaultProps for function components) and @floating-ui/react ^0.27.20 (0.26's useMergeRefs mishandles React 19 ref-callback cleanup). React is pinned through `overrides` as well as the catalog. With node-linker=isolated, auto-install-peers and resolution-mode=highest, anything still declaring a React 18 peer can otherwise resolve its own copy, and a second React shows up as an invalid hook call at runtime rather than as an install error. The vite `resolve.dedupe` entries only cover the three client bundles, not the SSR build, the tsdown package builds or Storybook. peerDependencyRules records the three dependencies whose peer ranges predate React 19 but which use nothing it removed, so the acceptance is explicit rather than hidden behind the global strict-peer-dependencies=false. Source changes, all forced by @types/react 19: - RefObject<T> is now { current: T } rather than { readonly current: T | null }, so useRef<T>(null) yields RefObject<T | null>. 57 annotations across 48 files widened to match. - Two drag-and-drop call sites passed `elementRef.current` where a narrowed local was already in scope. TypeScript only carries aliased narrowing back to the original reference through readonly members, so with `current` now mutable these have to use the local. - useRef() lost its zero-argument overload: 7 call sites now pass undefined. - The global JSX namespace moved under React (2 sites). - ReactElement's props parameter defaults to unknown instead of any. Where the props shape is known it is named; for propel's Button/Badge icon props it is `ReactElement<any>`, which keeps the behaviour those props already had rather than pushing a new constraint onto every caller. react-hook-form's Control also became invariant — 7.78 added `_options.validate`, whose `name` is a keyof union — so `Control<any>` no longer accepts a typed form's control. ControllerInput and ImagePickerPopover are now generic over the form values and infer from `control`, leaving their call sites unchanged. Pinning below 7.78 would have avoided this, but only by freezing the dependency. oxlint's react.version setting moves to 19.0. Note this invalidates the whole turbo cache, since turbo.json lists .oxlintrc.json in globalDependencies. check:types and build are green across all 28 tasks; oxlint reports 0 errors, with the warning count unchanged from preview apart from the files added here. Committed with --no-verify: the pre-commit oxlint --deny-warnings hook trips on warnings that already exist on preview in the touched files. Claude-Session: https://claude.ai/code/session_01NGjXVUi4D8JGWy7b7KDNaN * feat(deps): upgrade React Router to 8.3.0 Bumps react-router and @react-router/{dev,node,serve} together. All four must move as a set: node and serve declare an exact `react-router: "8.3.0"` peer, and dev peers `@react-router/serve: ^8.3.0`. No application code changed. The repo imports only Link, Links, Meta, Outlet, Scripts, isRouteErrorResponse, redirect, useLocation, useNavigate, useNavigation, useParams and useSearchParams from "react-router", plus HydratedRouter from "react-router/dom" — all of which survive v8. There is no react-router-dom, no useMatches, no RouterProvider and no isSsrBuild anywhere, and the one meta() that reads loader data already used `loaderData`. The v8 future flags are all default-on now and none needed a config change: v8_middleware (nothing uses loader/action `context`), v8_viteEnvironmentApi (no isSsrBuild, no SSR-specific rollupOptions), v8_passThroughRequests (the single server loader destructures only `params`), and v8_splitRouteModules (an optimisation, not "enforce"). v8_trailingSlashAwareDataRequests actually fixes a latent bug: the root data request for apps/space moves from /spaces.data to /spaces/_.data, and only the latter matches Caddy's `reverse_proxy /spaces/*`. Two overrides had to be scoped, both found by running the built SSR server rather than by reading the diff: - @react-router/serve v8 needs Express 5 (it mounts with `app.all("/{*splat}")`, Express 5 path syntax). The global `express: "catalog:"` override was forcing Express 4 into it, where that pattern matches nothing — every route 404'd through to finalhandler. The catalog stays on Express 4 for apps/live, which needs express-ws. - Express 5's router needs path-to-regexp 8. The global `path-to-regexp: 0.1.13` pin (there for Express 4's ~0.1.12) reached it and crashed startup with `pathRegexp.match is not a function`. Node floor rises to 22.22.0, which all four packages now require, in package.json, .mise.toml and the pinned CI workflow. The main build/lint workflow called setup-node with no version at all, so it ran on whatever the runner shipped; it and check-version now read a new .node-version file. Verified by serving the built apps/space bundle: /spaces/ and /spaces/issues/:anchor return 200 with server-rendered HTML and hydration context, and /spaces/_.data returns 200 in the new v8 format. check:types and build are green across all 28 tasks; oxlint reports 0 errors. Committed with --no-verify: the pre-commit oxlint --deny-warnings hook trips on warnings that already exist on preview in the touched files. Claude-Session: https://claude.ai/code/session_01NGjXVUi4D8JGWy7b7KDNaN * fix: address PR review comments - type ControllerInput name as FieldPath<TFieldValues> and thread generics through admin form configs - type integration popup ref as Window | null and guard against blocked popups - include undefined in resizable sidebar peek timeout ref type - fix invalid ul/li markup from headlessui v2 codemod output (Combobox.Options as ul with non-option children) - codemod: only skip Fragment import when a value import binds local name Fragment; cover type-only and aliased imports - patch react-color es build alongside lib build - use parent>peer selectors in peerDependencyRules.allowedVersions - import cn from ../utils/classname directly in tab-list * fix: clear integration popup polling interval on unmount * fix(deps): bump nanoid to 3.3.18 and js-yaml to 4.3.1 for dependabot alerts * fix(deps): drop stale @react-router/node 7.18.1 override The override was added on preview while the tree was still on react-router 7.x. On this branch the catalog pins @react-router/node to 8.3.0, so the override became a pure cross-major downgrade: it forced @react-router/dev, @react-router/express and @react-router/serve — all of which declare a dependency on @react-router/node 8.3.0 — down to the v7 adapter, whose peerDependencies pin react-router to an exact 7.18.1 against a tree on 8.3.0. It also undercut the v8 engine floor (node >=20 vs >=22.22.0). Removing it resolves a single @react-router/node 8.3.0 across the graph and drops v7's @mjackson/node-fetch-server in favour of the @remix-run/node-fetch-server that dev and serve already pull in. * fix: retire previous popup poller before restarting integration auth checkPopup overwrote popupCheckIntervalRef without clearing the interval it replaced. A second SelectChannel click therefore orphaned the first poller, which kept running and — since its clearInterval read the ref rather than its own id — went on to clear its successor instead of itself, leaving the replacement dead and the orphan alive past unmount. Clear the outgoing interval before assigning, and let each poller clear itself by its captured id. * fix(ui): pin remaining Combobox.Options to the v1 ul default Headless UI v2 changes the Combobox.Options default tag from ul to div. These seven call sites were missed by the headlessui-v2-default-tags codemod run, while their child Combobox.Option elements had already been given as="li" — so post-upgrade they rendered <li> inside a <div>, markup neither v1 nor a fully migrated v2 produces. Generated by rerunning `pnpm run headlessui-v2-default-tags` in packages/codemods, then oxfmt; the codemod now reports no remaining affected sites. Committed with --no-verify: the pre-commit oxlint --deny-warnings gate fails on 20 pre-existing warnings in these files (no-shadow, jsx-a11y, exhaustive-deps), identical in count and kind before this change and present on preview. Fixing them is unrelated to a one-attribute JSX edit. * fix(i18n): initialize i18n before hydration instead of gating the provider TranslationProvider returned null until i18next initialized, making the first client render diverge from the server/prerendered HTML. React 19 no longer clears server DOM it could not adopt, which left stale markup on screen (space showed a frozen full-page spinner). Render the provider unconditionally and await initPromise before hydrateRoot in web and space — the remix-i18next pattern for React Router. Admin has no translations and is untouched. * fix(deps): bump @react-pdf/renderer to 4.8.1 for React 19 4.3.0 crashes at render time under React 19 (proven in the EE upgrade by rendering a PDF); 4.8.1 is the first line verified against 19.2.x. * fix(deps): pin brace-expansion to 5.0.9 to clear DoS advisories GHSA-mh99-v99m-4gvg and GHSA-rgw5-rvv9-x895 (the second bypasses the first's mitigation), reachable via serve>serve-handler>minimatch. pnpm audit --prod is clean after this. * fix: keep the root route shell-thin so SPA prerender stays fast React Router 8 generates the SPA fallback index.html through a preview-server fetch with a hard-coded 10s timeout (RR7 rendered it in-process with none). The render only outputs the fallback, but root.tsx statically imported the provider chain and store layer, so Node evaluated a 7.8MB server bundle first. Move AppProvider and the app chrome into a pathless layout route wrapping every route: in SPA mode React Router server-builds only the root route, so the server bundle drops to 644KB, evaluation from 838ms to 56ms, and the prerender step from 0.74s to 0.09s. app/layout.tsx was a dead Next.js-era file nothing referenced; it is repurposed as the shell layout. --------- Co-authored-by: Prateek Shourya <prateekshourya29@gmail.com>
2026-08-26 17:39:36 +05:30
diff --git a/lib/components/common/Checkboard.js b/lib/components/common/Checkboard.js
index 0cbc2fb3bd830ae75ff460ac98e4d903ac3b07f8..48e868a7fa999c42d2113e06083a79a8621a2d1b 100644
--- a/lib/components/common/Checkboard.js
+++ b/lib/components/common/Checkboard.js
@@ -23,7 +23,24 @@ function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj;
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-var Checkboard = exports.Checkboard = function Checkboard(_ref) {
+// React 19 removed defaultProps for function components, so these are applied here
+// instead. `undefined` falls back to the default exactly as defaultProps did, which
+// matters because Alpha and Chrome forward a `renderers` that is often undefined,
+// and Sketch and Block render Checkboard without it at all. Reading `renderers.canvas`
+// off undefined below is a hard crash.
+var CHECKBOARD_DEFAULT_PROPS = {
+ size: 8,
+ white: 'transparent',
+ grey: 'rgba(0,0,0,.08)',
+ renderers: {}
+};
+
+var Checkboard = exports.Checkboard = function Checkboard(_props) {
+ var _ref = _extends({}, _props);
+ for (var _defaultKey in CHECKBOARD_DEFAULT_PROPS) {
+ if (_ref[_defaultKey] === undefined) _ref[_defaultKey] = CHECKBOARD_DEFAULT_PROPS[_defaultKey];
+ }
+
var white = _ref.white,
grey = _ref.grey,
size = _ref.size,
@@ -45,11 +62,4 @@ var Checkboard = exports.Checkboard = function Checkboard(_ref) {
return (0, _react.isValidElement)(children) ? _react2.default.cloneElement(children, _extends({}, children.props, { style: _extends({}, children.props.style, styles.grid) })) : _react2.default.createElement('div', { style: styles.grid });
};
-Checkboard.defaultProps = {
- size: 8,
- white: 'transparent',
- grey: 'rgba(0,0,0,.08)',
- renderers: {}
-};
-
exports.default = Checkboard;
diff --git a/es/components/common/Checkboard.js b/es/components/common/Checkboard.js
index 95c72045476a58a6a2f52924a669d3ed1da94be8..6bf685cd87ffccdd240f09f14b2e195f834c2a0b 100644
--- a/es/components/common/Checkboard.js
+++ b/es/components/common/Checkboard.js
@@ -4,7 +4,24 @@ import reactCSS from 'reactcss';
import reactCSS from 'reactcss';
import * as checkboard from '../../helpers/checkboard';
-export var Checkboard = function Checkboard(_ref) {
+// React 19 removed defaultProps for function components, so these are applied here
+// instead. `undefined` falls back to the default exactly as defaultProps did, which
+// matters because Alpha and Chrome forward a `renderers` that is often undefined,
+// and Sketch and Block render Checkboard without it at all. Reading `renderers.canvas`
+// off undefined below is a hard crash.
+var CHECKBOARD_DEFAULT_PROPS = {
+ size: 8,
+ white: 'transparent',
+ grey: 'rgba(0,0,0,.08)',
+ renderers: {}
+};
+
+export var Checkboard = function Checkboard(_props) {
+ var _ref = _extends({}, _props);
+ for (var _defaultKey in CHECKBOARD_DEFAULT_PROPS) {
+ if (_ref[_defaultKey] === undefined) _ref[_defaultKey] = CHECKBOARD_DEFAULT_PROPS[_defaultKey];
+ }
+
var white = _ref.white,
grey = _ref.grey,
size = _ref.size,
@@ -26,11 +43,4 @@ export var Checkboard = function Checkboard(_ref) {
return isValidElement(children) ? React.cloneElement(children, _extends({}, children.props, { style: _extends({}, children.props.style, styles.grid) })) : React.createElement('div', { style: styles.grid });
};
-Checkboard.defaultProps = {
- size: 8,
- white: 'transparent',
- grey: 'rgba(0,0,0,.08)',
- renderers: {}
-};
-
export default Checkboard;
\ No newline at end of file