Skip to content

feat: React19 and HDSv6 migration HCRC-196#265

Merged
mikkojamG merged 4 commits into
mainfrom
feat/HCRC-197-react-19-hds-6-migration
Jul 9, 2026
Merged

feat: React19 and HDSv6 migration HCRC-196#265
mikkojamG merged 4 commits into
mainfrom
feat/HCRC-197-react-19-hds-6-migration

Conversation

@Riippi

@Riippi Riippi commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Description

Reacr 19 and HDS 6 update.

https://helsinkisolutionoffice.atlassian.net/browse/HCRC-196

Summary by CodeRabbit

  • Chores
    • Updated support for React 19 and Node.js 24
    • Upgraded HDS design system components to latest versions
    • Simplified internal context provider implementations
    • Refactored ref handling in link components for improved compatibility

@Riippi Riippi requested a review from a team as a code owner June 15, 2026 13:55
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7fa8998e-cc65-4777-bb79-778d095bb649

📥 Commits

Reviewing files that changed from the base of the PR and between 83757da and 226d740.

📒 Files selected for processing (3)
  • eslint.config.mjs
  • package.json
  • src/core/utils/__tests__/recursiveMap.test.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • package.json
  • src/core/utils/tests/recursiveMap.test.tsx

📝 Walkthrough

Walkthrough

Upgrades the package to React 19 and HDS React 6. All context providers are migrated from Context.Provider JSX to the React 19 direct-context pattern. LinkBase drops forwardRef in favor of native ref-in-props. All JSX.Element type annotations are replaced with React.JSX.Element. Utility functions are updated for React 19 type compatibility.

Changes

React 19 and HDS 6 Upgrade

Layer / File(s) Summary
Dependency version bumps and ESLint config
package.json, eslint.config.mjs
engines.node set to ^24; peerDependencies updated to React 19 and hds-react ^6.0.2; devDependencies for @types/react*, hds-core, hds-react, react, react-dom, react-helmet-async upgraded to React 19 / HDS 6 ranges; hds-design-tokens bumped to ^6.0.2; @eslint-react/no-use-context rule disabled.
Context providers: Context.ProviderContext as JSX
src/core/carousel/context/CarouselContextProvider.tsx, src/core/configProvider/ConfigProvider.tsx, src/core/imageGallery/ImageGalleryProvider.tsx, src/core/pageContextProvider/PageContextProvider.tsx, src/core/carousel/components/__tests__/Carousel*.test.tsx
All four providers switched from <Context.Provider value={...}> to <Context value={...}>. Matching carousel test helpers updated to wrap components with CarouselContext directly.
LinkBase: forwardRef → native ref prop
src/core/link/LinkBase.tsx
LinkProps switches to ComponentPropsWithRef<'a'>; LinkBase receives ref via destructured props instead of a second forwardRef argument; default export removes React.forwardRef wrapper; iconLeft className coerced to boolean.
Global JSX.ElementReact.JSX.Element
src/common/components/container/Container.tsx, src/common/components/list/List.tsx, src/core/archiveSearchPageContent/ArchiveSearchPageContent.tsx, src/core/collection/Collection.tsx, src/core/configProvider/configContext.ts, src/core/hero/Hero.tsx, src/core/imageGallery/Lightbox.tsx, src/core/pageContent/..., src/apollo/...
All prop and return type annotations using the ambient JSX.Element are replaced with React.JSX.Element across the codebase.
Utility and carousel compatibility fixes
src/core/utils/recursiveMap.ts, src/core/utils/__tests__/recursiveMap.test.tsx, src/core/utils/getChildrenByType.ts, src/core/carousel/components/CarouselSliderPage.tsx
recursiveMap uses a typed element local for cloneElement; test adds React.ReactElement type cast; typeOfComponent uses optional chaining and returns '' fallback instead of undefined; CarouselSliderPage ref callback uses optional chaining.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 Hop, hop, hooray for nineteen's new day,
forwardRef retired, now ref comes to play.
Context.Provider shed its .Provider tail,
JSX.Element namespaced without fail.
The rabbit upgrades, leaves React 18 behind —
fresh carrots and tokens of every kind! 🥕

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description is incomplete. While it mentions the main update and includes a Jira link, it lacks required sections like Issues/Closes, Testing details, and Additional notes from the template. Fill in the required template sections, particularly the Closes issue link in the proper format and add Testing section with details about how the migration was tested.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically identifies the main change: a React 19 and HDS v6 migration with issue reference HCRC-196.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/HCRC-197-react-19-hds-6-migration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/apollo/page/useApolloPageContext.tsx`:
- Around line 1-6: Replace the `use()` API with `useContext()` in the
useApolloPageContext hook since this is unconditional context consumption.
Change the import statement to import `useContext` from 'react' instead of
`use`, and update the function body to call `useContext(ApolloPageContext)`
instead of `use(ApolloPageContext)`. This simplifies the code and follows the
recommended React pattern for unconditional context access.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 043908a6-6159-49b4-bf96-bec61282b0d4

📥 Commits

Reviewing files that changed from the base of the PR and between ae7623e and 83757da.

⛔ Files ignored due to path filters (2)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • src/core/pageContent/sidebarContent/__tests__/__snapshots__/SidebarContent.test.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (30)
  • package.json
  • src/apollo/page/useApolloPageContext.tsx
  • src/apollo/pageContent/PageContent.tsx
  • src/apollo/pageWithTemplateContent/PageWithTemplateContent.tsx
  • src/common/components/container/Container.tsx
  • src/common/components/list/List.tsx
  • src/core/archiveSearchPageContent/ArchiveSearchPageContent.tsx
  • src/core/carousel/components/CarouselSliderPage.tsx
  • src/core/carousel/components/__tests__/CarouselSlideButton.test.tsx
  • src/core/carousel/components/__tests__/CarouselSlider.test.tsx
  • src/core/carousel/components/__tests__/CarouselSliderDot.test.tsx
  • src/core/carousel/components/__tests__/CarouselSliderPage.test.tsx
  • src/core/carousel/context/CarouselContext.ts
  • src/core/carousel/context/CarouselContextProvider.tsx
  • src/core/collection/Collection.tsx
  • src/core/configProvider/ConfigProvider.tsx
  • src/core/configProvider/configContext.ts
  • src/core/configProvider/useConfig.ts
  • src/core/hero/Hero.tsx
  • src/core/imageGallery/ImageGalleryProvider.tsx
  • src/core/imageGallery/Lightbox.tsx
  • src/core/imageGallery/useImageGalleryContext.ts
  • src/core/link/LinkBase.tsx
  • src/core/pageContent/PageContentLayout.tsx
  • src/core/pageContent/types.ts
  • src/core/pageContextProvider/PageContextProvider.tsx
  • src/core/pageContextProvider/usePageContext.tsx
  • src/core/utils/__tests__/recursiveMap.test.tsx
  • src/core/utils/getChildrenByType.ts
  • src/core/utils/recursiveMap.ts

Comment thread src/apollo/page/useApolloPageContext.tsx Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates the component library to React 19 and HDS React 6, aligning types and internal patterns (context usage, element typing) with the updated React/HDS ecosystems.

Changes:

  • Upgraded React/ReactDOM to ^19 and HDS packages to 6.0.2 (plus associated lockfile updates).
  • Refactored multiple contexts to use React 19’s use(Context) and <Context value={...}> provider syntax.
  • Updated TS/JSX typings from JSX.Element to React.JSX.Element and tightened some element/clone typings.

Reviewed changes

Copilot reviewed 31 out of 32 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/core/utils/recursiveMap.ts Tightens element typing before accessing props.children.
src/core/utils/getChildrenByType.ts Adjusts __TYPE access typing and normalizes return value.
src/core/utils/tests/recursiveMap.test.tsx Updates cloneElement typing in tests for TS compatibility.
src/core/pageContextProvider/usePageContext.tsx Switches from useContext to React 19 use(Context).
src/core/pageContextProvider/PageContextProvider.tsx Uses React 19 context provider element syntax.
src/core/pageContent/types.ts Updates exported types to use React.JSX.Element.
src/core/pageContent/sidebarContent/tests/snapshots/SidebarContent.test.tsx.snap Snapshot updates due to dependency/style output changes.
src/core/pageContent/PageContentLayout.tsx Updates prop types to React.JSX.Element.
src/core/link/LinkBase.tsx Refactors link prop typing and component shape (notably ref handling).
src/core/imageGallery/useImageGalleryContext.ts Switches to React 19 use(Context).
src/core/imageGallery/Lightbox.tsx Updates return types to React.JSX.Element.
src/core/imageGallery/ImageGalleryProvider.tsx Uses React 19 context provider element syntax.
src/core/hero/Hero.tsx Updates prop types to React.JSX.Element.
src/core/configProvider/useConfig.ts Switches from useContext to React 19 use(Context).
src/core/configProvider/ConfigProvider.tsx Uses React 19 context provider element syntax.
src/core/configProvider/configContext.ts Updates component replacement typings to React.JSX.Element.
src/core/collection/Collection.tsx Updates record value type to React.JSX.Element.
src/core/carousel/context/CarouselContextProvider.tsx Uses React 19 context provider element syntax.
src/core/carousel/context/CarouselContext.ts Switches from useContext to React 19 use(Context).
src/core/carousel/components/CarouselSliderPage.tsx Ref callback adjusted (block body) while toggling inert.
src/core/carousel/components/tests/CarouselSliderPage.test.tsx Updates test provider syntax to <CarouselContext value=...>.
src/core/carousel/components/tests/CarouselSliderDot.test.tsx Updates test provider syntax to <CarouselContext value=...>.
src/core/carousel/components/tests/CarouselSlider.test.tsx Updates test provider syntax to <CarouselContext value=...>.
src/core/carousel/components/tests/CarouselSlideButton.test.tsx Updates test provider syntax to <CarouselContext value=...>.
src/core/archiveSearchPageContent/ArchiveSearchPageContent.tsx Updates prop typing to React.JSX.Element.
src/common/components/list/List.tsx Updates element typings to React.JSX.Element.
src/common/components/container/Container.tsx Updates prop typing to React.JSX.Element.
src/apollo/pageWithTemplateContent/PageWithTemplateContent.tsx Updates prop typing to React.JSX.Element.
src/apollo/pageContent/PageContent.tsx Updates prop typing to React.JSX.Element.
src/apollo/page/useApolloPageContext.tsx Switches from useContext to React 19 use(Context).
pnpm-lock.yaml Locks updated dependency tree for React 19 + HDS 6.
package.json Updates peer/dev deps to React 19 and HDS 6.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file
Comments suppressed due to low confidence (2)

src/core/imageGallery/useImageGalleryContext.ts:11

  • ImageGalleryContext is created with a non-null default value, so use(ImageGalleryContext) will always return a truthy object and this if (!context) branch will never run. If the intent is to throw when used outside the provider, the context should be initialized with undefined (and typed accordingly) rather than a default object.
  const context = use(ImageGalleryContext);
  if (!context) {
    throw new Error(
      `Image gallery components cannot be used outside the ImageGalleryProvider`,
    );
  }

src/core/carousel/context/CarouselContext.ts:40

  • CarouselContext is created with a non-null default object, so use(CarouselContext) will never return a falsy value and this guard (if (!context) throw ...) is effectively dead code. If you want a clear error when used outside the provider, initialize the context with undefined/null instead of a default object (and update the type accordingly).
  const context = use(CarouselContext);
  if (!context) {
    throw new Error(
      `Carousel components cannot be rendered outside the CarouselContextProvider`,
    );
  }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/core/link/LinkBase.tsx
Comment thread src/core/link/LinkBase.tsx
Comment thread src/core/link/LinkBase.tsx
Comment thread package.json
Refs: HCRC-197
@Riippi Riippi changed the title feat: React 19 hds 6 migration HCRC-196 feat: React19 and HDSv6 migration HCRC-196 Jun 15, 2026
@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
0.0% Coverage on New Code (required ≥ 65%)

See analysis details on SonarQube Cloud

@mikkojamG mikkojamG merged commit 5531636 into main Jul 9, 2026
6 of 7 checks passed
@mikkojamG mikkojamG deleted the feat/HCRC-197-react-19-hds-6-migration branch July 9, 2026 07:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants