diff --git a/package.json b/package.json index 9760520038d..a66edf13f43 100644 --- a/package.json +++ b/package.json @@ -187,10 +187,10 @@ "postcss": "^8.4.24", "postcss-custom-properties": "^13.2.0", "postcss-import": "^15.1.0", - "react": "^19.1.0", - "react-dom": "^19.1.0", + "react": "^19.2.0", + "react-dom": "^19.2.0", "react-frame-component": "^5.0.0", - "react-test-renderer": "^19.1.0", + "react-test-renderer": "^19.2.0", "recast": "^0.23", "recursive-readdir": "^2.2.2", "regenerator-runtime": "0.13.3", diff --git a/packages/@react-aria/collections/src/Document.ts b/packages/@react-aria/collections/src/Document.ts index dd1dbeb4f36..1bde2a2fdb0 100644 --- a/packages/@react-aria/collections/src/Document.ts +++ b/packages/@react-aria/collections/src/Document.ts @@ -475,12 +475,10 @@ export class Document = BaseCollection> extend /** Finalizes the collection update, updating all nodes and freezing the collection. */ getCollection(): C { - // If in a subscription update, return a clone of the existing collection. - // This ensures React will queue a render. React will call getCollection again - // during render, at which point all the updates will be complete and we can return - // the new collection. + // If in a subscription update, return return the existing collection. + // React will call getCollection again during render, at which point all the updates will be complete. if (this.inSubscription) { - return this.collection.clone(); + return this.collection; } // Reset queuedRender to false when getCollection is called during render. @@ -540,9 +538,18 @@ export class Document = BaseCollection> extend // we reset queuedRender back to false. this.queuedRender = true; this.inSubscription = true; + + // Clone the collection to ensure that React queues a render. It will call getCollection again + // during render, at which point all the updates will be complete and we can return + // the new collection. + if (!this.isSSR) { + this.collection = this.collection.clone(); + } + for (let fn of this.subscriptions) { fn(); } + this.inSubscription = false; } diff --git a/packages/dev/docs/package.json b/packages/dev/docs/package.json index 274eb27e9db..d243c0dc6c1 100644 --- a/packages/dev/docs/package.json +++ b/packages/dev/docs/package.json @@ -29,8 +29,8 @@ "highlight.js": "9.18.1", "markdown-to-jsx": "^6.11.0", "quicklink": "^2.3.0", - "react": "^19.1.0", - "react-dom": "^19.1.0", + "react": "^19.2.0", + "react-dom": "^19.2.0", "react-lowlight": "^2.0.0" }, "peerDependencies": { diff --git a/packages/dev/s2-docs/package.json b/packages/dev/s2-docs/package.json index 1e050fded2f..6190d5f041a 100644 --- a/packages/dev/s2-docs/package.json +++ b/packages/dev/s2-docs/package.json @@ -49,10 +49,10 @@ "json5": "^2.2.3", "lz-string": "^1.5.0", "markdown-to-jsx": "^6.11.0", - "react": "^19", + "react": "^19.2.0", "react-aria": "^3.40.0", "react-aria-components": "^1.7.1", - "react-dom": "^19", + "react-dom": "^19.2.0", "react-stately": "^3.38.0", "remark-mdx": "^3.1.0", "remark-parse": "^11.0.0", diff --git a/packages/react-aria-components/test/ListBox.test.js b/packages/react-aria-components/test/ListBox.test.js index 5b5c353be4f..197a15e7ad5 100644 --- a/packages/react-aria-components/test/ListBox.test.js +++ b/packages/react-aria-components/test/ListBox.test.js @@ -1948,4 +1948,40 @@ describe('ListBox', () => { expect(onClick).toHaveBeenCalledTimes(1); }); }); + + if (React.version.startsWith('19')) { + it('supports Activity', async () => { + function ActivityListBox() { + let [mode, setMode] = React.useState('hidden'); + + return ( + <> + + + +

List should be visible

+ + + Item 1 + Item 2 + Item 3 + Item 4 + Item 5 + +
+ + ); + } + + let {getAllByRole, getByRole, queryAllByRole} = render(); + let button = getByRole('button'); + expect(queryAllByRole('option')).toHaveLength(0); + await user.click(button); + expect(getAllByRole('option')).toHaveLength(5); + await user.click(button); + expect(queryAllByRole('option')).toHaveLength(0); + }); + } }); diff --git a/packages/react-aria-components/test/Tabs.test.js b/packages/react-aria-components/test/Tabs.test.js index 80c9ebfc2d4..bc18c2d1ee7 100644 --- a/packages/react-aria-components/test/Tabs.test.js +++ b/packages/react-aria-components/test/Tabs.test.js @@ -729,4 +729,42 @@ describe('Tabs', () => { expect(onClick).toHaveBeenCalledTimes(1); }); }); + + if (React.version.startsWith('19')) { + it('supports Activity', async () => { + function ActivityTabs() { + let [mode, setMode] = React.useState('hidden'); + + return ( + <> + + + + + A + B + + C + Test + + + A + B + C + + + + ); + } + + let {getByRole, getAllByRole, queryAllByRole} = render(); + + let button = getByRole('button'); + expect(queryAllByRole('tab')).toHaveLength(0); + await user.click(button); + expect(getAllByRole('tab')).toHaveLength(3); + }); + } }); diff --git a/starters/docs/package.json b/starters/docs/package.json index 00a78daa303..ca577cdc6bd 100644 --- a/starters/docs/package.json +++ b/starters/docs/package.json @@ -27,16 +27,16 @@ "clsx": "^2.1.1", "lightningcss-loader": "^2.1.0", "lucide-react": "^0.517.0", - "react": "^19.1.0", + "react": "^19.2.0", "react-aria-components": "^1.14.0", - "react-dom": "^19.1.0", + "react-dom": "^19.2.0", "storybook": "^8.6.14", "storybook-dark-mode": "^4.0.2", "typescript": "^5.8.2" }, "resolutions": { - "react": "19.1.0", - "react-dom": "19.1.0", + "react": "19.2.0", + "react-dom": "19.2.0", "@types/mime": "3.0.4", "jackspeak": "2.1.1" } diff --git a/yarn.lock b/yarn.lock index 54984eab68a..09f406000e1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6882,8 +6882,8 @@ __metadata: highlight.js: "npm:9.18.1" markdown-to-jsx: "npm:^6.11.0" quicklink: "npm:^2.3.0" - react: "npm:^19.1.0" - react-dom: "npm:^19.1.0" + react: "npm:^19.2.0" + react-dom: "npm:^19.2.0" react-lowlight: "npm:^2.0.0" peerDependencies: react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 @@ -7434,10 +7434,10 @@ __metadata: lz-string: "npm:^1.5.0" markdown-to-jsx: "npm:^6.11.0" playwright: "npm:^1.57.0" - react: "npm:^19" + react: "npm:^19.2.0" react-aria: "npm:^3.40.0" react-aria-components: "npm:^1.7.1" - react-dom: "npm:^19" + react-dom: "npm:^19.2.0" react-stately: "npm:^3.38.0" remark-mdx: "npm:^3.1.0" remark-parse: "npm:^11.0.0" @@ -24754,14 +24754,14 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0, react-dom@npm:^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0, react-dom@npm:^19, react-dom@npm:^19.1.0": - version: 19.1.0 - resolution: "react-dom@npm:19.1.0" +"react-dom@npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0, react-dom@npm:^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0, react-dom@npm:^19.2.0": + version: 19.2.1 + resolution: "react-dom@npm:19.2.1" dependencies: - scheduler: "npm:^0.26.0" + scheduler: "npm:^0.27.0" peerDependencies: - react: ^19.1.0 - checksum: 10c0/3e26e89bb6c67c9a6aa86cb888c7a7f8258f2e347a6d2a15299c17eb16e04c19194e3452bc3255bd34000a61e45e2cb51e46292392340432f133e5a5d2dfb5fc + react: ^19.2.1 + checksum: 10c0/e56b6b3d72314df580ca800b70a69a21c6372703c8f45d9b5451ca6519faefb2496d76ffa9c5adb94136d2bbf2fd303d0dfc208a2cd77ede3132877471af9470 languageName: node linkType: hard @@ -24948,10 +24948,10 @@ __metadata: postcss: "npm:^8.4.24" postcss-custom-properties: "npm:^13.2.0" postcss-import: "npm:^15.1.0" - react: "npm:^19.1.0" - react-dom: "npm:^19.1.0" + react: "npm:^19.2.0" + react-dom: "npm:^19.2.0" react-frame-component: "npm:^5.0.0" - react-test-renderer: "npm:^19.1.0" + react-test-renderer: "npm:^19.2.0" recast: "npm:^0.23" recursive-readdir: "npm:^2.2.2" regenerator-runtime: "npm:0.13.3" @@ -25037,17 +25037,10 @@ __metadata: languageName: node linkType: hard -"react@npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0, react@npm:^19, react@npm:^19.1.0": - version: 19.1.0 - resolution: "react@npm:19.1.0" - checksum: 10c0/530fb9a62237d54137a13d2cfb67a7db6a2156faed43eecc423f4713d9b20c6f2728b026b45e28fcd72e8eadb9e9ed4b089e99f5e295d2f0ad3134251bdd3698 - languageName: node - linkType: hard - -"react@npm:^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0": - version: 19.1.1 - resolution: "react@npm:19.1.1" - checksum: 10c0/8c9769a2dfd02e603af6445058325e6c8a24b47b185d0e461f66a6454765ddcaecb3f0a90184836c68bb509f3c38248359edbc42f0d07c23eb500a5c30c87b4e +"react@npm:^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0, react@npm:^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0, react@npm:^19.2.0": + version: 19.2.1 + resolution: "react@npm:19.2.1" + checksum: 10c0/2b5eaf407abb3db84090434c20d6c5a8e447ab7abcd8fe9eaf1ddc299babcf31284ee9db7ea5671d21c85ac5298bd632fa1a7da1ed78d5b368a537f5e1cd5d62 languageName: node linkType: hard @@ -26032,6 +26025,13 @@ __metadata: languageName: node linkType: hard +"scheduler@npm:^0.27.0": + version: 0.27.0 + resolution: "scheduler@npm:0.27.0" + checksum: 10c0/4f03048cb05a3c8fddc45813052251eca00688f413a3cee236d984a161da28db28ba71bd11e7a3dd02f7af84ab28d39fb311431d3b3772fed557945beb00c452 + languageName: node + linkType: hard + "section-matter@npm:^1.0.0": version: 1.0.0 resolution: "section-matter@npm:1.0.0"