From f9055e28ee7896d335204e74a5005ecec1c53472 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Tue, 22 Oct 2024 16:12:36 +0900 Subject: [PATCH 01/31] Upgrade Playwright to v1.48 (#66296) Co-authored-by: Mamaduka Co-authored-by: swissspidy --- package-lock.json | 26 +++++++++++++------------- package.json | 2 +- packages/scripts/package.json | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index 82cf77db40c57d..524584ed63e31a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -100,7 +100,7 @@ "@octokit/rest": "16.26.0", "@octokit/types": "6.34.0", "@octokit/webhooks-types": "5.8.0", - "@playwright/test": "1.47.0", + "@playwright/test": "1.48.1", "@pmmmwh/react-refresh-webpack-plugin": "0.5.11", "@react-native/babel-preset": "0.73.10", "@react-native/metro-babel-transformer": "0.73.10", @@ -7096,12 +7096,12 @@ } }, "node_modules/@playwright/test": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.47.0.tgz", - "integrity": "sha512-SgAdlSwYVpToI4e/IH19IHHWvoijAYH5hu2MWSXptRypLSnzj51PcGD+rsOXFayde4P9ZLi+loXVwArg6IUkCA==", + "version": "1.48.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.1.tgz", + "integrity": "sha512-s9RtWoxkOLmRJdw3oFvhFbs9OJS0BzrLUc8Hf6l2UdCNd1rqeEyD4BhCJkvzeEoD1FsK4mirsWwGerhVmYKtZg==", "dev": true, "dependencies": { - "playwright": "1.47.0" + "playwright": "1.48.1" }, "bin": { "playwright": "cli.js" @@ -41274,12 +41274,12 @@ "dev": true }, "node_modules/playwright": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.47.0.tgz", - "integrity": "sha512-jOWiRq2pdNAX/mwLiwFYnPHpEZ4rM+fRSQpRHwEwZlP2PUANvL3+aJOF/bvISMhFD30rqMxUB4RJx9aQbfh4Ww==", + "version": "1.48.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.1.tgz", + "integrity": "sha512-j8CiHW/V6HxmbntOfyB4+T/uk08tBy6ph0MpBXwuoofkSnLmlfdYNNkFTYD6ofzzlSqLA1fwH4vwvVFvJgLN0w==", "dev": true, "dependencies": { - "playwright-core": "1.47.0" + "playwright-core": "1.48.1" }, "bin": { "playwright": "cli.js" @@ -41292,9 +41292,9 @@ } }, "node_modules/playwright-core": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.47.0.tgz", - "integrity": "sha512-1DyHT8OqkcfCkYUD9zzUTfg7EfTd+6a8MkD/NWOvjo0u/SCNd5YmY/lJwFvUZOxJbWNds+ei7ic2+R/cRz/PDg==", + "version": "1.48.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.1.tgz", + "integrity": "sha512-Yw/t4VAFX/bBr1OzwCuOMZkY1Cnb4z/doAFSwf4huqAGWmf9eMNjmK7NiOljCdLmxeRYcGPPmcDgU0zOlzP0YA==", "dev": true, "bin": { "playwright-core": "cli.js" @@ -56607,7 +56607,7 @@ "npm": ">=8.19.2" }, "peerDependencies": { - "@playwright/test": "^1.47.0", + "@playwright/test": "^1.48.1", "react": "^18.0.0", "react-dom": "^18.0.0" } diff --git a/package.json b/package.json index c280e1b728c3df..67bfb7cf5df37b 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "@octokit/rest": "16.26.0", "@octokit/types": "6.34.0", "@octokit/webhooks-types": "5.8.0", - "@playwright/test": "1.47.0", + "@playwright/test": "1.48.1", "@pmmmwh/react-refresh-webpack-plugin": "0.5.11", "@react-native/babel-preset": "0.73.10", "@react-native/metro-babel-transformer": "0.73.10", diff --git a/packages/scripts/package.json b/packages/scripts/package.json index 66461f4eb28ec2..9bc4fcd915b204 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -95,7 +95,7 @@ "webpack-dev-server": "^4.15.1" }, "peerDependencies": { - "@playwright/test": "^1.47.0", + "@playwright/test": "^1.48.1", "react": "^18.0.0", "react-dom": "^18.0.0" }, From fe56004bafc42cdfe1fde897f05ff1d64a60b661 Mon Sep 17 00:00:00 2001 From: Ella <4710635+ellatrix@users.noreply.github.com> Date: Tue, 22 Oct 2024 09:33:00 +0200 Subject: [PATCH 02/31] Clean up: adjust reusable-blocks dependencies (#66302) --- backport-changelog/6.8/7604.md | 1 + lib/client-assets.php | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/backport-changelog/6.8/7604.md b/backport-changelog/6.8/7604.md index fc6902859caa49..8c7d80994ae605 100644 --- a/backport-changelog/6.8/7604.md +++ b/backport-changelog/6.8/7604.md @@ -1,3 +1,4 @@ https://github.com/WordPress/wordpress-develop/pull/7604 * https://github.com/WordPress/gutenberg/pull/66285 +* https://github.com/WordPress/gutenberg/pull/66302 diff --git a/lib/client-assets.php b/lib/client-assets.php index 092ae2d3679424..275c48dfc8e2d1 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -419,7 +419,7 @@ function gutenberg_register_packages_styles( $styles ) { $styles, 'wp-edit-widgets', gutenberg_url( 'build/edit-widgets/style.css' ), - array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-patterns', 'wp-reusable-blocks', 'wp-widgets', 'wp-preferences' ), + array( 'wp-components', 'wp-block-editor', 'wp-editor', 'wp-edit-blocks', 'wp-patterns', 'wp-widgets', 'wp-preferences' ), $version ); $styles->add_data( 'wp-edit-widgets', 'rtl', 'replace' ); From 0e65adcbe187797a536aa99f56b063a61cafdc3d Mon Sep 17 00:00:00 2001 From: Juan Aldasoro Date: Tue, 22 Oct 2024 11:03:26 +0200 Subject: [PATCH 03/31] Set image width to `fit-content` to solve aspect ratio problems in Firefox. (#66217) --- packages/block-library/src/image/style.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/block-library/src/image/style.scss b/packages/block-library/src/image/style.scss index 1bb19bf29da691..da4ccc50dac7f1 100644 --- a/packages/block-library/src/image/style.scss +++ b/packages/block-library/src/image/style.scss @@ -9,6 +9,7 @@ max-width: 100%; vertical-align: bottom; box-sizing: border-box; + width: fit-content; @media (prefers-reduced-motion: no-preference) { &.hide { From a4aeb1a03e91848fed09e6036ead2c54ad8db02e Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Tue, 22 Oct 2024 12:26:42 +0300 Subject: [PATCH 04/31] Storybook: Add BlockPatternsList story (#66227) Co-authored-by: ntsekouras Co-authored-by: ciampo Co-authored-by: youknowriad --- .../block-patterns-list/stories/fixtures.js | 834 ++++++++++++++++++ .../stories/index.story.js | 81 ++ .../components/block-patterns-list/style.scss | 2 + 3 files changed, 917 insertions(+) create mode 100644 packages/block-editor/src/components/block-patterns-list/stories/fixtures.js create mode 100644 packages/block-editor/src/components/block-patterns-list/stories/index.story.js diff --git a/packages/block-editor/src/components/block-patterns-list/stories/fixtures.js b/packages/block-editor/src/components/block-patterns-list/stories/fixtures.js new file mode 100644 index 00000000000000..0fd895bbe1716d --- /dev/null +++ b/packages/block-editor/src/components/block-patterns-list/stories/fixtures.js @@ -0,0 +1,834 @@ +export default [ + { + name: 'test/1', + title: 'Centered image with two-tone background color', + blocks: [ + { + clientId: '035ea9e6-cf5a-4631-a11e-29f3f696f836', + name: 'core/cover', + isValid: true, + attributes: { + useFeaturedImage: false, + alt: '', + hasParallax: false, + isRepeated: false, + dimRatio: 100, + backgroundType: 'image', + minHeight: 66, + minHeightUnit: 'vh', + customGradient: + 'linear-gradient(90deg,rgb(35,74,20) 50%,rgb(225,137,116) 50%)', + isDark: false, + tagName: 'div', + align: 'full', + style: { + spacing: { + padding: { + top: '5vw', + right: '5vw', + bottom: '5vw', + left: '5vw', + }, + margin: { + top: '0', + }, + }, + }, + }, + innerBlocks: [ + { + clientId: '57c3e044-137d-456d-8426-20768e07f09f', + name: 'core/group', + isValid: true, + attributes: { + tagName: 'div', + style: { + spacing: { + blockGap: '0px', + }, + layout: { + selfStretch: 'fill', + flexSize: null, + }, + }, + layout: { + type: 'constrained', + contentSize: '600px', + wideSize: '1200px', + }, + }, + innerBlocks: [ + { + clientId: + '9e251315-0ea5-4849-9e1a-974de0981f51', + name: 'core/spacer', + isValid: true, + attributes: { + height: '100px', + }, + innerBlocks: [], + originalContent: + '', + validationIssues: [], + }, + { + clientId: + 'd83373a3-bdc3-44d6-9f6f-5a36ef8d637c', + name: 'core/image', + isValid: true, + attributes: { + url: 'https://pd.w.org/2022/03/3866241b433db4ee2.96648572.jpeg', + alt: '', + caption: '', + sizeSlug: 'large', + className: 'is-style-default', + style: { + color: { + duotone: [ '#000000', '#ffffff' ], + }, + }, + }, + innerBlocks: [], + originalContent: + '
', + validationIssues: [], + }, + { + clientId: + '56e72331-1213-466f-bd14-1131a56b2c95', + name: 'core/spacer', + isValid: true, + attributes: { + height: '48px', + }, + innerBlocks: [], + originalContent: + '', + validationIssues: [], + }, + { + clientId: + '851c15bc-f5cf-4780-838e-6bfea2b09b30', + name: 'core/heading', + isValid: true, + attributes: { + textAlign: 'center', + content: 'Etcetera', + level: 2, + align: 'wide', + style: { + typography: { + fontSize: '50px', + fontStyle: 'normal', + fontWeight: '400', + textTransform: 'uppercase', + letterSpacing: '32px', + lineHeight: '1', + }, + spacing: { + padding: { + left: '32px', + }, + }, + }, + textColor: 'white', + }, + innerBlocks: [], + originalContent: + '

Etcetera

', + validationIssues: [], + }, + { + clientId: + 'a734e600-5b98-47c4-982d-c98e8c8b78a2', + name: 'core/spacer', + isValid: true, + attributes: { + height: '100px', + }, + innerBlocks: [], + originalContent: + '', + validationIssues: [], + }, + ], + originalContent: + '
\n\n\n\n\n\n\n\n
', + validationIssues: [], + }, + ], + originalContent: + '
', + validationIssues: [], + }, + ], + }, + { + name: 'test/2', + title: 'Fullwidth, vertically aligned headline on right with description on left', + blocks: [ + { + clientId: 'efa29ce0-cf43-421b-b9e6-46f52f17d943', + name: 'core/cover', + isValid: true, + attributes: { + alt: '', + hasParallax: false, + isRepeated: false, + dimRatio: 100, + customOverlayColor: '#e68b14', + backgroundType: 'image', + isDark: false, + useFeaturedImage: false, + tagName: 'div', + align: 'full', + style: { + spacing: { + padding: { + top: '5vw', + right: '5vw', + bottom: '5vw', + left: '5vw', + }, + margin: { + top: '0', + }, + }, + }, + isUserOverlayColor: true, + }, + innerBlocks: [ + { + clientId: '4e50914f-9c9c-471a-84ad-4a22b514a393', + name: 'core/group', + isValid: true, + attributes: { + tagName: 'div', + layout: { + type: 'flex', + flexWrap: 'wrap', + verticalAlignment: 'top', + }, + }, + innerBlocks: [ + { + clientId: + '72b5d32d-35df-4530-8c81-ce67baaf34d1', + name: 'core/group', + isValid: true, + attributes: { + tagName: 'div', + style: { + layout: { + selfStretch: 'fixed', + flexSize: '320px', + }, + spacing: { + blockGap: '24px', + }, + }, + layout: { + type: 'default', + }, + }, + innerBlocks: [ + { + clientId: + '86b7c5b3-2de6-42ff-9d41-d38dd267a122', + name: 'core/paragraph', + isValid: true, + attributes: { + content: + "Let 'em Roll is an album by American organist Big John Patton recorded in 1965 and released on the Blue Note label.", + dropCap: false, + style: { + layout: { + selfStretch: 'fixed', + flexSize: '330px', + }, + typography: { + fontSize: '17px', + fontStyle: 'normal', + fontWeight: '300', + lineHeight: '1.4', + textTransform: 'none', + textDecoration: 'none', + letterSpacing: '0px', + }, + }, + }, + innerBlocks: [], + originalContent: + '

Let \'em Roll is an album by American organist Big John Patton recorded in 1965 and released on the Blue Note label.

', + validationIssues: [], + }, + { + clientId: + '50d8d1c7-05dd-41d4-af67-29449e818ef7', + name: 'core/buttons', + isValid: true, + attributes: {}, + innerBlocks: [ + { + clientId: + '3e26f576-a29a-4947-85f2-1454ea85db60', + name: 'core/button', + isValid: true, + attributes: { + tagName: 'a', + type: 'button', + text: 'Shop Now', + backgroundColor: 'black', + textColor: 'white', + style: { + typography: { + fontSize: '17px', + fontStyle: 'normal', + fontWeight: '700', + textDecoration: + 'none', + textTransform: + 'uppercase', + letterSpacing: + '0px', + }, + spacing: { + padding: { + top: '14px', + bottom: '14px', + left: '36px', + right: '36px', + }, + }, + border: { + radius: '0px', + top: { + radius: '0px', + width: '0px', + style: 'none', + }, + right: { + radius: '0px', + width: '0px', + style: 'none', + }, + bottom: { + radius: '0px', + width: '0px', + style: 'none', + }, + left: { + radius: '0px', + width: '0px', + style: 'none', + }, + }, + }, + }, + innerBlocks: [], + originalContent: + '', + validationIssues: [], + }, + ], + originalContent: + '
', + validationIssues: [], + }, + ], + originalContent: + '
\n\n
', + validationIssues: [], + }, + { + clientId: + 'e8176dce-481f-4454-8e01-13bc5382e0fd', + name: 'core/group', + isValid: true, + attributes: { + tagName: 'div', + style: { + spacing: { + blockGap: '0px', + }, + layout: { + selfStretch: 'fill', + flexSize: null, + }, + }, + layout: { + type: 'default', + }, + }, + innerBlocks: [ + { + clientId: + '738291ae-b0d1-4867-90b5-f35b999ca407', + name: 'core/paragraph', + isValid: true, + attributes: { + align: 'right', + content: "Let
'EM
Roll", + dropCap: false, + style: { + typography: { + fontSize: '148px', + textTransform: 'uppercase', + fontStyle: 'normal', + fontWeight: '700', + lineHeight: '0.8', + letterSpacing: '-4px', + }, + }, + textColor: 'black', + }, + innerBlocks: [], + originalContent: + '

Let
\'EM
Roll

', + validationIssues: [], + }, + { + clientId: + '331df46f-7623-49a1-8031-7c421bddc15a', + name: 'core/paragraph', + isValid: true, + attributes: { + align: 'right', + content: 'Big
John
Patton', + dropCap: false, + style: { + typography: { + fontSize: '148px', + textTransform: 'uppercase', + fontStyle: 'normal', + fontWeight: '700', + lineHeight: '0.8', + letterSpacing: '-4px', + }, + }, + textColor: 'white', + }, + innerBlocks: [], + originalContent: + '

Big
John
Patton

', + validationIssues: [], + }, + ], + originalContent: + '
\n\n
', + validationIssues: [], + }, + ], + originalContent: + '
\n\n
', + validationIssues: [], + }, + ], + originalContent: + '
', + validationIssues: [], + }, + ], + }, + { + name: 'test/3', + title: 'Two columns of text with offset heading', + blocks: [ + { + clientId: 'da715d18-2126-4be0-bf13-3328419f220a', + name: 'core/group', + isValid: true, + attributes: { + tagName: 'div', + align: 'full', + style: { + color: { + background: '#f2f0e9', + }, + }, + }, + innerBlocks: [ + { + clientId: '8a89e4af-1f70-4545-9d1e-887ff50a141d', + name: 'core/spacer', + isValid: true, + attributes: { + height: '70px', + }, + innerBlocks: [], + originalContent: + '', + validationIssues: [], + }, + { + clientId: '4ab42169-0fcd-416a-bd34-487f6a4e33ad', + name: 'core/columns', + isValid: true, + attributes: { + verticalAlignment: 'center', + isStackedOnMobile: true, + align: 'wide', + }, + innerBlocks: [ + { + clientId: + '88b53c37-16dc-4396-b9bc-6cc115411d9a', + name: 'core/column', + isValid: true, + attributes: { + width: '50%', + }, + innerBlocks: [ + { + clientId: + '1b5a12e4-06cf-4f78-b665-7440771d0025', + name: 'core/paragraph', + isValid: true, + attributes: { + content: + 'Oceanic Inspiration', + dropCap: false, + style: { + typography: { + lineHeight: '1.1', + fontSize: '30px', + }, + color: { + text: '#000000', + }, + }, + }, + innerBlocks: [], + originalContent: + '

Oceanic Inspiration

', + validationIssues: [], + }, + ], + originalContent: + '
', + validationIssues: [], + }, + { + clientId: + '82b7e2aa-dcd8-4b34-a2a9-d239192fed71', + name: 'core/column', + isValid: true, + attributes: { + width: '50%', + }, + innerBlocks: [ + { + clientId: + 'b0fbba51-f3ec-40d5-91d6-64a24ae223f4', + name: 'core/separator', + isValid: true, + attributes: { + className: 'is-style-wide', + opacity: 'css', + style: { + color: { + background: '#000000', + }, + }, + }, + innerBlocks: [], + originalContent: + '
', + validationIssues: [], + }, + ], + originalContent: + '
', + validationIssues: [], + }, + ], + originalContent: + '
\n\n
', + validationIssues: [], + }, + { + clientId: '72d3dc7f-bbbe-4088-b556-a32c07191068', + name: 'core/columns', + isValid: true, + attributes: { + isStackedOnMobile: true, + align: 'wide', + }, + innerBlocks: [ + { + clientId: + 'cf3abb5c-eee8-4314-af70-022b4f7e5bc4', + name: 'core/column', + isValid: true, + attributes: {}, + innerBlocks: [], + originalContent: + '
', + validationIssues: [], + }, + { + clientId: + '6978a278-bcf8-4244-9e99-bf5b56fe0f5e', + name: 'core/column', + isValid: true, + attributes: {}, + innerBlocks: [ + { + clientId: + '26a6b210-07b6-49b1-8c0b-41d0760562a5', + name: 'core/paragraph', + isValid: true, + attributes: { + content: + 'Winding veils round their heads, the women walked on deck. They were now moving steadily down the river, passing the dark shapes of ships at anchor, and London was a swarm of lights with a pale yellow canopy drooping above it. There were the lights of the great theatres, the lights of the long streets, lights that indicated huge squares of domestic comfort, lights that hung high in air.', + dropCap: false, + style: { + color: { + text: '#000000', + }, + }, + fontSize: 'extra-small', + }, + innerBlocks: [], + originalContent: + '

Winding veils round their heads, the women walked on deck. They were now moving steadily down the river, passing the dark shapes of ships at anchor, and London was a swarm of lights with a pale yellow canopy drooping above it. There were the lights of the great theatres, the lights of the long streets, lights that indicated huge squares of domestic comfort, lights that hung high in air.

', + validationIssues: [], + }, + ], + originalContent: + '
', + validationIssues: [], + }, + { + clientId: + '53ac5018-2b60-429e-b893-fce01f8bad24', + name: 'core/column', + isValid: true, + attributes: {}, + innerBlocks: [ + { + clientId: + '10a12c7d-77b5-46c7-8215-ff2f94ed4e27', + name: 'core/paragraph', + isValid: true, + attributes: { + content: + 'No darkness would ever settle upon those lamps, as no darkness had settled upon them for hundreds of years. It seemed dreadful that the town should blaze for ever in the same spot; dreadful at least to people going away to adventure upon the sea, and beholding it as a circumscribed mound, eternally burnt, eternally scarred. From the deck of the ship the great city appeared a crouched and cowardly figure, a sedentary miser.', + dropCap: false, + style: { + color: { + text: '#000000', + }, + }, + fontSize: 'extra-small', + }, + innerBlocks: [], + originalContent: + '

No darkness would ever settle upon those lamps, as no darkness had settled upon them for hundreds of years. It seemed dreadful that the town should blaze for ever in the same spot; dreadful at least to people going away to adventure upon the sea, and beholding it as a circumscribed mound, eternally burnt, eternally scarred. From the deck of the ship the great city appeared a crouched and cowardly figure, a sedentary miser.

', + validationIssues: [], + }, + ], + originalContent: + '
', + validationIssues: [], + }, + ], + originalContent: + '
\n\n\n\n
', + validationIssues: [], + }, + { + clientId: 'f401521c-d5d4-486a-b069-47350b032dc9', + name: 'core/spacer', + isValid: true, + attributes: { + height: '40px', + }, + innerBlocks: [], + originalContent: + '', + validationIssues: [], + }, + ], + originalContent: + '
\n\n\n\n\n\n
', + validationIssues: [], + }, + ], + }, + { + name: 'test/4', + title: 'Offset text with a brutalist design vibe', + blocks: [ + { + clientId: 'ac947e62-0568-4fa2-85a0-927b86c8ae42', + name: 'core/cover', + isValid: true, + attributes: { + alt: '', + hasParallax: false, + isRepeated: false, + dimRatio: 100, + customOverlayColor: '#ffb43c', + backgroundType: 'image', + minHeight: 66, + minHeightUnit: 'vh', + isDark: false, + useFeaturedImage: false, + tagName: 'div', + align: 'full', + textColor: 'black', + style: { + spacing: { + padding: { + top: '48px', + right: '48px', + bottom: '48px', + left: '48px', + }, + margin: { + top: '0', + }, + }, + }, + isUserOverlayColor: true, + }, + innerBlocks: [ + { + clientId: 'a23ab6aa-b6dc-4148-a7fc-a4ad04deb738', + name: 'core/group', + isValid: true, + attributes: { + tagName: 'div', + style: { + spacing: { + blockGap: '0px', + }, + }, + layout: { + type: 'constrained', + wideSize: '1200px', + contentSize: '800px', + }, + }, + innerBlocks: [ + { + clientId: + '2cd000fa-8e5b-4edc-8238-5912c5e397d2', + name: 'core/paragraph', + isValid: true, + attributes: { + align: 'left', + content: + '✴︎ Walk', + dropCap: false, + style: { + typography: { + fontSize: '148px', + textTransform: 'uppercase', + fontStyle: 'normal', + fontWeight: '700', + lineHeight: '0.9', + letterSpacing: '-2px', + }, + }, + textColor: 'black', + }, + innerBlocks: [], + originalContent: + '

✴︎ Walk

', + validationIssues: [], + }, + { + clientId: + '2d747e99-c672-4d7f-91d4-f8f03d295f2b', + name: 'core/paragraph', + isValid: true, + attributes: { + align: 'right', + content: 'In the', + dropCap: false, + style: { + typography: { + fontSize: '148px', + textTransform: 'uppercase', + fontStyle: 'normal', + fontWeight: '700', + lineHeight: '0.9', + letterSpacing: '-2px', + }, + }, + textColor: 'black', + }, + innerBlocks: [], + originalContent: + '

In the

', + validationIssues: [], + }, + { + clientId: + 'd63e34e7-8943-49ff-bc05-8749809f4117', + name: 'core/paragraph', + isValid: true, + attributes: { + align: 'left', + content: 'Park', + dropCap: false, + style: { + typography: { + fontSize: '148px', + textTransform: 'uppercase', + fontStyle: 'normal', + fontWeight: '700', + lineHeight: '0.9', + letterSpacing: '-2px', + }, + }, + textColor: 'black', + }, + innerBlocks: [], + originalContent: + '

Park

', + validationIssues: [], + }, + { + clientId: + 'e996575b-4ada-43b1-8ae1-a6dbb2ec0ecc', + name: 'core/paragraph', + isValid: true, + attributes: { + align: 'center', + content: '—01.03', + dropCap: false, + style: { + typography: { + fontSize: '140px', + textTransform: 'uppercase', + fontStyle: 'italic', + fontWeight: '200', + letterSpacing: '0px', + lineHeight: '0.9', + }, + color: { + text: '#a65a00', + }, + }, + }, + innerBlocks: [], + originalContent: + '

—01.03

', + validationIssues: [], + }, + ], + originalContent: + '
\n\n\n\n\n\n
', + validationIssues: [], + }, + ], + originalContent: + '
', + validationIssues: [], + }, + ], + }, +]; diff --git a/packages/block-editor/src/components/block-patterns-list/stories/index.story.js b/packages/block-editor/src/components/block-patterns-list/stories/index.story.js new file mode 100644 index 00000000000000..9eb393ea13e762 --- /dev/null +++ b/packages/block-editor/src/components/block-patterns-list/stories/index.story.js @@ -0,0 +1,81 @@ +/** + * External dependencies + */ +import blockLibraryStyles from '!!raw-loader!../../../../../block-library/build-style/style.css'; + +/** + * WordPress dependencies + */ +import { useAsyncList } from '@wordpress/compose'; + +/** + * Internal dependencies + */ +import BlockPatternsList from '../'; +import { ExperimentalBlockEditorProvider } from '../../provider'; +import patterns from './fixtures'; + +const blockEditorSettings = { + styles: [ { css: blockLibraryStyles } ], +}; + +export default { + component: BlockPatternsList, + title: 'BlockEditor/BlockPatternsList', +}; + +export const Default = { + render: function Template( props ) { + const shownPatterns = useAsyncList( props.blockPatterns ); + return ( + + + + ); + }, + args: { + blockPatterns: patterns, + isDraggable: false, + label: 'Block patterns story', + showTitle: true, + showTitlesAsTooltip: false, + }, + argTypes: { + blockPatterns: { description: 'The patterns to render.' }, + shownPatterns: { + description: + 'Usually this component is used with `useAsyncList` for performance reasons and you should provide the returned list from that hook. Alternatively it should have the same value with `blockPatterns`.', + }, + showTitle: { + description: 'Whether to render the title of each pattern.', + table: { + defaultValue: { summary: true }, + type: { summary: 'boolean' }, + }, + }, + onClickPattern: { type: 'function' }, + onHover: { type: 'function' }, + showTitlesAsTooltip: { + description: + 'Whether to render the title of each pattern as a tooltip. If enabled, it takes precedence over `showTitle` prop.', + }, + orientation: { + description: 'Orientation for the underlying composite widget.', + table: { + defaultValue: { summary: 'both' }, + type: { summary: 'string' }, + }, + }, + category: { description: 'The currently selected pattern category.' }, + isDraggable: { + description: 'Whether the pattern list item should be draggable.', + }, + }, + parameters: { + actions: { argTypesRegex: '^on.*' }, + controls: { expanded: true }, + }, +}; diff --git a/packages/block-editor/src/components/block-patterns-list/style.scss b/packages/block-editor/src/components/block-patterns-list/style.scss index 84e95563737c3c..c46bb49b9a9016 100644 --- a/packages/block-editor/src/components/block-patterns-list/style.scss +++ b/packages/block-editor/src/components/block-patterns-list/style.scss @@ -26,6 +26,8 @@ // the bottom margin set on `...__list-item` above scroll-margin-bottom: ($grid-unit-40 + $grid-unit-30); + outline: 0; + .block-editor-block-patterns-list__item-title { flex-grow: 1; font-size: $helptext-font-size; From 0b76a258213bde016726e16949d76fed12c5a34d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Tue, 22 Oct 2024 11:40:45 +0200 Subject: [PATCH 05/31] Site editor routes: add docs for areas and prevent `edit` area from rendering when canvas is `edit` (#66309) Co-authored-by: oandregal Co-authored-by: youknowriad --- .../edit-site/src/components/layout/index.js | 22 ++++++++++--------- .../components/site-editor-routes/README.md | 20 +++++++++++++++++ 2 files changed, 32 insertions(+), 10 deletions(-) create mode 100644 packages/edit-site/src/components/site-editor-routes/README.md diff --git a/packages/edit-site/src/components/layout/index.js b/packages/edit-site/src/components/layout/index.js index d02f2905f24d85..8c150039c6df81 100644 --- a/packages/edit-site/src/components/layout/index.js +++ b/packages/edit-site/src/components/layout/index.js @@ -183,16 +183,18 @@ export default function Layout( { route } ) { ) } - { ! isMobileViewport && areas.edit && ( -
- { areas.edit } -
- ) } + { ! isMobileViewport && + areas.edit && + canvasMode !== 'edit' && ( +
+ { areas.edit } +
+ ) } { ! isMobileViewport && areas.preview && (
diff --git a/packages/edit-site/src/components/site-editor-routes/README.md b/packages/edit-site/src/components/site-editor-routes/README.md new file mode 100644 index 00000000000000..64121c8bd9a6b5 --- /dev/null +++ b/packages/edit-site/src/components/site-editor-routes/README.md @@ -0,0 +1,20 @@ +# Site Editor Routes + +## Areas + +When `canvasMode` is not `edit`, the areas avaliable to use are: + +| Area | Non-mobile viewport | Mobile viewport | +| --- | --- | --- | +| `sidebar` | Always rendered. | Only if `mobile` is not provided. | +| `content` | Rendered if provided. | Not rendered. | +| `preview` | Rendered if provided. | Not rendered. | +| `edit` | Rendered if provided. | Not rendered. | +| `mobile` | Not rendered | Rendered as full-screen, if provided. | + +When `canvasMode` is `edit`, the areas avaliable to use are: + +| Area | Non-mobile viewport | Mobile viewport | +| --- | --- | --- | +| `preview` | Rendered as full-screen, if provided. Otherwise, it'll display an empty blank sidebar. | Not rendered. | +| `mobile` | Not rendered | Rendered as full-screen, if provided. Otherwise, it'll display an empty blank sidebar. | From 58362df3d20b4ad3b2c7c9e7eae7e7999702c85f Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 22 Oct 2024 11:39:11 +0100 Subject: [PATCH 06/31] Site Editor: Remove synchronization of canvas mode into store (#66213) Co-authored-by: youknowriad Co-authored-by: ramonjd Co-authored-by: ntsekouras --- .../block-editor/use-editor-iframe-props.js | 40 +++---- .../block-editor/use-site-editor-settings.js | 19 ++-- .../edit-site/src/components/editor/index.js | 41 ++++--- .../editor/use-adapt-editor-to-canvas.js | 53 ++++++++++ .../components/global-styles-sidebar/index.js | 81 +++++++------- .../components/keyboard-shortcuts/global.js | 8 +- .../edit-site/src/components/layout/index.js | 39 +++---- .../src/components/resizable-frame/index.js | 29 +++-- .../src/components/save-panel/index.js | 60 +++++------ .../index.js | 76 ++++++++----- .../use-sync-canvas-mode-with-url.js | 73 ------------- .../src/hooks/commands/use-common-commands.js | 100 +++++++++++------- .../hooks/commands/use-edit-mode-commands.js | 32 +++--- .../hooks/commands/use-set-command-context.js | 16 ++- .../edit-site/src/store/private-actions.js | 79 -------------- .../edit-site/src/store/private-selectors.js | 11 -- packages/edit-site/src/store/reducer.js | 18 ---- packages/router/src/history.ts | 36 ++++++- 18 files changed, 387 insertions(+), 424 deletions(-) create mode 100644 packages/edit-site/src/components/editor/use-adapt-editor-to-canvas.js delete mode 100644 packages/edit-site/src/components/sync-state-with-url/use-sync-canvas-mode-with-url.js diff --git a/packages/edit-site/src/components/block-editor/use-editor-iframe-props.js b/packages/edit-site/src/components/block-editor/use-editor-iframe-props.js index 3b5c9f7fe65726..46719a00c16aad 100644 --- a/packages/edit-site/src/components/block-editor/use-editor-iframe-props.js +++ b/packages/edit-site/src/components/block-editor/use-editor-iframe-props.js @@ -6,37 +6,37 @@ import clsx from 'clsx'; /** * WordPress dependencies */ -import { useSelect, useDispatch } from '@wordpress/data'; +import { useSelect } from '@wordpress/data'; import { ENTER, SPACE } from '@wordpress/keycodes'; import { useState, useEffect } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { store as editorStore } from '@wordpress/editor'; +import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies */ import { unlock } from '../../lock-unlock'; -import { store as editSiteStore } from '../../store'; -export default function useEditorIframeProps() { - const { canvasMode, currentPostIsTrashed } = useSelect( ( select ) => { - const { getCanvasMode } = unlock( select( editSiteStore ) ); +const { useLocation, useHistory } = unlock( routerPrivateApis ); - return { - canvasMode: getCanvasMode(), - currentPostIsTrashed: - select( editorStore ).getCurrentPostAttribute( 'status' ) === - 'trash', - }; +export default function useEditorIframeProps() { + const { params } = useLocation(); + const history = useHistory(); + const { canvas = 'view' } = params; + const currentPostIsTrashed = useSelect( ( select ) => { + return ( + select( editorStore ).getCurrentPostAttribute( 'status' ) === + 'trash' + ); }, [] ); - const { setCanvasMode } = unlock( useDispatch( editSiteStore ) ); const [ isFocused, setIsFocused ] = useState( false ); useEffect( () => { - if ( canvasMode === 'edit' ) { + if ( canvas === 'edit' ) { setIsFocused( false ); } - }, [ canvasMode ] ); + }, [ canvas ] ); // In view mode, make the canvas iframe be perceived and behave as a button // to switch to edit mode, with a meaningful label and no title attribute. @@ -55,11 +55,15 @@ export default function useEditorIframeProps() { ! currentPostIsTrashed ) { event.preventDefault(); - setCanvasMode( 'edit' ); + history.push( { ...params, canvas: 'edit' }, undefined, { + transition: 'canvas-mode-edit-transition', + } ); } }, onClick: () => { - setCanvasMode( 'edit' ); + history.push( { ...params, canvas: 'edit' }, undefined, { + transition: 'canvas-mode-edit-transition', + } ); }, onClickCapture: ( event ) => { if ( currentPostIsTrashed ) { @@ -72,8 +76,8 @@ export default function useEditorIframeProps() { return { className: clsx( 'edit-site-visual-editor__editor-canvas', { - 'is-focused': isFocused && canvasMode === 'view', + 'is-focused': isFocused && canvas === 'view', } ), - ...( canvasMode === 'view' ? viewModeIframeProps : {} ), + ...( canvas === 'view' ? viewModeIframeProps : {} ), }; } diff --git a/packages/edit-site/src/components/block-editor/use-site-editor-settings.js b/packages/edit-site/src/components/block-editor/use-site-editor-settings.js index e4d70402efa8be..dcdfb157b235b6 100644 --- a/packages/edit-site/src/components/block-editor/use-site-editor-settings.js +++ b/packages/edit-site/src/components/block-editor/use-site-editor-settings.js @@ -38,22 +38,25 @@ function useNavigateToPreviousEntityRecord() { } export function useSpecificEditorSettings() { + const { params } = useLocation(); + const { canvas = 'view' } = params; const onNavigateToEntityRecord = useNavigateToEntityRecord(); - const { canvasMode, settings, shouldUseTemplateAsDefaultRenderingMode } = - useSelect( ( select ) => { - const { getEditedPostContext, getCanvasMode, getSettings } = unlock( + const { settings, shouldUseTemplateAsDefaultRenderingMode } = useSelect( + ( select ) => { + const { getEditedPostContext, getSettings } = unlock( select( editSiteStore ) ); const _context = getEditedPostContext(); return { - canvasMode: getCanvasMode(), settings: getSettings(), // TODO: The `postType` check should be removed when the default rendering mode per post type is merged. // @see https://github.com/WordPress/gutenberg/pull/62304/ shouldUseTemplateAsDefaultRenderingMode: _context?.postId && _context?.postType !== 'post', }; - }, [] ); + }, + [] + ); const defaultRenderingMode = shouldUseTemplateAsDefaultRenderingMode ? 'template-locked' : 'post-only'; @@ -65,15 +68,15 @@ export function useSpecificEditorSettings() { richEditingEnabled: true, supportsTemplateMode: true, - focusMode: canvasMode !== 'view', + focusMode: canvas !== 'view', defaultRenderingMode, onNavigateToEntityRecord, onNavigateToPreviousEntityRecord, - __unstableIsPreviewMode: canvasMode === 'view', + __unstableIsPreviewMode: canvas === 'view', }; }, [ settings, - canvasMode, + canvas, defaultRenderingMode, onNavigateToEntityRecord, onNavigateToPreviousEntityRecord, diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index c2a7730c0fee56..9058a163707997 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -48,6 +48,7 @@ import SiteIcon from '../site-icon'; import useEditorIframeProps from '../block-editor/use-editor-iframe-props'; import useEditorTitle from './use-editor-title'; import { useIsSiteEditorLoading } from '../layout/hooks'; +import { useAdaptEditorToCanvas } from './use-adapt-editor-to-canvas'; const { Editor, BackButton } = unlock( editorPrivateApis ); const { useHistory, useLocation } = unlock( routerPrivateApis ); @@ -80,13 +81,14 @@ const siteIconVariants = { export default function EditSiteEditor( { isPostsList = false } ) { const disableMotion = useReducedMotion(); const { params } = useLocation(); + const { canvas = 'view' } = params; const isLoading = useIsSiteEditorLoading(); + useAdaptEditorToCanvas( canvas ); const { editedPostType, editedPostId, contextPostType, contextPostId, - canvasMode, isEditingPage, supportsGlobalStyles, showIconLabels, @@ -97,7 +99,6 @@ export default function EditSiteEditor( { isPostsList = false } ) { const { getEditorCanvasContainerView, getEditedPostContext, - getCanvasMode, isPage, getEditedPostType, getEditedPostId, @@ -114,7 +115,6 @@ export default function EditSiteEditor( { isPostsList = false } ) { editedPostId: getEditedPostId(), contextPostType: _context?.postId ? _context.postType : undefined, contextPostId: _context?.postId ? _context.postId : undefined, - canvasMode: getCanvasMode(), isEditingPage: isPage(), supportsGlobalStyles: getCurrentTheme()?.is_block_theme, showIconLabels: get( 'core', 'showIconLabels' ), @@ -129,7 +129,7 @@ export default function EditSiteEditor( { isPostsList = false } ) { const _isPreviewingTheme = isPreviewingTheme(); const hasDefaultEditorCanvasView = ! useHasEditorCanvasContainer(); const iframeProps = useEditorIframeProps(); - const isEditMode = canvasMode === 'edit'; + const isEditMode = canvas === 'edit'; const postWithTemplate = !! contextPostId; const loadingProgressId = useInstanceId( CanvasLoader, @@ -144,16 +144,15 @@ export default function EditSiteEditor( { isPostsList = false } ) { // Forming a "block formatting context" to prevent margin collapsing. // @see https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Block_formatting_context css: - canvasMode === 'view' + canvas === 'view' ? `body{min-height: 100vh; ${ currentPostIsTrashed ? '' : 'cursor: pointer;' }}` : undefined, }, ], - [ settings.styles, canvasMode, currentPostIsTrashed ] + [ settings.styles, canvas, currentPostIsTrashed ] ); - const { setCanvasMode } = unlock( useDispatch( editSiteStore ) ); const { __unstableSetEditorMode, resetZoomLevel } = unlock( useDispatch( blockEditorStore ) ); @@ -264,7 +263,6 @@ export default function EditSiteEditor( { isPostsList = false } ) { showTooltip tooltipPosition="middle right" onClick={ () => { - setCanvasMode( 'view' ); __unstableSetEditorMode( 'edit' ); @@ -276,10 +274,29 @@ export default function EditSiteEditor( { isPostsList = false } ) { isPostsList && params?.focusMode ) { - history.push( { - page: 'gutenberg-posts-dashboard', - postType: 'post', - } ); + history.push( + { + page: 'gutenberg-posts-dashboard', + postType: 'post', + }, + undefined, + { + transition: + 'canvas-mode-view-transition', + } + ); + } else { + history.push( + { + ...params, + canvas: undefined, + }, + undefined, + { + transition: + 'canvas-mode-view-transition', + } + ); } } } > diff --git a/packages/edit-site/src/components/editor/use-adapt-editor-to-canvas.js b/packages/edit-site/src/components/editor/use-adapt-editor-to-canvas.js new file mode 100644 index 00000000000000..a09adfb7a49d53 --- /dev/null +++ b/packages/edit-site/src/components/editor/use-adapt-editor-to-canvas.js @@ -0,0 +1,53 @@ +/** + * WordPress dependencies + */ +import { useDispatch, useSelect, useRegistry } from '@wordpress/data'; +import { store as blockEditorStore } from '@wordpress/block-editor'; +import { store as editorStore } from '@wordpress/editor'; +import { useLayoutEffect } from '@wordpress/element'; +import { store as preferencesStore } from '@wordpress/preferences'; + +export function useAdaptEditorToCanvas( canvas ) { + const { clearSelectedBlock } = useDispatch( blockEditorStore ); + const { + setDeviceType, + closePublishSidebar, + setIsListViewOpened, + setIsInserterOpened, + } = useDispatch( editorStore ); + const { get: getPreference } = useSelect( preferencesStore ); + const registry = useRegistry(); + useLayoutEffect( () => { + const isMediumOrBigger = + window.matchMedia( '(min-width: 782px)' ).matches; + registry.batch( () => { + clearSelectedBlock(); + setDeviceType( 'Desktop' ); + closePublishSidebar(); + setIsInserterOpened( false ); + + // Check if the block list view should be open by default. + // If `distractionFree` mode is enabled, the block list view should not be open. + // This behavior is disabled for small viewports. + if ( + isMediumOrBigger && + canvas === 'edit' && + getPreference( 'core', 'showListViewByDefault' ) && + ! getPreference( 'core', 'distractionFree' ) + ) { + setIsListViewOpened( true ); + } else { + setIsListViewOpened( false ); + } + } ); + }, [ + canvas, + registry, + clearSelectedBlock, + setDeviceType, + closePublishSidebar, + setIsInserterOpened, + setIsListViewOpened, + getPreference, + ] ); +} diff --git a/packages/edit-site/src/components/global-styles-sidebar/index.js b/packages/edit-site/src/components/global-styles-sidebar/index.js index 2194f2edbc0f29..2b9a2669a96fe6 100644 --- a/packages/edit-site/src/components/global-styles-sidebar/index.js +++ b/packages/edit-site/src/components/global-styles-sidebar/index.js @@ -11,6 +11,7 @@ import { store as editorStore, privateApis as editorPrivateApis, } from '@wordpress/editor'; +import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies @@ -23,8 +24,11 @@ import { store as coreStore } from '@wordpress/core-data'; import DefaultSidebar from './default-sidebar'; const { interfaceStore } = unlock( editorPrivateApis ); +const { useLocation } = unlock( routerPrivateApis ); export default function GlobalStylesSidebar() { + const { params } = useLocation(); + const { canvas = 'view' } = params; const { shouldClearCanvasContainerView, isStyleBookOpened, @@ -32,43 +36,48 @@ export default function GlobalStylesSidebar() { hasRevisions, isRevisionsOpened, isRevisionsStyleBookOpened, - } = useSelect( ( select ) => { - const { getActiveComplementaryArea } = select( interfaceStore ); - const { getEditorCanvasContainerView, getCanvasMode } = unlock( - select( editSiteStore ) - ); - const canvasContainerView = getEditorCanvasContainerView(); - const _isVisualEditorMode = - 'visual' === select( editorStore ).getEditorMode(); - const _isEditCanvasMode = 'edit' === getCanvasMode(); - const _showListViewByDefault = select( preferencesStore ).get( - 'core', - 'showListViewByDefault' - ); - const { getEntityRecord, __experimentalGetCurrentGlobalStylesId } = - select( coreStore ); + } = useSelect( + ( select ) => { + const { getActiveComplementaryArea } = select( interfaceStore ); + const { getEditorCanvasContainerView } = unlock( + select( editSiteStore ) + ); + const canvasContainerView = getEditorCanvasContainerView(); + const _isVisualEditorMode = + 'visual' === select( editorStore ).getEditorMode(); + const _isEditCanvasMode = 'edit' === canvas; + const _showListViewByDefault = select( preferencesStore ).get( + 'core', + 'showListViewByDefault' + ); + const { getEntityRecord, __experimentalGetCurrentGlobalStylesId } = + select( coreStore ); - const globalStylesId = __experimentalGetCurrentGlobalStylesId(); - const globalStyles = globalStylesId - ? getEntityRecord( 'root', 'globalStyles', globalStylesId ) - : undefined; + const globalStylesId = __experimentalGetCurrentGlobalStylesId(); + const globalStyles = globalStylesId + ? getEntityRecord( 'root', 'globalStyles', globalStylesId ) + : undefined; - return { - isStyleBookOpened: 'style-book' === canvasContainerView, - shouldClearCanvasContainerView: - 'edit-site/global-styles' !== - getActiveComplementaryArea( 'core' ) || - ! _isVisualEditorMode || - ! _isEditCanvasMode, - showListViewByDefault: _showListViewByDefault, - hasRevisions: - !! globalStyles?._links?.[ 'version-history' ]?.[ 0 ]?.count, - isRevisionsStyleBookOpened: - 'global-styles-revisions:style-book' === canvasContainerView, - isRevisionsOpened: - 'global-styles-revisions' === canvasContainerView, - }; - }, [] ); + return { + isStyleBookOpened: 'style-book' === canvasContainerView, + shouldClearCanvasContainerView: + 'edit-site/global-styles' !== + getActiveComplementaryArea( 'core' ) || + ! _isVisualEditorMode || + ! _isEditCanvasMode, + showListViewByDefault: _showListViewByDefault, + hasRevisions: + !! globalStyles?._links?.[ 'version-history' ]?.[ 0 ] + ?.count, + isRevisionsStyleBookOpened: + 'global-styles-revisions:style-book' === + canvasContainerView, + isRevisionsOpened: + 'global-styles-revisions' === canvasContainerView, + }; + }, + [ canvas ] + ); const { setEditorCanvasContainerView } = unlock( useDispatch( editSiteStore ) ); @@ -77,7 +86,7 @@ export default function GlobalStylesSidebar() { if ( shouldClearCanvasContainerView ) { setEditorCanvasContainerView( undefined ); } - }, [ shouldClearCanvasContainerView ] ); + }, [ shouldClearCanvasContainerView, setEditorCanvasContainerView ] ); const { setIsListViewOpened } = useDispatch( editorStore ); diff --git a/packages/edit-site/src/components/keyboard-shortcuts/global.js b/packages/edit-site/src/components/keyboard-shortcuts/global.js index 2e71cf88202069..8ab9723e42ea65 100644 --- a/packages/edit-site/src/components/keyboard-shortcuts/global.js +++ b/packages/edit-site/src/components/keyboard-shortcuts/global.js @@ -5,6 +5,7 @@ import { useShortcut } from '@wordpress/keyboard-shortcuts'; import { useDispatch, useSelect } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; import { store as editorStore } from '@wordpress/editor'; +import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies @@ -12,12 +13,14 @@ import { store as editorStore } from '@wordpress/editor'; import { store as editSiteStore } from '../../store'; import { unlock } from '../../lock-unlock'; +const { useHistory } = unlock( routerPrivateApis ); + function KeyboardShortcutsGlobal() { const { __experimentalGetDirtyEntityRecords, isSavingEntityRecord } = useSelect( coreStore ); const { hasNonPostEntityChanges } = useSelect( editorStore ); - const { getCanvasMode } = unlock( useSelect( editSiteStore ) ); const { setIsSaveViewOpened } = useDispatch( editSiteStore ); + const history = useHistory(); useShortcut( 'core/edit-site/save', ( event ) => { event.preventDefault(); @@ -28,7 +31,8 @@ function KeyboardShortcutsGlobal() { isSavingEntityRecord( record.kind, record.name, record.key ) ); const _hasNonPostEntityChanges = hasNonPostEntityChanges(); - const isViewMode = getCanvasMode() === 'view'; + const isViewMode = + history.getLocationWithParams().params.canvas === 'view'; if ( ( ! hasDirtyEntities || ! _hasNonPostEntityChanges || isSaving ) && ! isViewMode diff --git a/packages/edit-site/src/components/layout/index.js b/packages/edit-site/src/components/layout/index.js index 8c150039c6df81..3b9769d470f518 100644 --- a/packages/edit-site/src/components/layout/index.js +++ b/packages/edit-site/src/components/layout/index.js @@ -6,7 +6,6 @@ import clsx from 'clsx'; /** * WordPress dependencies */ -import { useSelect } from '@wordpress/data'; import { __unstableMotion as motion, __unstableAnimatePresence as AnimatePresence, @@ -27,12 +26,12 @@ import { privateApis as editorPrivateApis, } from '@wordpress/editor'; import { privateApis as coreCommandsPrivateApis } from '@wordpress/core-commands'; +import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies */ import ErrorBoundary from '../error-boundary'; -import { store as editSiteStore } from '../../store'; import { default as SiteHub, SiteHubMobile } from '../site-hub'; import ResizableFrame from '../resizable-frame'; import { unlock } from '../../lock-unlock'; @@ -43,25 +42,20 @@ import useMovingAnimation from './animation'; import SidebarContent from '../sidebar'; import SaveHub from '../save-hub'; import SavePanel from '../save-panel'; -import useSyncCanvasModeWithURL from '../sync-state-with-url/use-sync-canvas-mode-with-url'; const { useCommands } = unlock( coreCommandsPrivateApis ); const { useGlobalStyle } = unlock( blockEditorPrivateApis ); const { NavigableRegion } = unlock( editorPrivateApis ); +const { useLocation } = unlock( routerPrivateApis ); const ANIMATION_DURATION = 0.3; export default function Layout( { route } ) { - useSyncCanvasModeWithURL(); + const { params } = useLocation(); + const { canvas = 'view' } = params; useCommands(); const isMobileViewport = useViewportMatch( 'medium', '<' ); const toggleRef = useRef(); - const { canvasMode } = useSelect( ( select ) => { - const { getCanvasMode } = unlock( select( editSiteStore ) ); - return { - canvasMode: getCanvasMode(), - }; - }, [] ); const navigateRegionsProps = useNavigateRegions(); const disableMotion = useReducedMotion(); const [ canvasResizer, canvasSize ] = useResizeObserver(); @@ -70,26 +64,19 @@ export default function Layout( { route } ) { useState( false ); const { name: routeKey, areas, widths } = route; const animationRef = useMovingAnimation( { - triggerAnimationOnChange: canvasMode, + triggerAnimationOnChange: routeKey + '-' + canvas, } ); const [ backgroundColor ] = useGlobalStyle( 'color.background' ); const [ gradientValue ] = useGlobalStyle( 'color.gradient' ); - const previousCanvaMode = usePrevious( canvasMode ); + const previousCanvaMode = usePrevious( canvas ); useEffect( () => { if ( previousCanvaMode === 'edit' ) { toggleRef.current?.focus(); } // Should not depend on the previous canvas mode value but the next. // eslint-disable-next-line react-hooks/exhaustive-deps - }, [ canvasMode ] ); - - // Synchronizing the URL with the store value of canvasMode happens in an effect - // This condition ensures the component is only rendered after the synchronization happens - // which prevents any animations due to potential canvasMode value change. - if ( canvasMode === 'init' ) { - return null; - } + }, [ canvas ] ); return ( <> @@ -103,7 +90,7 @@ export default function Layout( { route } ) { 'edit-site-layout', navigateRegionsProps.className, { - 'is-full-canvas': canvasMode === 'edit', + 'is-full-canvas': canvas === 'edit', } ) } > @@ -118,7 +105,7 @@ export default function Layout( { route } ) { className="edit-site-layout__sidebar-region" > - { canvasMode === 'view' && ( + { canvas === 'view' && ( - { canvasMode !== 'edit' && ( + { canvas !== 'edit' && ( unlock( select( editSiteStore ) ).getCanvasMode(), - [] - ); - const { setCanvasMode } = unlock( useDispatch( editSiteStore ) ); + const FRAME_TRANSITION = { type: 'tween', duration: isResizing ? 0 : 0.5 }; const frameRef = useRef( null ); const resizableHandleHelpId = useInstanceId( @@ -158,7 +158,16 @@ function ResizableFrame( { setFrameSize( INITIAL_FRAME_SIZE ); } else { // Trigger full screen if the frame is resized far enough to the left. - setCanvasMode( 'edit' ); + history.push( + { + ...params, + canvas: 'edit', + }, + undefined, + { + transition: 'canvas-mode-edit-transition', + } + ); } }; @@ -237,7 +246,7 @@ function ResizableFrame( { } } } whileHover={ - canvasMode === 'view' + canvas === 'view' ? { scale: 1.005, transition: { @@ -275,7 +284,7 @@ function ResizableFrame( { onMouseOver={ () => setShouldShowHandle( true ) } onMouseOut={ () => setShouldShowHandle( false ) } handleComponent={ { - [ isRTL() ? 'right' : 'left' ]: canvasMode === 'view' && ( + [ isRTL() ? 'right' : 'left' ]: canvas === 'view' && ( <> { /* Disable reason: role="separator" does in fact support aria-valuenow */ } diff --git a/packages/edit-site/src/components/save-panel/index.js b/packages/edit-site/src/components/save-panel/index.js index 9b00a39fd78948..d7817d5b3c1bb2 100644 --- a/packages/edit-site/src/components/save-panel/index.js +++ b/packages/edit-site/src/components/save-panel/index.js @@ -15,6 +15,8 @@ import { import { useDispatch, useSelect } from '@wordpress/data'; import { __, sprintf } from '@wordpress/i18n'; import { store as coreStore } from '@wordpress/core-data'; +import { privateApis as routerPrivateApis } from '@wordpress/router'; +import { useEffect } from '@wordpress/element'; /** * Internal dependencies @@ -27,6 +29,7 @@ import { isPreviewingTheme } from '../../utils/is-previewing-theme'; const { EntitiesSavedStatesExtensible, NavigableRegion } = unlock( privateApis ); +const { useLocation } = unlock( routerPrivateApis ); const EntitiesSavedStatesForPreview = ( { onClose } ) => { const isDirtyProps = useEntitiesSavedStatesIsDirty(); @@ -87,41 +90,36 @@ const _EntitiesSavedStates = ( { onClose, renderDialog = undefined } ) => { }; export default function SavePanel() { - const { isSaveViewOpen, canvasMode, isDirty, isSaving } = useSelect( - ( select ) => { - const { - __experimentalGetDirtyEntityRecords, - isSavingEntityRecord, - isResolving, - } = select( coreStore ); - const dirtyEntityRecords = __experimentalGetDirtyEntityRecords(); - const isActivatingTheme = isResolving( 'activateTheme' ); - const { isSaveViewOpened, getCanvasMode } = unlock( - select( editSiteStore ) - ); + const { params } = useLocation(); + const { canvas = 'view' } = params; + const { isSaveViewOpen, isDirty, isSaving } = useSelect( ( select ) => { + const { + __experimentalGetDirtyEntityRecords, + isSavingEntityRecord, + isResolving, + } = select( coreStore ); + const dirtyEntityRecords = __experimentalGetDirtyEntityRecords(); + const isActivatingTheme = isResolving( 'activateTheme' ); + const { isSaveViewOpened } = unlock( select( editSiteStore ) ); - // The currently selected entity to display. - // Typically template or template part in the site editor. - return { - isSaveViewOpen: isSaveViewOpened(), - canvasMode: getCanvasMode(), - isDirty: dirtyEntityRecords.length > 0, - isSaving: - dirtyEntityRecords.some( ( record ) => - isSavingEntityRecord( - record.kind, - record.name, - record.key - ) - ) || isActivatingTheme, - }; - }, - [] - ); + // The currently selected entity to display. + // Typically template or template part in the site editor. + return { + isSaveViewOpen: isSaveViewOpened(), + isDirty: dirtyEntityRecords.length > 0, + isSaving: + dirtyEntityRecords.some( ( record ) => + isSavingEntityRecord( record.kind, record.name, record.key ) + ) || isActivatingTheme, + }; + }, [] ); const { setIsSaveViewOpened } = useDispatch( editSiteStore ); const onClose = () => setIsSaveViewOpened( false ); + useEffect( () => { + setIsSaveViewOpened( false ); + }, [ canvas, setIsSaveViewOpened ] ); - if ( canvasMode === 'view' ) { + if ( canvas === 'view' ) { return isSaveViewOpen ? ( !! select( @@ -48,7 +51,16 @@ export function SidebarNavigationItemGlobalStyles( props ) { { ...props } onClick={ () => { // Switch to edit mode. - setCanvasMode( 'edit' ); + history.push( + { + ...params, + canvas: 'edit', + }, + undefined, + { + transition: 'canvas-mode-edit-transition', + } + ); // Open global styles sidebar. openGeneralSidebar( 'edit-site/global-styles' ); } } @@ -57,45 +69,51 @@ export function SidebarNavigationItemGlobalStyles( props ) { } export default function SidebarNavigationScreenGlobalStyles( { backPath } ) { + const history = useHistory(); + const { params } = useLocation(); + const { canvas = 'view' } = params; const { revisions, isLoading: isLoadingRevisions } = useGlobalStylesRevisions(); const { openGeneralSidebar } = useDispatch( editSiteStore ); const { setIsListViewOpened } = useDispatch( editorStore ); const isMobileViewport = useViewportMatch( 'medium', '<' ); - const { setCanvasMode, setEditorCanvasContainerView } = unlock( + const { setEditorCanvasContainerView } = unlock( useDispatch( editSiteStore ) ); - const { isViewMode, isStyleBookOpened, revisionsCount } = useSelect( - ( select ) => { - const { getCanvasMode, getEditorCanvasContainerView } = unlock( - select( editSiteStore ) - ); - const { getEntityRecord, __experimentalGetCurrentGlobalStylesId } = - select( coreStore ); - const globalStylesId = __experimentalGetCurrentGlobalStylesId(); - const globalStyles = globalStylesId - ? getEntityRecord( 'root', 'globalStyles', globalStylesId ) - : undefined; - return { - isViewMode: 'view' === getCanvasMode(), - isStyleBookOpened: - 'style-book' === getEditorCanvasContainerView(), - revisionsCount: - globalStyles?._links?.[ 'version-history' ]?.[ 0 ]?.count ?? - 0, - }; - }, - [] - ); + const { isStyleBookOpened, revisionsCount } = useSelect( ( select ) => { + const { getEditorCanvasContainerView } = unlock( + select( editSiteStore ) + ); + const { getEntityRecord, __experimentalGetCurrentGlobalStylesId } = + select( coreStore ); + const globalStylesId = __experimentalGetCurrentGlobalStylesId(); + const globalStyles = globalStylesId + ? getEntityRecord( 'root', 'globalStyles', globalStylesId ) + : undefined; + return { + isStyleBookOpened: 'style-book' === getEditorCanvasContainerView(), + revisionsCount: + globalStyles?._links?.[ 'version-history' ]?.[ 0 ]?.count ?? 0, + }; + }, [] ); const { set: setPreference } = useDispatch( preferencesStore ); const openGlobalStyles = useCallback( async () => { + history.push( + { + ...params, + canvas: 'edit', + }, + undefined, + { + transition: 'canvas-mode-edit-transition', + } + ); return Promise.all( [ setPreference( 'core', 'distractionFree', false ), - setCanvasMode( 'edit' ), openGeneralSidebar( 'edit-site/global-styles' ), ] ); - }, [ setCanvasMode, openGeneralSidebar, setPreference ] ); + }, [ history, params, openGeneralSidebar, setPreference ] ); const openStyleBook = useCallback( async () => { await openGlobalStyles(); @@ -166,7 +184,7 @@ export default function SidebarNavigationScreenGlobalStyles( { backPath } ) { } /> - { isStyleBookOpened && ! isMobileViewport && isViewMode && ( + { isStyleBookOpened && ! isMobileViewport && canvas === 'view' && ( false } diff --git a/packages/edit-site/src/components/sync-state-with-url/use-sync-canvas-mode-with-url.js b/packages/edit-site/src/components/sync-state-with-url/use-sync-canvas-mode-with-url.js deleted file mode 100644 index d9295f83ee2452..00000000000000 --- a/packages/edit-site/src/components/sync-state-with-url/use-sync-canvas-mode-with-url.js +++ /dev/null @@ -1,73 +0,0 @@ -/** - * WordPress dependencies - */ -import { useEffect, useRef } from '@wordpress/element'; -import { useSelect, useDispatch } from '@wordpress/data'; -import { privateApis as routerPrivateApis } from '@wordpress/router'; - -/** - * Internal dependencies - */ -import { store as editSiteStore } from '../../store'; -import { unlock } from '../../lock-unlock'; - -const { useLocation, useHistory } = unlock( routerPrivateApis ); - -export default function useSyncCanvasModeWithURL() { - const history = useHistory(); - const { params } = useLocation(); - const canvasMode = useSelect( - ( select ) => unlock( select( editSiteStore ) ).getCanvasMode(), - [] - ); - const { setCanvasMode } = unlock( useDispatch( editSiteStore ) ); - const currentCanvasModeRef = useRef( canvasMode ); - const { canvas: canvasInUrl } = params; - const currentCanvasInUrlRef = useRef( canvasInUrl ); - const currentUrlParamsRef = useRef( params ); - useEffect( () => { - currentUrlParamsRef.current = params; - }, [ params ] ); - - useEffect( () => { - currentCanvasModeRef.current = canvasMode; - if ( canvasMode === 'init' ) { - return; - } - - if ( - canvasMode === 'edit' && - currentCanvasInUrlRef.current !== canvasMode - ) { - history.push( { - ...currentUrlParamsRef.current, - canvas: 'edit', - } ); - } - - if ( - canvasMode === 'view' && - currentCanvasInUrlRef.current !== undefined - ) { - history.push( { - ...currentUrlParamsRef.current, - canvas: undefined, - } ); - } - }, [ canvasMode, history ] ); - - useEffect( () => { - currentCanvasInUrlRef.current = canvasInUrl; - if ( - canvasInUrl !== 'edit' && - currentCanvasModeRef.current !== 'view' - ) { - setCanvasMode( 'view' ); - } else if ( - canvasInUrl === 'edit' && - currentCanvasModeRef.current !== 'edit' - ) { - setCanvasMode( 'edit' ); - } - }, [ canvasInUrl, setCanvasMode ] ); -} diff --git a/packages/edit-site/src/hooks/commands/use-common-commands.js b/packages/edit-site/src/hooks/commands/use-common-commands.js index ca6e2d1c6b45dd..536817e88d3a47 100644 --- a/packages/edit-site/src/hooks/commands/use-common-commands.js +++ b/packages/edit-site/src/hooks/commands/use-common-commands.js @@ -29,13 +29,10 @@ const { useGlobalStylesReset } = unlock( blockEditorPrivateApis ); const { useHistory, useLocation } = unlock( routerPrivateApis ); function useGlobalStylesOpenStylesCommands() { - const { openGeneralSidebar, setCanvasMode } = unlock( - useDispatch( editSiteStore ) - ); + const { openGeneralSidebar } = unlock( useDispatch( editSiteStore ) ); const { params } = useLocation(); - const { getCanvasMode } = unlock( useSelect( editSiteStore ) ); + const { canvas = 'view' } = params; const history = useHistory(); - const isBlockBasedTheme = useSelect( ( select ) => { return select( coreStore ).getCurrentTheme().is_block_theme; }, [] ); @@ -57,22 +54,21 @@ function useGlobalStylesOpenStylesCommands() { canvas: 'edit', } ); } - if ( params.postId && getCanvasMode() !== 'edit' ) { - setCanvasMode( 'edit' ); + if ( params.postId && canvas !== 'edit' ) { + history.push( + { ...params, canvas: 'edit' }, + undefined, + { + transition: 'canvas-mode-edit-transition', + } + ); } openGeneralSidebar( 'edit-site/global-styles' ); }, icon: styles, }, ]; - }, [ - history, - openGeneralSidebar, - setCanvasMode, - getCanvasMode, - isBlockBasedTheme, - params.postId, - ] ); + }, [ history, openGeneralSidebar, params, canvas, isBlockBasedTheme ] ); return { isLoading: false, @@ -81,11 +77,9 @@ function useGlobalStylesOpenStylesCommands() { } function useGlobalStylesToggleWelcomeGuideCommands() { - const { openGeneralSidebar, setCanvasMode } = unlock( - useDispatch( editSiteStore ) - ); + const { openGeneralSidebar } = unlock( useDispatch( editSiteStore ) ); const { params } = useLocation(); - const { getCanvasMode } = unlock( useSelect( editSiteStore ) ); + const { canvas = 'view' } = params; const { set } = useDispatch( preferencesStore ); const history = useHistory(); @@ -110,8 +104,17 @@ function useGlobalStylesToggleWelcomeGuideCommands() { canvas: 'edit', } ); } - if ( params.postId && getCanvasMode() !== 'edit' ) { - setCanvasMode( 'edit' ); + if ( params.postId && canvas !== 'edit' ) { + history.push( + { + ...params, + canvas: 'edit', + }, + undefined, + { + transition: 'canvas-mode-edit-transition', + } + ); } openGeneralSidebar( 'edit-site/global-styles' ); set( 'core/edit-site', 'welcomeGuideStyles', true ); @@ -127,11 +130,10 @@ function useGlobalStylesToggleWelcomeGuideCommands() { }, [ history, openGeneralSidebar, - setCanvasMode, - getCanvasMode, + canvas, isBlockBasedTheme, set, - params.postId, + params, ] ); return { @@ -167,9 +169,11 @@ function useGlobalStylesResetCommands() { } function useGlobalStylesOpenCssCommands() { - const { openGeneralSidebar, setEditorCanvasContainerView, setCanvasMode } = - unlock( useDispatch( editSiteStore ) ); + const { openGeneralSidebar, setEditorCanvasContainerView } = unlock( + useDispatch( editSiteStore ) + ); const { params } = useLocation(); + const { canvas = 'view' } = params; const history = useHistory(); const { canEditCSS } = useSelect( ( select ) => { const { getEntityRecord, __experimentalGetCurrentGlobalStylesId } = @@ -184,7 +188,6 @@ function useGlobalStylesOpenCssCommands() { canEditCSS: !! globalStyles?._links?.[ 'wp:action-edit-css' ], }; }, [] ); - const { getCanvasMode } = unlock( useSelect( editSiteStore ) ); const commands = useMemo( () => { if ( ! canEditCSS ) { @@ -204,8 +207,17 @@ function useGlobalStylesOpenCssCommands() { canvas: 'edit', } ); } - if ( params.postId && getCanvasMode() !== 'edit' ) { - setCanvasMode( 'edit' ); + if ( params.postId && canvas !== 'edit' ) { + history.push( + { + ...params, + canvas: 'edit', + }, + undefined, + { + transition: 'canvas-mode-edit-transition', + } + ); } openGeneralSidebar( 'edit-site/global-styles' ); setEditorCanvasContainerView( 'global-styles-css' ); @@ -217,9 +229,8 @@ function useGlobalStylesOpenCssCommands() { openGeneralSidebar, setEditorCanvasContainerView, canEditCSS, - getCanvasMode, - setCanvasMode, - params.postId, + canvas, + params, ] ); return { isLoading: false, @@ -228,10 +239,11 @@ function useGlobalStylesOpenCssCommands() { } function useGlobalStylesOpenRevisionsCommands() { - const { openGeneralSidebar, setEditorCanvasContainerView, setCanvasMode } = - unlock( useDispatch( editSiteStore ) ); - const { getCanvasMode } = unlock( useSelect( editSiteStore ) ); + const { openGeneralSidebar, setEditorCanvasContainerView } = unlock( + useDispatch( editSiteStore ) + ); const { params } = useLocation(); + const { canvas = 'view' } = params; const history = useHistory(); const hasRevisions = useSelect( ( select ) => { const { getEntityRecord, __experimentalGetCurrentGlobalStylesId } = @@ -261,8 +273,17 @@ function useGlobalStylesOpenRevisionsCommands() { canvas: 'edit', } ); } - if ( params.postId && getCanvasMode() !== 'edit' ) { - setCanvasMode( 'edit' ); + if ( params.postId && canvas !== 'edit' ) { + history.push( + { + ...params, + canvas: 'edit', + }, + undefined, + { + transition: 'canvas-mode-edit-transition', + } + ); } openGeneralSidebar( 'edit-site/global-styles' ); setEditorCanvasContainerView( 'global-styles-revisions' ); @@ -274,9 +295,8 @@ function useGlobalStylesOpenRevisionsCommands() { history, openGeneralSidebar, setEditorCanvasContainerView, - getCanvasMode, - setCanvasMode, - params.postId, + canvas, + params, ] ); return { diff --git a/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js b/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js index d0064a947001a2..97283044193892 100644 --- a/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js +++ b/packages/edit-site/src/hooks/commands/use-edit-mode-commands.js @@ -20,26 +20,22 @@ import { unlock } from '../../lock-unlock'; import { TEMPLATE_POST_TYPE } from '../../utils/constants'; import { useLink } from '../../components/routes/link'; -const { useHistory } = unlock( routerPrivateApis ); +const { useHistory, useLocation } = unlock( routerPrivateApis ); function usePageContentFocusCommands() { const { record: template } = useEditedEntityRecord(); - const { isPage, canvasMode, templateId, currentPostType } = useSelect( - ( select ) => { - const { isPage: _isPage, getCanvasMode } = unlock( - select( editSiteStore ) - ); - const { getCurrentPostType, getCurrentTemplateId } = - select( editorStore ); - return { - isPage: _isPage(), - canvasMode: getCanvasMode(), - templateId: getCurrentTemplateId(), - currentPostType: getCurrentPostType(), - }; - }, - [] - ); + const { params } = useLocation(); + const { canvas = 'view' } = params; + const { isPage, templateId, currentPostType } = useSelect( ( select ) => { + const { isPage: _isPage } = unlock( select( editSiteStore ) ); + const { getCurrentPostType, getCurrentTemplateId } = + select( editorStore ); + return { + isPage: _isPage(), + templateId: getCurrentTemplateId(), + currentPostType: getCurrentPostType(), + }; + }, [] ); const { onClick: editTemplate } = useLink( { postType: 'wp_template', @@ -48,7 +44,7 @@ function usePageContentFocusCommands() { const { setRenderingMode } = useDispatch( editorStore ); - if ( ! isPage || canvasMode !== 'edit' ) { + if ( ! isPage || canvas !== 'edit' ) { return { isLoading: false, commands: [] }; } diff --git a/packages/edit-site/src/hooks/commands/use-set-command-context.js b/packages/edit-site/src/hooks/commands/use-set-command-context.js index 30f7f7ce258c61..e27c4ca91582fd 100644 --- a/packages/edit-site/src/hooks/commands/use-set-command-context.js +++ b/packages/edit-site/src/hooks/commands/use-set-command-context.js @@ -4,34 +4,32 @@ import { useSelect } from '@wordpress/data'; import { privateApis as commandsPrivateApis } from '@wordpress/commands'; import { store as blockEditorStore } from '@wordpress/block-editor'; +import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies */ -import { store as editSiteStore } from '../../store'; import { unlock } from '../../lock-unlock'; import { useHasEditorCanvasContainer } from '../../components/editor-canvas-container'; const { useCommandContext } = unlock( commandsPrivateApis ); +const { useLocation } = unlock( routerPrivateApis ); /** * React hook used to set the correct command context based on the current state. */ export default function useSetCommandContext() { - const { hasBlockSelected, canvasMode } = useSelect( ( select ) => { - const { getCanvasMode } = unlock( select( editSiteStore ) ); - const { getBlockSelectionStart } = select( blockEditorStore ); - return { - canvasMode: getCanvasMode(), - hasBlockSelected: getBlockSelectionStart(), - }; + const { params } = useLocation(); + const { canvas = 'view' } = params; + const hasBlockSelected = useSelect( ( select ) => { + return select( blockEditorStore ).getBlockSelectionStart(); }, [] ); const hasEditorCanvasContainer = useHasEditorCanvasContainer(); // Sets the right context for the command palette let commandContext = 'site-editor'; - if ( canvasMode === 'edit' ) { + if ( canvas === 'edit' ) { commandContext = 'entity-edit'; } if ( hasBlockSelected ) { diff --git a/packages/edit-site/src/store/private-actions.js b/packages/edit-site/src/store/private-actions.js index 1c5924a292765b..1db3873acedda2 100644 --- a/packages/edit-site/src/store/private-actions.js +++ b/packages/edit-site/src/store/private-actions.js @@ -1,82 +1,3 @@ -/** - * WordPress dependencies - */ -import { store as blockEditorStore } from '@wordpress/block-editor'; -import { store as preferencesStore } from '@wordpress/preferences'; -import { store as editorStore } from '@wordpress/editor'; - -/** - * Action that switches the canvas mode. - * - * @param {?string} mode Canvas mode. - */ -export const setCanvasMode = - ( mode ) => - ( { registry, dispatch } ) => { - const isMediumOrBigger = - window.matchMedia( '(min-width: 782px)' ).matches; - const switchCanvasMode = () => { - registry.batch( () => { - registry.dispatch( blockEditorStore ).clearSelectedBlock(); - registry.dispatch( editorStore ).setDeviceType( 'Desktop' ); - const isPublishSidebarOpened = registry - .select( editorStore ) - .isPublishSidebarOpened(); - dispatch( { - type: 'SET_CANVAS_MODE', - mode, - } ); - const isEditMode = mode === 'edit'; - if ( isPublishSidebarOpened && ! isEditMode ) { - registry.dispatch( editorStore ).closePublishSidebar(); - } - - // Check if the block list view should be open by default. - // If `distractionFree` mode is enabled, the block list view should not be open. - // This behavior is disabled for small viewports. - if ( - isMediumOrBigger && - isEditMode && - registry - .select( preferencesStore ) - .get( 'core', 'showListViewByDefault' ) && - ! registry - .select( preferencesStore ) - .get( 'core', 'distractionFree' ) - ) { - registry - .dispatch( editorStore ) - .setIsListViewOpened( true ); - } else { - registry - .dispatch( editorStore ) - .setIsListViewOpened( false ); - } - registry.dispatch( editorStore ).setIsInserterOpened( false ); - } ); - }; - - /* - * Skip transition in mobile, otherwise it crashes the browser. - * See: https://github.com/WordPress/gutenberg/pull/63002. - */ - if ( ! isMediumOrBigger || ! document.startViewTransition ) { - switchCanvasMode(); - } else { - document.documentElement.classList.add( - `canvas-mode-${ mode }-transition` - ); - const transition = document.startViewTransition( () => - switchCanvasMode() - ); - transition.finished.finally( () => { - document.documentElement.classList.remove( - `canvas-mode-${ mode }-transition` - ); - } ); - } - }; - /** * Action that switches the editor canvas container view. * diff --git a/packages/edit-site/src/store/private-selectors.js b/packages/edit-site/src/store/private-selectors.js index d0f1d3f4196008..b7c14534419582 100644 --- a/packages/edit-site/src/store/private-selectors.js +++ b/packages/edit-site/src/store/private-selectors.js @@ -1,14 +1,3 @@ -/** - * Returns the current canvas mode. - * - * @param {Object} state Global application state. - * - * @return {string} Canvas mode. - */ -export function getCanvasMode( state ) { - return state.canvasMode; -} - /** * Returns the editor canvas container view. * diff --git a/packages/edit-site/src/store/reducer.js b/packages/edit-site/src/store/reducer.js index 951f004adc9af5..3ce067c25c1954 100644 --- a/packages/edit-site/src/store/reducer.js +++ b/packages/edit-site/src/store/reducer.js @@ -60,27 +60,10 @@ export function saveViewPanel( state = false, action ) { switch ( action.type ) { case 'SET_IS_SAVE_VIEW_OPENED': return action.isOpen; - case 'SET_CANVAS_MODE': - return false; } return state; } -/** - * Reducer used to track the site editor canvas mode (edit or view). - * - * @param {Object} state Current state. - * @param {Object} action Dispatched action. - */ -function canvasMode( state = 'init', action ) { - switch ( action.type ) { - case 'SET_CANVAS_MODE': - return action.mode; - } - - return state; -} - /** * Reducer used to track the site editor canvas container view. * Default is `undefined`, denoting the default, visual block editor. @@ -111,7 +94,6 @@ export default combineReducers( { settings, editedPost, saveViewPanel, - canvasMode, editorCanvasContainerView, routes, } ); diff --git a/packages/router/src/history.ts b/packages/router/src/history.ts index e046522a751894..6cbef108eec206 100644 --- a/packages/router/src/history.ts +++ b/packages/router/src/history.ts @@ -12,6 +12,10 @@ export interface EnhancedHistory extends BrowserHistory { getLocationWithParams: () => Location; } +interface PushOptions { + transition?: string; +} + const history = createBrowserHistory(); const originalHistoryPush = history.push; @@ -32,9 +36,35 @@ function preserveThemePreview( params: Record< string, any > ) { return { ...params, wp_theme_preview: currentThemePreview }; } -function push( params: Record< string, any >, state: Record< string, any > ) { - const search = buildQueryString( preserveThemePreview( params ) ); - return originalHistoryPush.call( history, { search }, state ); +function push( + params: Record< string, any >, + state: Record< string, any >, + options: PushOptions = {} +) { + const performPush = () => { + const search = buildQueryString( preserveThemePreview( params ) ); + return originalHistoryPush.call( history, { search }, state ); + }; + + /* + * Skip transition in mobile, otherwise it crashes the browser. + * See: https://github.com/WordPress/gutenberg/pull/63002. + */ + const isMediumOrBigger = window.matchMedia( '(min-width: 782px)' ).matches; + if ( + ! isMediumOrBigger || + // @ts-expect-error + ! document.startViewTransition || + ! options.transition + ) { + return performPush(); + } + document.documentElement.classList.add( options.transition ); + // @ts-expect-error + const transition = document.startViewTransition( () => performPush() ); + transition.finished.finally( () => { + document.documentElement.classList.remove( options.transition ?? '' ); + } ); } function replace( From c0317dd12cccf08ef7eda737e7276b5f7e548cac Mon Sep 17 00:00:00 2001 From: James Koster Date: Tue, 22 Oct 2024 11:40:59 +0100 Subject: [PATCH 07/31] Data views: Fix alignment of action items in list layout (#66273) Co-authored-by: jameskoster Co-authored-by: stokesman --- packages/dataviews/src/dataviews-layouts/list/style.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/dataviews/src/dataviews-layouts/list/style.scss b/packages/dataviews/src/dataviews-layouts/list/style.scss index 9a3128c14b76a7..429f2397c96019 100644 --- a/packages/dataviews/src/dataviews-layouts/list/style.scss +++ b/packages/dataviews/src/dataviews-layouts/list/style.scss @@ -33,7 +33,7 @@ ul.dataviews-view-list { .dataviews-view-list__item-actions { flex-basis: min-content; overflow: unset; - margin-inline: $grid-unit-10 0; + padding-inline-end: $grid-unit-05; .components-button { opacity: 1; From e43a1c574959eb835f34b92479b7b6b4ff5ff8ea Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Tue, 22 Oct 2024 13:17:50 +0200 Subject: [PATCH 08/31] Pull request automation: use full npm install (#66314) Remove single-package installation from this workflow that creates problems when migrating to npm workspaces. The regular npm install workflow is frequently available in cache. --- Co-authored-by: sirreal Co-authored-by: gziolo --- .github/workflows/pull-request-automation.yml | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/.github/workflows/pull-request-automation.yml b/.github/workflows/pull-request-automation.yml index 9aecafc2009e7f..cf37fa00c060bf 100644 --- a/.github/workflows/pull-request-automation.yml +++ b/.github/workflows/pull-request-automation.yml @@ -17,24 +17,8 @@ jobs: ref: trunk show-progress: ${{ runner.debug == '1' && 'true' || 'false' }} - - name: Use desired version of Node.js - uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4 - with: - node-version-file: '.nvmrc' - check-latest: true - - - name: Cache NPM packages - uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 # v4.1.1 - with: - # npm cache files are stored in `~/.npm` on Linux/macOS - path: ~/.npm - key: ${{ runner.os }}-node-${{ matrix.node }}-npm-pr-automation-cache-${{ hashFiles('**/package-lock.json') }} - - # Changing into the action's directory and running `npm install` is much - # faster than a full project-wide `npm ci`. - - name: Install NPM dependencies - run: npm install - working-directory: packages/project-management-automation + - name: Setup Node.js and install dependencies + uses: ./.github/setup-node - uses: ./packages/project-management-automation with: From d0771cda1bdc8d4d78c956f4fffda04182572967 Mon Sep 17 00:00:00 2001 From: Marin Atanasov <8436925+tyxla@users.noreply.github.com> Date: Tue, 22 Oct 2024 14:34:25 +0300 Subject: [PATCH 09/31] Edit Site: Fix canvasMode var (#66316) Co-authored-by: tyxla Co-authored-by: ciampo Co-authored-by: Mamaduka Co-authored-by: sirreal --- .../edit-site/src/components/layout/index.js | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/edit-site/src/components/layout/index.js b/packages/edit-site/src/components/layout/index.js index 3b9769d470f518..12799f46fbe348 100644 --- a/packages/edit-site/src/components/layout/index.js +++ b/packages/edit-site/src/components/layout/index.js @@ -170,18 +170,16 @@ export default function Layout( { route } ) {
) } - { ! isMobileViewport && - areas.edit && - canvasMode !== 'edit' && ( -
- { areas.edit } -
- ) } + { ! isMobileViewport && areas.edit && canvas !== 'edit' && ( +
+ { areas.edit } +
+ ) } { ! isMobileViewport && areas.preview && (
From 9fcb43b679d957abe4c051fbcdf17a70bdb84e0f Mon Sep 17 00:00:00 2001 From: Marin Atanasov <8436925+tyxla@users.noreply.github.com> Date: Tue, 22 Oct 2024 15:13:52 +0300 Subject: [PATCH 10/31] Update a few function definitions (#66315) Co-authored-by: tyxla Co-authored-by: ciampo --- packages/components/src/spacer/hook.ts | 5 +++-- packages/data-controls/src/index.ts | 4 +++- packages/fields/src/mutation/index.ts | 6 +++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/components/src/spacer/hook.ts b/packages/components/src/spacer/hook.ts index 82d36baa5e202f..3ef4b21e104c74 100644 --- a/packages/components/src/spacer/hook.ts +++ b/packages/components/src/spacer/hook.ts @@ -12,8 +12,9 @@ import { space } from '../utils/space'; import { rtl, useCx } from '../utils'; import type { SpacerProps } from './types'; -const isDefined = < T >( o: T ): o is Exclude< T, null | undefined > => - typeof o !== 'undefined' && o !== null; +function isDefined< T >( o: T ): o is Exclude< T, null | undefined > { + return typeof o !== 'undefined' && o !== null; +} export function useSpacer( props: WordPressComponentProps< SpacerProps, 'div' > diff --git a/packages/data-controls/src/index.ts b/packages/data-controls/src/index.ts index 9edc6502ef881f..c0898d214224f5 100644 --- a/packages/data-controls/src/index.ts +++ b/packages/data-controls/src/index.ts @@ -154,7 +154,9 @@ export const __unstableAwaitPromise = function < T >( promise: Promise< T > ) { * store. */ export const controls = { - AWAIT_PROMISE: < T >( { promise }: { promise: Promise< T > } ) => promise, + AWAIT_PROMISE< T >( { promise }: { promise: Promise< T > } ) { + return promise; + }, API_FETCH( { request }: { request: APIFetchOptions } ) { return triggerFetch( request ); }, diff --git a/packages/fields/src/mutation/index.ts b/packages/fields/src/mutation/index.ts index 80e399d74e9479..89df0f769f70ed 100644 --- a/packages/fields/src/mutation/index.ts +++ b/packages/fields/src/mutation/index.ts @@ -10,9 +10,9 @@ import { dispatch } from '@wordpress/data'; */ import type { CoreDataError, Post } from '../types'; -const getErrorMessagesFromPromises = < T >( +function getErrorMessagesFromPromises< T >( allSettledResults: PromiseSettledResult< T >[] -) => { +) { const errorMessages = new Set< string >(); // If there was at lease one failure. if ( allSettledResults.length === 1 ) { @@ -36,7 +36,7 @@ const getErrorMessagesFromPromises = < T >( } } return errorMessages; -}; +} export type NoticeSettings< T extends Post > = { success: { From ba2d08e434df9955543966d4fdd83a557ee1eb0c Mon Sep 17 00:00:00 2001 From: Carolina Nymark Date: Tue, 22 Oct 2024 14:19:16 +0200 Subject: [PATCH 11/31] Archives: Add border block support (#63400) Archives: Add border block support Co-authored-by: carolinan Co-authored-by: aaronrobertshaw --- packages/block-library/src/archives/block.json | 6 ++++++ packages/block-library/src/archives/editor.scss | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/packages/block-library/src/archives/block.json b/packages/block-library/src/archives/block.json index e36691f3143c22..7fe956a994ed5a 100644 --- a/packages/block-library/src/archives/block.json +++ b/packages/block-library/src/archives/block.json @@ -26,6 +26,12 @@ }, "supports": { "align": true, + "__experimentalBorder": { + "radius": true, + "color": true, + "width": true, + "style": true + }, "html": false, "spacing": { "margin": true, diff --git a/packages/block-library/src/archives/editor.scss b/packages/block-library/src/archives/editor.scss index 6bb1d96431acf7..eb657b595f7141 100644 --- a/packages/block-library/src/archives/editor.scss +++ b/packages/block-library/src/archives/editor.scss @@ -1,3 +1,11 @@ ul.wp-block-archives { padding-left: 2.5em; } + +// The following styles are to prevent duplicate spacing and borders for the archives +// block in the editor given it uses server side rendering. +// See https://github.com/WordPress/gutenberg/pull/63400 +.wp-block-archives .wp-block-archives { + margin: 0; + border: 0; +} From 1461ef1c57639605c3233e72252f4b80b736896c Mon Sep 17 00:00:00 2001 From: Aki Hamano <54422211+t-hamano@users.noreply.github.com> Date: Tue, 22 Oct 2024 21:21:03 +0900 Subject: [PATCH 12/31] SpacingSizesControl: Use generic label for linked button (#66304) Co-authored-by: t-hamano Co-authored-by: madhusudhand Co-authored-by: mikachan --- .../spacing-sizes-control/linked-button.js | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/packages/block-editor/src/components/spacing-sizes-control/linked-button.js b/packages/block-editor/src/components/spacing-sizes-control/linked-button.js index e9ca68aaa2b31d..f6d56be66072ad 100644 --- a/packages/block-editor/src/components/spacing-sizes-control/linked-button.js +++ b/packages/block-editor/src/components/spacing-sizes-control/linked-button.js @@ -3,20 +3,10 @@ */ import { Button, Tooltip } from '@wordpress/components'; import { link, linkOff } from '@wordpress/icons'; -import { __, sprintf } from '@wordpress/i18n'; +import { __ } from '@wordpress/i18n'; export default function LinkedButton( { isLinked, ...props } ) { - const label = isLinked - ? sprintf( - // translators: 1. Type of spacing being modified (padding, margin, etc). - __( 'Unlink %1$s' ), - props.label.toLowerCase() - ).trim() - : sprintf( - // translators: 1. Type of spacing being modified (padding, margin, etc). - __( 'Link %1$s' ), - props.label.toLowerCase() - ).trim(); + const label = isLinked ? __( 'Unlink sides' ) : __( 'Link sides' ); return ( From d1c3508487735e8266f8ea7a6a3238ee8ca6b81b Mon Sep 17 00:00:00 2001 From: Carolina Nymark Date: Tue, 22 Oct 2024 14:49:28 +0200 Subject: [PATCH 13/31] Add theme type to the bug report issue template (#63851) * Add theme type to the bug report issue template * Add "Not sure" option to the theme type checkboxes --------- Co-authored-by: carolinan Co-authored-by: desrosj --- .github/ISSUE_TEMPLATE/Bug_report.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/Bug_report.yml b/.github/ISSUE_TEMPLATE/Bug_report.yml index 5d7c876ccefca7..41bb6f1c9ba108 100644 --- a/.github/ISSUE_TEMPLATE/Bug_report.yml +++ b/.github/ISSUE_TEMPLATE/Bug_report.yml @@ -65,3 +65,13 @@ body: options: - label: 'Yes' required: true + + - type: checkboxes + id: themes + attributes: + label: Please confirm which theme type you used for testing. + options: + - label: 'Block' + - label: 'Classic' + - label: 'Hybrid (e.g. classic with theme.json)' + - label: 'Not sure' From ca8c191b419a8335c94f9e1c9526793ecc1c35cb Mon Sep 17 00:00:00 2001 From: Aki Hamano <54422211+t-hamano@users.noreply.github.com> Date: Tue, 22 Oct 2024 22:36:13 +0900 Subject: [PATCH 14/31] Editor Interface: Remove small header from global styles/plugin sidebar (#64474) Co-authored-by: t-hamano Co-authored-by: stokesman Co-authored-by: jameskoster Co-authored-by: jasmussen Co-authored-by: afercia Co-authored-by: Mamaduka --- .../global-styles-sidebar/default-sidebar.js | 1 - .../components/global-styles-sidebar/index.js | 32 ++++++++++-------- .../components/global-styles/screen-css.js | 1 + .../src/components/plugin-sidebar/index.js | 13 -------- packages/interface/CHANGELOG.md | 4 +++ .../complementary-area-header/index.js | 33 +++++++------------ .../complementary-area-header/style.scss | 25 -------------- .../components/complementary-area/README.md | 8 ----- .../components/complementary-area/index.js | 7 ++-- .../components/complementary-area/style.scss | 6 +--- 10 files changed, 39 insertions(+), 91 deletions(-) diff --git a/packages/edit-site/src/components/global-styles-sidebar/default-sidebar.js b/packages/edit-site/src/components/global-styles-sidebar/default-sidebar.js index 5817c6d97ddddf..1f24bb49aa9f80 100644 --- a/packages/edit-site/src/components/global-styles-sidebar/default-sidebar.js +++ b/packages/edit-site/src/components/global-styles-sidebar/default-sidebar.js @@ -30,7 +30,6 @@ export default function DefaultSidebar( { scope="core" identifier={ identifier } title={ title } - smallScreenTitle={ title } icon={ icon } closeLabel={ closeLabel } header={ header } diff --git a/packages/edit-site/src/components/global-styles-sidebar/index.js b/packages/edit-site/src/components/global-styles-sidebar/index.js index 2b9a2669a96fe6..c0ad313d5d477c 100644 --- a/packages/edit-site/src/components/global-styles-sidebar/index.js +++ b/packages/edit-site/src/components/global-styles-sidebar/index.js @@ -11,6 +11,7 @@ import { store as editorStore, privateApis as editorPrivateApis, } from '@wordpress/editor'; +import { useViewportMatch } from '@wordpress/compose'; import { privateApis as routerPrivateApis } from '@wordpress/router'; /** @@ -81,6 +82,7 @@ export default function GlobalStylesSidebar() { const { setEditorCanvasContainerView } = unlock( useDispatch( editSiteStore ) ); + const isMobileViewport = useViewportMatch( 'medium', '<' ); useEffect( () => { if ( shouldClearCanvasContainerView ) { @@ -149,20 +151,22 @@ export default function GlobalStylesSidebar() { gap={ 1 } className="edit-site-global-styles-sidebar__header-actions" > - -