diff --git a/.eslintrc.js b/.eslintrc.js index 5f88587b915c2..9cb0b100714d4 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -79,6 +79,7 @@ module.exports = { { name: 'lodash', importNames: [ + 'capitalize', 'chunk', 'clamp', 'compact', @@ -86,6 +87,7 @@ module.exports = { 'countBy', 'defaults', 'defaultTo', + 'delay', 'differenceWith', 'dropRight', 'each', @@ -103,15 +105,18 @@ module.exports = { 'isBoolean', 'isFinite', 'isFunction', + 'isMatch', 'isNil', 'isNumber', 'isObject', 'isObjectLike', + 'isPlainObject', 'isString', 'isUndefined', 'keyBy', 'keys', 'lowerCase', + 'maxBy', 'memoize', 'negate', 'noop', @@ -125,6 +130,7 @@ module.exports = { 'reverse', 'size', 'snakeCase', + 'startsWith', 'stubFalse', 'stubTrue', 'sum', @@ -136,6 +142,8 @@ module.exports = { 'uniqueId', 'uniqWith', 'values', + 'words', + 'zip', ], message: 'This Lodash method is not recommended. Please use native functionality instead. If using `memoize`, please use `memize` instead.', diff --git a/.github/workflows/build-plugin-zip.yml b/.github/workflows/build-plugin-zip.yml index 8bd14acdff60c..30a598c93c7ef 100644 --- a/.github/workflows/build-plugin-zip.yml +++ b/.github/workflows/build-plugin-zip.yml @@ -192,7 +192,7 @@ jobs: run: | IFS='.' read -r -a VERSION_ARRAY <<< "${VERSION}" MILESTONE="Gutenberg ${VERSION_ARRAY[0]}.${VERSION_ARRAY[1]}" - npm run changelog -- --milestone="$MILESTONE" --unreleased > release-notes.txt + npm run other:changelog -- --milestone="$MILESTONE" --unreleased > release-notes.txt sed -ie '1,6d' release-notes.txt if [[ ${{ needs.bump-version.outputs.new_version }} != *"rc"* ]]; then # Include previous RCs' release notes, if any diff --git a/.github/workflows/end2end-test-playwright.yml b/.github/workflows/end2end-test-playwright.yml index 8ab3b9a22966f..b67c15834b832 100644 --- a/.github/workflows/end2end-test-playwright.yml +++ b/.github/workflows/end2end-test-playwright.yml @@ -47,7 +47,7 @@ jobs: - name: Run the tests run: | - npm run test-e2e:playwright + npm run test:e2e:playwright - name: Archive debug artifacts (screenshots, traces) uses: actions/upload-artifact@e448a9b857ee2131e752b06002bf0e093c65e571 # v2.2.2 diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index 2efa28a0fb736..f45c1f229666a 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -1,4 +1,4 @@ -name: Performances Tests +name: Performance Tests on: pull_request: diff --git a/.github/workflows/static-checks.yml b/.github/workflows/static-checks.yml index e6aaaeaa06bfa..684c13710fdab 100644 --- a/.github/workflows/static-checks.yml +++ b/.github/workflows/static-checks.yml @@ -46,7 +46,7 @@ jobs: run: npm run build:package-types - name: Check local changes - run: npm run check-local-changes + run: npm run other:check-local-changes - name: License compatibility - run: npm run check-licenses + run: npm run other:check-licenses diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 786272b4e29e4..795ad86c9a276 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -46,10 +46,10 @@ jobs: npx lerna run build - name: Running the tests - run: npm run test-unit -- --ci --maxWorkers=2 --cacheDirectory="$HOME/.jest-cache" + run: npm run test:unit -- --ci --maxWorkers=2 --cacheDirectory="$HOME/.jest-cache" - name: Running the date tests - run: npm run test-unit:date -- --ci --maxWorkers=2 --cacheDirectory="$HOME/.jest-cache" + run: npm run test:unit:date -- --ci --maxWorkers=2 --cacheDirectory="$HOME/.jest-cache" unit-php: name: PHP @@ -75,14 +75,14 @@ jobs: npm run wp-env start - name: Running lint check - run: npm run lint-php + run: npm run lint:php - name: Running single site unit tests - run: npm run test-unit-php + run: npm run test:unit:php if: ${{ success() || failure() }} - name: Running multisite unit tests - run: npm run test-unit-php-multisite + run: npm run test:unit:php:multisite if: ${{ success() || failure() }} mobile-unit-js: diff --git a/bin/api-docs/are-api-docs-unstaged.js b/bin/api-docs/are-api-docs-unstaged.js index e4fbadace0265..ed2b50fb6fa12 100644 --- a/bin/api-docs/are-api-docs-unstaged.js +++ b/bin/api-docs/are-api-docs-unstaged.js @@ -35,7 +35,7 @@ const getUnstagedReadmes = () => '\n', 'Some API docs may be out of date:', unstagedReadmes.toString(), - 'Either build and stage them with npm run api-docs:blocks or continue with --no-verify.', + 'Either build and stage them with npm run docs:blocks or continue with --no-verify.', '\n' ) ); diff --git a/bin/plugin/commands/performance.js b/bin/plugin/commands/performance.js index 4c7faf0180a16..1b0d85a2bb140 100644 --- a/bin/plugin/commands/performance.js +++ b/bin/plugin/commands/performance.js @@ -177,7 +177,7 @@ async function setUpGitBranch( branch, environmentDirectory ) { */ async function runTestSuite( testSuite, performanceTestDirectory ) { await runShellScript( - `npm run test-performance -- packages/e2e-tests/specs/performance/${ testSuite }.test.js`, + `npm run test:performance -- packages/e2e-tests/specs/performance/${ testSuite }.test.js`, performanceTestDirectory ); const rawResults = await readJSONFile( diff --git a/bin/plugin/commands/test/changelog.js b/bin/plugin/commands/test/changelog.js index 321a86da8b156..e9e1872c38c99 100644 --- a/bin/plugin/commands/test/changelog.js +++ b/bin/plugin/commands/test/changelog.js @@ -462,7 +462,7 @@ describe( 'getFormattedItemDescription', () => { describe( 'getChangelog', () => { test( 'verify that the changelog is properly formatted', () => { // The fixture with the list of pull requests was generated by running the following command: - // npm run changelog -- --milestone="Gutenberg 11.3" + // npm run other:changelog -- --milestone="Gutenberg 11.3" // The response from the `fetchAllPullRequests` call in the `getChangelog` method was stored in the JSON file. expect( getChangelog( pullRequests ) ).toMatchSnapshot(); } ); @@ -471,7 +471,7 @@ describe( 'getChangelog', () => { describe( 'getContributorProps', () => { test( 'verify that the contributors props are properly formatted', () => { // The fixture with the list of pull requests was generated by running the following command: - // npm run changelog -- --milestone="Gutenberg 11.3" + // npm run other:changelog -- --milestone="Gutenberg 11.3" expect( getContributorProps( pullRequests ) ).toMatchSnapshot(); } ); } ); @@ -479,7 +479,7 @@ describe( 'getContributorProps', () => { describe( 'getContributorList', () => { test( 'verify that the contributors list is properly formatted', () => { // The fixture with the list of pull requests was generated by running the following command: - // npm run changelog -- --milestone="Gutenberg 11.3" + // npm run other:changelog -- --milestone="Gutenberg 11.3" expect( getContributorsList( pullRequests ) ).toMatchSnapshot(); } ); } ); diff --git a/bin/unit-test-date.sh b/bin/unit-test-date.sh index d3e5c79bba83d..e83f4c91a4bbe 100755 --- a/bin/unit-test-date.sh +++ b/bin/unit-test-date.sh @@ -11,7 +11,7 @@ locales=(en_US ja_JP) for timezone in "${timezones[@]}"; do for locale in "${locales[@]}"; do - TZ=$timezone LANG=$locale npm run test-unit -- packages/date "$@" & + TZ=$timezone LANG=$locale npm run test:unit -- packages/date "$@" & pids+=($!) pidsTimezones+=($timezone) pidsLocales+=($locale) diff --git a/changelog.txt b/changelog.txt index c47a83590c0a9..d49f1bb5c7505 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,39 +1,571 @@ == Changelog == -= 13.8.0-rc.2 = += 13.9.0-rc.1 = + + ## Changelog +### Enhancements + +- Style engine: Prettify combined selectors. ([43003](https://github.com/WordPress/gutenberg/pull/43003)) +- Style engine: Prettify output. ([42909](https://github.com/WordPress/gutenberg/pull/42909)) +- Style engine: Rename global function. ([42719](https://github.com/WordPress/gutenberg/pull/42719)) +- Shortcuts: Add Ctrl+Y for redo on Windows. ([42627](https://github.com/WordPress/gutenberg/pull/42627)) + +#### Components + +- BaseControl: Add `box-sizing` resets. ([42889](https://github.com/WordPress/gutenberg/pull/42889)) +- BorderControl: Add box sizing reset. ([42754](https://github.com/WordPress/gutenberg/pull/42754)) +- BoxControl: Export `applyValueToSides` util function. ([42733](https://github.com/WordPress/gutenberg/pull/42733)) +- ComboboxControl and FormTokenField: Enhance components with custom render callback for options. ([42597](https://github.com/WordPress/gutenberg/pull/42597)) +- ComboboxControl: Add support for uncontrolled mode. ([42752](https://github.com/WordPress/gutenberg/pull/42752)) +- Flex: Convert component to TypeScript. ([42537](https://github.com/WordPress/gutenberg/pull/42537)) +- FontSizePicker: Add 40px size variant. ([42716](https://github.com/WordPress/gutenberg/pull/42716)) +- Placeholder: Convert component to TypeScript. ([42990](https://github.com/WordPress/gutenberg/pull/42990)) +- Popover: Rewrite Storybook examples using controls. ([42903](https://github.com/WordPress/gutenberg/pull/42903)) +- Popover: Tidy up code 🧹 , add more comments. ([42944](https://github.com/WordPress/gutenberg/pull/42944)) +- ResizableBox: Change tooltip background to match other tooltips. ([42800](https://github.com/WordPress/gutenberg/pull/42800)) +- Storybook: Add global CSS switcher. ([42747](https://github.com/WordPress/gutenberg/pull/42747)) +- StyleProvider: Convert component to TypeScript. ([42541](https://github.com/WordPress/gutenberg/pull/42541)) +- Swatch: Convert component to TypeScript. ([42162](https://github.com/WordPress/gutenberg/pull/42162)) +- Tooltip (Experimental), CustomSelectControl, TimePicker: add missing font sizes which were necessary in non-WordPress contexts. ([42844](https://github.com/WordPress/gutenberg/pull/42844)) +- Typography Panel: Fix font appearance control width. ([42795](https://github.com/WordPress/gutenberg/pull/42795)) +- UnitControl: Update unit dropdown design. ([42000](https://github.com/WordPress/gutenberg/pull/42000)) +- Update control labels to the new uppercase styles. ([42789](https://github.com/WordPress/gutenberg/pull/42789)) + +#### Block Library + +- Archives: Add a control to make block's dropdown label invisible. ([43025](https://github.com/WordPress/gutenberg/pull/43025)) +- Query Title: Add a search title variation. ([42662](https://github.com/WordPress/gutenberg/pull/42662)) +- Media&Text: Add help to ImageSizeControl. ([40642](https://github.com/WordPress/gutenberg/pull/40642)) +- Post Author: Rendering html for the author description at the editor. ([42109](https://github.com/WordPress/gutenberg/pull/42109)) +- Post Featured Image: Add link target and rel attributes. ([42853](https://github.com/WordPress/gutenberg/pull/42853)) + +#### CSS & Styling + +- Rename solid color. ([42918](https://github.com/WordPress/gutenberg/pull/42918)) +- Try: Tab style subpixel fix. ([42892](https://github.com/WordPress/gutenberg/pull/42892)) + +#### Site Editor + +- Add: Author nicename template creation ability. ([42165](https://github.com/WordPress/gutenberg/pull/42165)) +- [Site Editor]: Add fallback template content on creation. ([42520](https://github.com/WordPress/gutenberg/pull/42520)) + +#### Block Directory + +- Modernize `DownloadableBlockListItem` tests. ([43026](https://github.com/WordPress/gutenberg/pull/43026)) + +#### List View + +- List View Expander: Fix icon in RTL mode. ([42997](https://github.com/WordPress/gutenberg/pull/42997)) + +#### Global Styles + +- Layout: Add a disable-layout-styles theme supports flag to opt out of all layout styles. ([42544](https://github.com/WordPress/gutenberg/pull/42544)) + +#### Block Editor + +- Rich text: Add character shortcuts for wrapping selection. ([42469](https://github.com/WordPress/gutenberg/pull/42469)) + +#### Document Settings + +- Post Template: Update template title selector. ([42091](https://github.com/WordPress/gutenberg/pull/42091)) + +#### Design Tools + +- Cover: Show Resize Tooltip on Drag. ([23522](https://github.com/WordPress/gutenberg/pull/23522)) +- Update color button style. ([41838](https://github.com/WordPress/gutenberg/pull/41838)) +- Add explicit bypass for fluid font size calculation. ([42757](https://github.com/WordPress/gutenberg/pull/42757)) + ### Bug Fixes +- Block Styles: Truncate long button labels. ([42975](https://github.com/WordPress/gutenberg/pull/42975)) +- ColorGradientControl: Fix awkward padding in popover. ([43018](https://github.com/WordPress/gutenberg/pull/43018)) +- Create Block: Remove i18n references from save properties. ([43035](https://github.com/WordPress/gutenberg/pull/43035)) +- Firefox: Fix issue where it selects a nearby contentEditable. ([42777](https://github.com/WordPress/gutenberg/pull/42777)) +- Layout: Fix flex direction column. ([42939](https://github.com/WordPress/gutenberg/pull/42939)) +- List v2: Fix Cmd+A. ([42858](https://github.com/WordPress/gutenberg/pull/42858)) +- Style Engine: Include 6.1 CSS filter, ensure style engine can output CSS functions like clamp. ([43004](https://github.com/WordPress/gutenberg/pull/43004)) +- Style engine: Disable stylesheet optimization temporarily. ([43051](https://github.com/WordPress/gutenberg/pull/43051)) + +#### Block Library + +- Navigation: Fix invalid permissions warning by avoiding using trashed wp_navigation posts (JS implementation). ([42982](https://github.com/WordPress/gutenberg/pull/42982)) +- Disabled blocks passed to BlockTypesList are no longer draggable. ([42751](https://github.com/WordPress/gutenberg/pull/42751)) +- Fix drag and drop performance when dragging over the insertion point. ([42806](https://github.com/WordPress/gutenberg/pull/42806)) +- Social Link: add missing 'width' and 'height' attributes. ([41373](https://github.com/WordPress/gutenberg/pull/41373)) +- Separator: Fix the block CSS classes in the editor. ([42769](https://github.com/WordPress/gutenberg/pull/42769)) +- Tag Cloud: Fix alignment issue when align center. ([43017](https://github.com/WordPress/gutenberg/pull/43017)) +- Navigation: Fix `current-menu-item` class logic. ([42849](https://github.com/WordPress/gutenberg/pull/42849)) +- Media&Text: Round position attribute on focal point save. ([33915](https://github.com/WordPress/gutenberg/pull/33915)) +- Social: Include has-visible-labels on edit component. ([42791](https://github.com/WordPress/gutenberg/pull/42791)) +- Writing flow: Fix Shift+Arrow partial selection for lists & quote. ([42885](https://github.com/WordPress/gutenberg/pull/42885)) +- LatestPost: Fix issue with floated featured images overflowing focus style. ([40663](https://github.com/WordPress/gutenberg/pull/40663)) + +#### Components + +- ColorPicker: Fix layout overflow. ([42992](https://github.com/WordPress/gutenberg/pull/42992)) +- External link component: Add a check for on page anchor links. ([42259](https://github.com/WordPress/gutenberg/pull/42259)) +- Icons: Fix storybook library icon names. ([43034](https://github.com/WordPress/gutenberg/pull/43034)) +- InputControl: Fix incorrect size prop passing to `Text`. ([42793](https://github.com/WordPress/gutenberg/pull/42793)) +- Popover: Anchor correctly to parent node when no explicit anchor is passed. ([42971](https://github.com/WordPress/gutenberg/pull/42971)) +- Popover: Fix arrow placement and design. ([42874](https://github.com/WordPress/gutenberg/pull/42874)) +- Popover: Improve iframe offset computation. ([42417](https://github.com/WordPress/gutenberg/pull/42417)) +- Popover: Make sure that ownerDocument is always defined. ([42886](https://github.com/WordPress/gutenberg/pull/42886)) +- `InputControl`: Fix acceptance of falsy values in controlled updates. ([42484](https://github.com/WordPress/gutenberg/pull/42484)) + +#### Block Editor + +- Inserter: Avoid warning when CRA is displayed. ([42723](https://github.com/WordPress/gutenberg/pull/42723)) +- Pasting: Dismiss pasted image if file:// schema detected. ([42785](https://github.com/WordPress/gutenberg/pull/42785)) +- Prevent multiselection via dragging when already dragging blocks. ([42877](https://github.com/WordPress/gutenberg/pull/42877)) +- Quote: Fix raw transform handler. ([43093](https://github.com/WordPress/gutenberg/pull/43093)) +- Rich text: Fix error when attempting to remove placeholder on composition start. ([42821](https://github.com/WordPress/gutenberg/pull/42821)) + #### Global Styles -- Theme JSON Resolver: Update cache check to also check that the object is an instance of the Gutenberg version. ([42756](https://github.com/WordPress/gutenberg/pull/42756)) +- Fix styles declarations returning before all properties output. ([42954](https://github.com/WordPress/gutenberg/pull/42954)) +- Fluid typography: Migrate fluid typography algorithm to JS for site editor. ([42688](https://github.com/WordPress/gutenberg/pull/42688)) +- Spacing presets: Prevent % spacing size units being stripped by sanitize_title. ([43101](https://github.com/WordPress/gutenberg/pull/43101)) +- Specify priority in remove_action. ([43073](https://github.com/WordPress/gutenberg/pull/43073)) + +#### Build Tooling + +- Fix: CSS files don't build in dev mode on Windows. ([42041](https://github.com/WordPress/gutenberg/pull/42041)) +- Fix: Script name error in main package.json. ([43089](https://github.com/WordPress/gutenberg/pull/43089)) + +#### Accessibility + +- Fix issue where changing the id of the recursion provider can result in focus loss. ([42916](https://github.com/WordPress/gutenberg/pull/42916)) +- Site Editor: Don't disable the Save button. ([42842](https://github.com/WordPress/gutenberg/pull/42842)) + +#### CSS & Styling + +- Layout: Merge CSS rule for block gap. ([43052](https://github.com/WordPress/gutenberg/pull/43052)) + +#### Testing + +- Fix: Just another end-to-end test. ([42947](https://github.com/WordPress/gutenberg/pull/42947)) + +#### Document Settings + +- Decode the post URL for the button label. ([42930](https://github.com/WordPress/gutenberg/pull/42930)) + +#### Site Editor + +- Internalization fixes for site editor template creation. ([42762](https://github.com/WordPress/gutenberg/pull/42762)) + +### Performance + +- Lodash: Refactor away from `_.isMatch()`. ([42271](https://github.com/WordPress/gutenberg/pull/42271)) +- Lodash: Refactor away from `_.zip()`. ([42926](https://github.com/WordPress/gutenberg/pull/42926)) +- Lodash: Remove completely from `@wordpress/dom` package. ([42912](https://github.com/WordPress/gutenberg/pull/42912)) +- Lodash: Remove completely from `@wordpress/element` package. ([42898](https://github.com/WordPress/gutenberg/pull/42898)) + +#### Components + +- Lodash: Refactor away from `_.delay()`. ([42966](https://github.com/WordPress/gutenberg/pull/42966)) +- Lodash: Refactor away from `_.startsWith()`. ([43019](https://github.com/WordPress/gutenberg/pull/43019)) + +#### Block Library + +- Refactor Calendar block away from `moment`. ([43029](https://github.com/WordPress/gutenberg/pull/43029)) + +#### Accessibility + +- Lodash: Refactor away from `_.maxBy()`. ([42914](https://github.com/WordPress/gutenberg/pull/42914)) + +#### Data Layer + +- Lodash: Refactor away from `_.isPlainObject()`. ([42508](https://github.com/WordPress/gutenberg/pull/42508)) ### Experiments +- Style engine: Enqueue block support styles. ([42452](https://github.com/WordPress/gutenberg/pull/42452)) ([42880](https://github.com/WordPress/gutenberg/pull/42880)) +- Combine style-engine stores for block-supports. ([42970](https://github.com/WordPress/gutenberg/pull/42970)) +- Style engine: Add optimize flag and combine functions into wp_style_engine_get_stylesheet. ([42878](https://github.com/WordPress/gutenberg/pull/42878)) + +### Documentation + +- Add examples for `core/blocks` actions. ([42637](https://github.com/WordPress/gutenberg/pull/42637)) +- Add examples for core/viewport package. ([42921](https://github.com/WordPress/gutenberg/pull/42921)) +- Added the allowedFormat details in richtext readme. ([42426](https://github.com/WordPress/gutenberg/pull/42426)) +- Adding `@example` entries to the public API exposed in `core/blocks`. ([42745](https://github.com/WordPress/gutenberg/pull/42745)) +- Cover: Fix rendered content PHPDoc type. ([43099](https://github.com/WordPress/gutenberg/pull/43099)) +- Create Block: Update document links in templates. ([42839](https://github.com/WordPress/gutenberg/pull/42839)) +- Docs: Fix return type of home link attribute function. ([42901](https://github.com/WordPress/gutenberg/pull/42901)) +- Docs: Fix textual consistency about block attributes. ([43075](https://github.com/WordPress/gutenberg/pull/43075)) +- Docs: Link plugins GitHub release pages. ([42736](https://github.com/WordPress/gutenberg/pull/42736)) +- Document the cherry-picking automation. ([42932](https://github.com/WordPress/gutenberg/pull/42932)) +- Fixed broken external link to Mozilla Developer documentation. ([43065](https://github.com/WordPress/gutenberg/pull/43065)) +- Release Docs: Troubleshooting failed "Bump version" job. ([42936](https://github.com/WordPress/gutenberg/pull/42936)) +- Release docs: Update performance test instructions. ([43015](https://github.com/WordPress/gutenberg/pull/43015)) +- Remove the emoji characters to fix the handbook rendering. ([43028](https://github.com/WordPress/gutenberg/pull/43028)) +- Update broken internal link. ([43094](https://github.com/WordPress/gutenberg/pull/43094)) +- Update theme-json.md to include new element support and :Ref. ([42412](https://github.com/WordPress/gutenberg/pull/42412)) +- [Gutenberg Data Tutorial] Adjust the image URLs and whitespace to render correctly in the Handbook. ([42969](https://github.com/WordPress/gutenberg/pull/42969)) + +### Code Quality + +- Add mutations data and helper functions to useEntityRecord. ([39595](https://github.com/WordPress/gutenberg/pull/39595)) +- Remove old WordPress 5.8 code. ([42818](https://github.com/WordPress/gutenberg/pull/42818)) + +#### Block Library + +- Add separate callbacks for selecting a classic or navigation menu in the nav block. ([43057](https://github.com/WordPress/gutenberg/pull/43057)) +- Avoid reliance on status constants when consuming useCreateNavigationMenu hook. ([42704](https://github.com/WordPress/gutenberg/pull/42704)) +- Home Link: Use 'sprintf' in the render callback. ([43024](https://github.com/WordPress/gutenberg/pull/43024)) +- Nav block: Extract hook for inner blocks. ([42743](https://github.com/WordPress/gutenberg/pull/42743)) +- Nav block: Normalize to function expressions. ([42744](https://github.com/WordPress/gutenberg/pull/42744)) +- Normalize usage of Notifications in Nav block. ([42706](https://github.com/WordPress/gutenberg/pull/42706)) +- Remove duplicate speak calls from navigation block. ([43079](https://github.com/WordPress/gutenberg/pull/43079)) +- Site Title: Use home_url instead of get_bloginfo. ([42857](https://github.com/WordPress/gutenberg/pull/42857)) + +#### Site Editor + +- Navigation Menu Sidebar: Remove unnecessary Fragment. ([43021](https://github.com/WordPress/gutenberg/pull/43021)) + #### Global Styles -- Layout: Reduce specificity of fallback blockGap styles. ([42665](https://github.com/WordPress/gutenberg/pull/42665)) +- useGlobalStylesOutput: Use memo for derived values. ([42917](https://github.com/WordPress/gutenberg/pull/42917)) + +### Tools + +- Use git for `wp-env`'s default WordPress version. ([42826](https://github.com/WordPress/gutenberg/pull/42826)) + +#### Testing + +- Migrate deprecated node matcher tests to playwright. ([42759](https://github.com/WordPress/gutenberg/pull/42759)) +- Migrate group block tests to Playwright. ([42801](https://github.com/WordPress/gutenberg/pull/42801)) +- Migrate missing block tests to Playwright. ([41680](https://github.com/WordPress/gutenberg/pull/41680)) +- Migrate Convert Block Type test to Playwright. ([42760](https://github.com/WordPress/gutenberg/pull/42760)) + +#### Build Tooling + +- Lodash: Refactor away from `_.flatMap()`. ([42360](https://github.com/WordPress/gutenberg/pull/42360)) +- Standardize script naming in main package.json. ([42368](https://github.com/WordPress/gutenberg/pull/42368)) + +#### Block Library + +- Nav block: Move overlay colors to the responsive wrapper. ([42875](https://github.com/WordPress/gutenberg/pull/42875)) +- Navigation block: Extract navigation block utils. ([42865](https://github.com/WordPress/gutenberg/pull/42865)) +- Navigation: Overlay: Fix link inheritance. ([42929](https://github.com/WordPress/gutenberg/pull/42929)) +- Page List: Fix indentation in PHP file. ([42852](https://github.com/WordPress/gutenberg/pull/42852)) +- Query Pagination: Correctly position the "next" link on the first page. ([42764](https://github.com/WordPress/gutenberg/pull/42764)) +- Search Block: Remove margins from the input. ([42959](https://github.com/WordPress/gutenberg/pull/42959)) +- Transforms: Add group unwrap. ([42685](https://github.com/WordPress/gutenberg/pull/42685)) +- [Post Title]: Do not add `rel` attribute if empty. ([42855](https://github.com/WordPress/gutenberg/pull/42855)) +- [Query Loop]: Try filters with ToolsPanel. ([42629](https://github.com/WordPress/gutenberg/pull/42629)) + +#### Global Styles + +- Add block spacing to root block support UI. ([42797](https://github.com/WordPress/gutenberg/pull/42797)) +- Elements: Update the load order of the CSS in the Site Editor. ([42863](https://github.com/WordPress/gutenberg/pull/42863)) +- Heading element UI controls. ([42176](https://github.com/WordPress/gutenberg/pull/42176)) +- Theme JSON: Add a static $blocks_metadata data definition to the Gutenberg instance of WP_Theme_JSON. ([42776](https://github.com/WordPress/gutenberg/pull/42776)) +- Upsize typography panel components. ([42718](https://github.com/WordPress/gutenberg/pull/42718)) + +#### Widgets Editor + +- Format Library: Add missing keyboard shortcut description in customizer widget. ([43044](https://github.com/WordPress/gutenberg/pull/43044)) + +#### Reusable Blocks + +- Make template part and reusable block creation language consistent. ([43032](https://github.com/WordPress/gutenberg/pull/43032)) + +#### CSS & Styling + +- Navigation: Try to keep :Where just for paddings. ([42967](https://github.com/WordPress/gutenberg/pull/42967)) + +#### Accessibility + +- Change shortcut text for redo tooltip on Windows. ([42830](https://github.com/WordPress/gutenberg/pull/42830)) + +#### Block Editor + +- Quote: Unwrap on Backspace at start. ([42808](https://github.com/WordPress/gutenberg/pull/42808)) + +#### Site Editor + +- Add a 'View Site' link in the site editor. ([42331](https://github.com/WordPress/gutenberg/pull/42331)) + +#### Full Site Editing + +- [Full Site Editing]: Update `clear customizations` copy for templates. ([41765](https://github.com/WordPress/gutenberg/pull/41765)) + + +## First time contributors + +The following PRs were merged by first time contributors: + +- @fellyph: Rendering html for the author description at the editor. ([42109](https://github.com/WordPress/gutenberg/pull/42109)) +- @merkys7: Fix social-link block missing 'width' and 'height' attributes. ([41373](https://github.com/WordPress/gutenberg/pull/41373)) +- @Smit2808: Added the allowedFormat details in richtext readme. ([42426](https://github.com/WordPress/gutenberg/pull/42426)) +- @theminaldiwan: Fixed alignment issue of tagcloud block when align center. ([43017](https://github.com/WordPress/gutenberg/pull/43017)) ## Contributors The following contributors merged PRs in this release: -@andrewserong +@aaronrobertshaw @adamziel @andrewserong @aristath @carolinan @chad1008 @ciampo @derekblank @dougwollison @ellatrix @fellyph @geriux @getdave @glendaviesnz @ItsJonQ @jameskoster @jasmussen @jorgefilipecosta @JustinyAhin @kjohnson @Mamaduka @manzoorwanijk @matiasbenedetto @mcsf @merkys7 @mikachan @mirka @noahtallen @ntsekouras @pavanpatil1 @pooja-muchandikar @ramonjd @ryanwelcher @SavPhill @scruffian @shimotmk @SiobhyB @Smit2808 @Soean @stokesman @t-hamano @talldan @tellthemachines @theminaldiwan @tyxla @walbo -= 13.8.0-rc.1 = += 13.8.1 = ## Changelog -### Features + +### Enhancements + +- Allow removing CSS declarations from the WP_Style_Engine_CSS_Declarations object. ([42428](https://github.com/WordPress/gutenberg/pull/42428)) +- Equalize modal content padding. ([42370](https://github.com/WordPress/gutenberg/pull/42370)) +- Remove top margin on the first paragraph in a modal. ([42369](https://github.com/WordPress/gutenberg/pull/42369)) + +#### Components +- BorderControl: Render border color/style dropdown as UnitControl prefix. ([42212](https://github.com/WordPress/gutenberg/pull/42212)) +- ColorPicker: Cleanly implement large size. ([42002](https://github.com/WordPress/gutenberg/pull/42002)) +- ComboboxControl: Refactor `onKeyDown` to use `keyboardEvent.code`. ([42569](https://github.com/WordPress/gutenberg/pull/42569)) +- Elevation: Convert component to TypeScript. ([42302](https://github.com/WordPress/gutenberg/pull/42302)) +- InputControl: Decrease large default padding if has prefix/suffix. ([42166](https://github.com/WordPress/gutenberg/pull/42166)) +- ScrollLock: Covert component to TypeScript. ([42303](https://github.com/WordPress/gutenberg/pull/42303)) +- SelectControl: Add flag for larger default size. ([42456](https://github.com/WordPress/gutenberg/pull/42456)) +- Shortcut: Covert component to TypeScript. ([42272](https://github.com/WordPress/gutenberg/pull/42272)) +- Divider: Complete TypeScript migration of component. ([41991](https://github.com/WordPress/gutenberg/pull/41991)) +- ToggleGroupControl: Add size variants. ([42008](https://github.com/WordPress/gutenberg/pull/42008)) +- UnitControl: Update unit select's focus styles. ([42383](https://github.com/WordPress/gutenberg/pull/42383)) +- BorderControl: Add missing changelog for accessibility enhancements. ([42411](https://github.com/WordPress/gutenberg/pull/42411)) +- CustomSelectControl: Use styles from SelectControl. ([42460](https://github.com/WordPress/gutenberg/pull/42460)) +- Dropdown: Add wrapper for custom padding. ([42595](https://github.com/WordPress/gutenberg/pull/42595)) +- InputControl: Add padding wrapper for prefix/suffix. ([42378](https://github.com/WordPress/gutenberg/pull/42378)) +- ScrollLock: Improve Storybook story for documentation view. ([42344](https://github.com/WordPress/gutenberg/pull/42344)) +- `ColorPalette`: Display checkered preview background when `value` is transparent. ([42232](https://github.com/WordPress/gutenberg/pull/42232)) + +#### Block Library +- Added WhatsApp icon to the Social Icon Block. ([42137](https://github.com/WordPress/gutenberg/pull/42137)) +- Template Part: Swap block action places. ([42221](https://github.com/WordPress/gutenberg/pull/42221)) +- Template Parts: Add search to replacement modal. ([42459](https://github.com/WordPress/gutenberg/pull/42459)) +- Image: Add border block support for color, width, and style. ([31366](https://github.com/WordPress/gutenberg/pull/31366)) +- List v2: Remove quote transforms as removed by Quote v2. ([42700](https://github.com/WordPress/gutenberg/pull/42700)) +- Merge Comments and Post Comments blocks. ([41807](https://github.com/WordPress/gutenberg/pull/41807)) +- Theme.json: Add support for heading / caption elements in theme.json schema. ([42433](https://github.com/WordPress/gutenberg/pull/42433)) + +#### Global Styles +- Add layout content size controls to global styles. ([42309](https://github.com/WordPress/gutenberg/pull/42309)) +- Core CSS support for root padding and alignfull blocks. ([42085](https://github.com/WordPress/gutenberg/pull/42085)) +- Theme.json: Add block support feature level selectors for blocks. ([42087](https://github.com/WordPress/gutenberg/pull/42087)) + +#### Document Settings +- Make 'Move to trash' button full width. ([42577](https://github.com/WordPress/gutenberg/pull/42577)) + +#### Block Editor +- Add setting to display rich text toolbar inline. ([42399](https://github.com/WordPress/gutenberg/pull/42399)) +- Add block variations for individual template parts. ([42454](https://github.com/WordPress/gutenberg/pull/42454)) +- Enable `onEnter` support for group block. ([40724](https://github.com/WordPress/gutenberg/pull/40724)) + +#### Site Editor +- On template creation, don't show search if not needed. ([42357](https://github.com/WordPress/gutenberg/pull/42357)) + +#### Accessibility +- BorderControl: Update labelling, tooltips and wrap with fieldset and legend. ([42348](https://github.com/WordPress/gutenberg/pull/42348)) + +#### Icons +- Add shuffle icon to library. ([42193](https://github.com/WordPress/gutenberg/pull/42193)) + +#### Nested / Inner Blocks +- Quote: Use nested blocks. ([25892](https://github.com/WordPress/gutenberg/pull/25892)) + +#### Colors +- Update color palette popover style. ([41900](https://github.com/WordPress/gutenberg/pull/41900)) + + +### Bug Fixes + +- Env: Download WordPress PHPUnit Into Container. ([41780](https://github.com/WordPress/gutenberg/pull/41780)) +- Env: Restrict `WP_TESTS_DOMAIN` constant to just hostname and not home URL. ([41039](https://github.com/WordPress/gutenberg/pull/41039)) +- Fix: Condition bug on BoxControl. ([42402](https://github.com/WordPress/gutenberg/pull/42402)) +- MaybeCategoryPanel: Update category selector. ([42663](https://github.com/WordPress/gutenberg/pull/42663)) +- Post title: Fix single line paste. ([42321](https://github.com/WordPress/gutenberg/pull/42321)) +- Scripts: Exit error code 1 when status value is null. ([42396](https://github.com/WordPress/gutenberg/pull/42396)) +- Style engine: Check item value validity. ([42487](https://github.com/WordPress/gutenberg/pull/42487)) +- Utilize WordPress PHPUnit Test Library Included By `wp-env`. ([41852](https://github.com/WordPress/gutenberg/pull/41852)) +- fix: Correct alt text footnote spacing. ([42504](https://github.com/WordPress/gutenberg/pull/42504)) + +#### Block Library +- Cover Block: Prevent transform to Group block when featured image is set. ([42638](https://github.com/WordPress/gutenberg/pull/42638)) +- Cover block: Adding background-size and background-repeat properties to the block CSS. ([42470](https://github.com/WordPress/gutenberg/pull/42470)) +- Fix tab/focus order issue in Media & text block. ([40806](https://github.com/WordPress/gutenberg/pull/40806)) +- List v2: Add forward delete. ([42564](https://github.com/WordPress/gutenberg/pull/42564)) +- List v2: Improve paste handling. ([42524](https://github.com/WordPress/gutenberg/pull/42524)) +- List v2: Merge with nested items. ([42551](https://github.com/WordPress/gutenberg/pull/42551)) +- List v2: Switch to default block type on Backspace from start. ([42633](https://github.com/WordPress/gutenberg/pull/42633)) +- Page List: Fetch items with 'view' context. ([42559](https://github.com/WordPress/gutenberg/pull/42559)) +- Social Icons Block: Fix button opacity in template parts. ([42641](https://github.com/WordPress/gutenberg/pull/42641)) +- Group block: Add context to the word "Row". ([42255](https://github.com/WordPress/gutenberg/pull/42255)) +- Hide prefix and suffix placeholders in post terms. ([42418](https://github.com/WordPress/gutenberg/pull/42418)) +- Theme.json: Fix schema for button elements. ([42431](https://github.com/WordPress/gutenberg/pull/42431)) +- [Media Text]: Fix deprecations regression. ([42816](https://github.com/WordPress/gutenberg/pull/42816)) +- Site Logo: Add the missing 'site_icon_url' to the REST_API index. ([42957](https://github.com/WordPress/gutenberg/pull/42957)) + +#### Components +- AnglePickerControl: Fix gap between elements in RTL mode. ([42534](https://github.com/WordPress/gutenberg/pull/42534)) +- ColorPalette: Fix background image in RTL mode. ([42510](https://github.com/WordPress/gutenberg/pull/42510)) +- Context System: Don't explicitly set `undefined` value to `children`. ([42686](https://github.com/WordPress/gutenberg/pull/42686)) +- Popover: Fix width on `expandOnMobile`. ([42635](https://github.com/WordPress/gutenberg/pull/42635)) +- RangeControl: Clamp initialPosition between min and max values. ([42571](https://github.com/WordPress/gutenberg/pull/42571)) +- Tooltip: Avoid unnecessary re-renders of ` - ' . $archives . ''; + $show_label = empty( $attributes['showLabel'] ) ? ' screen-reader-text' : ''; + + $block_content = ' + '; return sprintf( '
%2$s
', diff --git a/packages/block-library/src/audio/test/__snapshots__/edit.native.js.snap b/packages/block-library/src/audio/test/__snapshots__/edit.native.js.snap index 6607aa41ddcaf..4a72a64f314b4 100644 --- a/packages/block-library/src/audio/test/__snapshots__/edit.native.js.snap +++ b/packages/block-library/src/audio/test/__snapshots__/edit.native.js.snap @@ -97,7 +97,14 @@ exports[`Audio block renders audio block error state without crashing 1`] = ` } } > - + - + + { canRemove && ( diff --git a/packages/block-library/src/block/edit.native.js b/packages/block-library/src/block/edit.native.js index 6cd3ae6e3192e..f6e49bf1be0f0 100644 --- a/packages/block-library/src/block/edit.native.js +++ b/packages/block-library/src/block/edit.native.js @@ -27,7 +27,8 @@ import { import { useSelect, useDispatch } from '@wordpress/data'; import { __, sprintf } from '@wordpress/i18n'; import { - __experimentalUseNoRecursiveRenders as useNoRecursiveRenders, + __experimentalRecursionProvider as RecursionProvider, + __experimentalUseHasRecursion as useHasRecursion, InnerBlocks, Warning, store as blockEditorStore, @@ -48,8 +49,7 @@ export default function ReusableBlockEdit( { clientId, isSelected, } ) { - const [ hasAlreadyRendered, RecursionProvider ] = - useNoRecursiveRenders( ref ); + const hasAlreadyRendered = useHasRecursion( ref ); const [ showHelp, setShowHelp ] = useState( false ); const infoTextStyle = usePreferredColorSchemeStyle( @@ -214,7 +214,7 @@ export default function ReusableBlockEdit( { } return ( - + :where(.wp-block-button__link), -:where(.wp-block-button__link).is-style-outline { +.wp-block-button.is-style-outline > .wp-block-button__link, +.wp-block-button .wp-block-button__link.is-style-outline { border: 2px solid currentColor; padding: 0.667em 1.333em; } -.is-style-outline > .wp-block-button__link:not(.has-text-color), -.wp-block-button__link.is-style-outline:not(.has-text-color) { +.wp-block-button.is-style-outline > .wp-block-button__link:not(.has-text-color), +.wp-block-button .wp-block-button__link.is-style-outline:not(.has-text-color) { color: currentColor; } -.is-style-outline > .wp-block-button__link:not(.has-background), -.wp-block-button__link.is-style-outline:not(.has-background) { +.wp-block-button.is-style-outline > .wp-block-button__link:not(.has-background), +.wp-block-button .wp-block-button__link.is-style-outline:not(.has-background) { background-color: transparent; } diff --git a/packages/block-library/src/calendar/edit.js b/packages/block-library/src/calendar/edit.js index 5ee7fe14ed072..a60a18d8eeae8 100644 --- a/packages/block-library/src/calendar/edit.js +++ b/packages/block-library/src/calendar/edit.js @@ -1,7 +1,6 @@ /** * External dependencies */ -import moment from 'moment'; import memoize from 'memize'; /** @@ -15,14 +14,22 @@ import { useBlockProps } from '@wordpress/block-editor'; import { store as coreStore } from '@wordpress/core-data'; import { __ } from '@wordpress/i18n'; +/** + * Returns the year and month of a specified date. + * + * @see `WP_REST_Posts_Controller::prepare_date_response()`. + * + * @param {string} date Date in `ISO8601/RFC3339` format. + * @return {Object} Year and date of the specified date. + */ const getYearMonth = memoize( ( date ) => { if ( ! date ) { return {}; } - const momentDate = moment( date ); + const dateObj = new Date( date ); return { - year: momentDate.year(), - month: momentDate.month() + 1, + year: dateObj.getFullYear(), + month: dateObj.getMonth() + 1, }; } ); diff --git a/packages/block-library/src/columns/edit.native.js b/packages/block-library/src/columns/edit.native.js index 306ab96709df8..4f62e227d890e 100644 --- a/packages/block-library/src/columns/edit.native.js +++ b/packages/block-library/src/columns/edit.native.js @@ -2,7 +2,7 @@ * External dependencies */ import { View, Dimensions } from 'react-native'; -import { times, map, delay } from 'lodash'; +import { times, map } from 'lodash'; /** * WordPress dependencies */ @@ -496,7 +496,9 @@ const ColumnsEdit = ( props ) => { useEffect( () => { if ( isSelected && isDefaultColumns ) { - delay( () => setIsVisible( true ), 100 ); + const revealTimeout = setTimeout( () => setIsVisible( true ), 100 ); + + return () => clearTimeout( revealTimeout ); } }, [] ); diff --git a/packages/block-library/src/cover/index.php b/packages/block-library/src/cover/index.php index b67b4823027a3..4168d267671f7 100644 --- a/packages/block-library/src/cover/index.php +++ b/packages/block-library/src/cover/index.php @@ -8,8 +8,8 @@ /** * Renders the `core/cover` block on server. * - * @param array $attributes The block attributes. - * @param array $content The block rendered content. + * @param array $attributes The block attributes. + * @param string $content The block rendered content. * * @return string Returns the cover block markup, if useFeaturedImage is true. */ diff --git a/packages/block-library/src/cover/shared.js b/packages/block-library/src/cover/shared.js index c28f099b48523..0e18d28372764 100644 --- a/packages/block-library/src/cover/shared.js +++ b/packages/block-library/src/cover/shared.js @@ -72,8 +72,9 @@ export function attributesFromMedia( setAttributes, dimRatio ) { id: media.id, alt: media?.alt, backgroundType: mediaType, + focalPoint: undefined, ...( mediaType === VIDEO_BACKGROUND_TYPE - ? { focalPoint: undefined, hasParallax: undefined } + ? { hasParallax: undefined } : {} ), } ); }; diff --git a/packages/block-library/src/file/test/__snapshots__/edit.native.js.snap b/packages/block-library/src/file/test/__snapshots__/edit.native.js.snap index 34a76a0e65096..080c6fa338f8b 100644 --- a/packages/block-library/src/file/test/__snapshots__/edit.native.js.snap +++ b/packages/block-library/src/file/test/__snapshots__/edit.native.js.snap @@ -54,7 +54,14 @@ exports[`File block renders file error state without crashing 1`] = ` } } > - + - + - + - + event.preventDefault(); -export default function HomeEdit( { - attributes, - setAttributes, - context, - clientId, -} ) { - const { homeUrl } = useSelect( - ( select ) => { - const { - getUnstableBase, // Site index. - } = select( coreStore ); - return { - homeUrl: getUnstableBase()?.home, - }; - }, - [ clientId ] - ); +export default function HomeEdit( { attributes, setAttributes, context } ) { + const { homeUrl } = useSelect( ( select ) => { + const { + getUnstableBase, // Site index. + } = select( coreStore ); + return { + homeUrl: getUnstableBase()?.home, + }; + }, [] ); + const { __unstableMarkNextChangeAsNotPersistent } = + useDispatch( blockEditorStore ); const { textColor, backgroundColor, style } = context; const blockProps = useBlockProps( { @@ -50,9 +48,10 @@ export default function HomeEdit( { useEffect( () => { if ( label === undefined ) { + __unstableMarkNextChangeAsNotPersistent(); setAttributes( { label: __( 'Home' ) } ); } - }, [ clientId, label ] ); + }, [ label ] ); return ( <> diff --git a/packages/block-library/src/home-link/index.php b/packages/block-library/src/home-link/index.php index 56712913aa201..55b4884ea9590 100644 --- a/packages/block-library/src/home-link/index.php +++ b/packages/block-library/src/home-link/index.php @@ -89,7 +89,7 @@ function block_core_home_link_build_css_font_sizes( $context ) { * Builds an array with classes and style for the li wrapper * * @param array $context Home link block context. - * @return array The li wrapper attributes. + * @return string The li wrapper attributes. */ function block_core_home_link_build_li_wrapper_attributes( $context ) { $colors = block_core_home_link_build_css_colors( $context ); @@ -125,24 +125,15 @@ function render_block_core_home_link( $attributes, $content, $block ) { return ''; } - $wrapper_attributes = block_core_home_link_build_li_wrapper_attributes( $block->context ); - $aria_current = is_home() || ( is_front_page() && 'page' === get_option( 'show_on_front' ) ) ? ' aria-current="page"' : ''; - $html = '
  • %4$s
  • ', + block_core_home_link_build_li_wrapper_attributes( $block->context ), + esc_url( home_url() ), + $aria_current, + wp_kses_post( $attributes['label'] ) + ); } /** diff --git a/packages/block-library/src/image/test/edit.native.js b/packages/block-library/src/image/test/edit.native.js index e8b748e95e430..323f46d8751a9 100644 --- a/packages/block-library/src/image/test/edit.native.js +++ b/packages/block-library/src/image/test/edit.native.js @@ -7,6 +7,7 @@ import { initializeEditor, getEditorHtml, render, + waitFor, } from 'test/helpers'; import { Image } from 'react-native'; import Clipboard from '@react-native-clipboard/clipboard'; @@ -40,16 +41,6 @@ sendMediaUpload.mockImplementation( ( payload ) => { uploadCallBack( payload ); } ); -/** - * Immediately invoke delayed functions. A better alternative would be using - * fake timers and test the delay itself. However, fake timers does not work - * with our custom waitFor implementation. - */ -jest.mock( 'lodash', () => { - const actual = jest.requireActual( 'lodash' ); - return { ...actual, delay: ( cb ) => cb() }; -} ); - function mockGetMedia( media ) { jest.spyOn( select( coreStore ), 'getMedia' ).mockReturnValue( media ); } @@ -157,6 +148,9 @@ describe( 'Image Block', () => { 'wordpress.org' ); fireEvent.press( screen.getByA11yLabel( 'Apply' ) ); + await waitFor( + () => new Promise( ( resolve ) => setTimeout( resolve, 100 ) ) + ); const expectedHtml = `
    Mountain
    @@ -183,6 +177,7 @@ describe( 'Image Block', () => { ); fireEvent.press( screen.getByText( 'None' ) ); fireEvent.press( screen.getByText( 'Media File' ) ); + await waitFor( () => screen.getByText( 'Custom URL' ) ); fireEvent.press( screen.getByText( 'Custom URL' ) ); // Await asynchronous fetch of clipboard await act( () => clipboardPromise ); @@ -191,6 +186,7 @@ describe( 'Image Block', () => { 'wordpress.org' ); fireEvent.press( screen.getByA11yLabel( 'Apply' ) ); + await waitFor( () => screen.getByText( 'Custom URL' ) ); fireEvent.press( screen.getByText( 'Custom URL' ) ); // Await asynchronous fetch of clipboard await act( () => clipboardPromise ); diff --git a/packages/block-library/src/index.native.js b/packages/block-library/src/index.native.js index 863cd4ef3315d..cdde10333cf07 100644 --- a/packages/block-library/src/index.native.js +++ b/packages/block-library/src/index.native.js @@ -41,6 +41,7 @@ import * as mediaText from './media-text'; import * as latestComments from './latest-comments'; import * as latestPosts from './latest-posts'; import * as list from './list'; +import * as listItem from './list-item'; import * as missing from './missing'; import * as more from './more'; import * as nextpage from './nextpage'; @@ -75,6 +76,7 @@ export const coreBlocks = [ heading, gallery, list, + listItem, quote, // Register all remaining core blocks. @@ -179,6 +181,14 @@ const devOnly = ( block ) => ( !! __DEV__ ? block : null ); const iOSOnly = ( block ) => Platform.OS === 'ios' ? block : devOnly( block ); +// To be removed once List V2 is released on the web editor. +function listCheck( listBlock, blocksFlags ) { + if ( blocksFlags?.__experimentalEnableListBlockV2 ) { + listBlock.settings = listBlock?.settingsV2; + } + return listBlock; +} + // Hide the Classic block and SocialLink block addFilter( 'blocks.registerBlockType', @@ -230,9 +240,11 @@ addFilter( * * registerCoreBlocks(); * ``` + * @param {Object} [blocksFlags] Experimental flags + * * */ -export const registerCoreBlocks = () => { +export const registerCoreBlocks = ( blocksFlags ) => { // When adding new blocks to this list please also consider updating /src/block-support/supported-blocks.json in the Gutenberg-Mobile repo [ paragraph, @@ -244,7 +256,8 @@ export const registerCoreBlocks = () => { video, nextpage, separator, - list, + listCheck( list, blocksFlags ), + listItem, quote, mediaText, preformatted, diff --git a/packages/block-library/src/latest-posts/editor.scss b/packages/block-library/src/latest-posts/editor.scss index 3454f8f5139f0..3c2d6a30f1c07 100644 --- a/packages/block-library/src/latest-posts/editor.scss +++ b/packages/block-library/src/latest-posts/editor.scss @@ -3,6 +3,11 @@ &.is-grid { padding-left: 0; } + + // Apply overflow for post items, so any floated featured images won't crop the focus style. + > li { + overflow: hidden; + } } .wp-block-latest-posts li a > div { diff --git a/packages/block-library/src/list-item/edit.js b/packages/block-library/src/list-item/edit.js index 303cade808454..3447cce9e4bbd 100644 --- a/packages/block-library/src/list-item/edit.js +++ b/packages/block-library/src/list-item/edit.js @@ -30,7 +30,7 @@ import { } from './hooks'; import { convertToListItems } from './utils'; -function IndentUI( { clientId } ) { +export function IndentUI( { clientId } ) { const [ canIndent, indentListItem ] = useIndentListItem( clientId ); const [ canOutdent, outdentListItem ] = useOutdentListItem( clientId ); diff --git a/packages/block-library/src/list-item/edit.native.js b/packages/block-library/src/list-item/edit.native.js new file mode 100644 index 0000000000000..2762c28c6024d --- /dev/null +++ b/packages/block-library/src/list-item/edit.native.js @@ -0,0 +1,148 @@ +/** + * External dependencies + */ +import { View } from 'react-native'; + +/** + * WordPress dependencies + */ +import { + RichText, + useBlockProps, + useInnerBlocksProps, + BlockControls, + store as blockEditorStore, +} from '@wordpress/block-editor'; +import { __ } from '@wordpress/i18n'; +import { useSelect } from '@wordpress/data'; +import { useState, useCallback } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { useSplit, useMerge } from './hooks'; +import { convertToListItems } from './utils'; +import { IndentUI } from './edit.js'; +import styles from './style.scss'; +import ListStyleType from './list-style-type'; + +export default function ListItemEdit( { + attributes, + setAttributes, + onReplace, + clientId, + style, +} ) { + const [ contentWidth, setContentWidth ] = useState(); + const { placeholder, content } = attributes; + const { + blockIndex, + hasInnerBlocks, + indentationLevel, + numberOfListItems, + ordered, + reversed, + start, + } = useSelect( + ( select ) => { + const { + getBlockAttributes, + getBlockCount, + getBlockIndex, + getBlockParentsByBlockName, + getBlockRootClientId, + } = select( blockEditorStore ); + const currentIdentationLevel = getBlockParentsByBlockName( + clientId, + 'core/list-item', + true + ).length; + const currentBlockIndex = getBlockIndex( clientId ); + const blockWithInnerBlocks = getBlockCount( clientId ) > 0; + const rootClientId = getBlockRootClientId( clientId ); + const blockAttributes = getBlockAttributes( rootClientId ); + const totalListItems = getBlockCount( rootClientId ); + const { + ordered: isOrdered, + reversed: isReversed, + start: startValue, + } = blockAttributes || {}; + + return { + blockIndex: currentBlockIndex, + hasInnerBlocks: blockWithInnerBlocks, + indentationLevel: currentIdentationLevel, + numberOfListItems: totalListItems, + ordered: isOrdered, + reversed: isReversed, + start: startValue, + }; + }, + [ clientId ] + ); + + const blockProps = useBlockProps( { + ...( hasInnerBlocks && styles[ 'wp-block-list-item__nested-blocks' ] ), + } ); + const innerBlocksProps = useInnerBlocksProps( blockProps, { + allowedBlocks: [ 'core/list' ], + renderAppender: false, + } ); + + const onSplit = useSplit( clientId ); + const onMerge = useMerge( clientId ); + const onLayout = useCallback( ( { nativeEvent } ) => { + setContentWidth( ( prevState ) => { + const { width } = nativeEvent.layout; + + if ( ! prevState || prevState.width !== width ) { + return Math.floor( width ); + } + return prevState; + } ); + }, [] ); + + return ( + + + + + + + + setAttributes( { content: nextContent } ) + } + value={ content } + placeholder={ placeholder || __( 'List' ) } + onSplit={ onSplit } + onMerge={ onMerge } + onReplace={ ( blocks, ...args ) => { + onReplace( convertToListItems( blocks ), ...args ); + } } + style={ style } + deleteEnter={ true } + containerWidth={ contentWidth } + /> + + + + + + + + ); +} diff --git a/packages/block-library/src/list-item/icons.native.js b/packages/block-library/src/list-item/icons.native.js new file mode 100644 index 0000000000000..ee8aebada41ef --- /dev/null +++ b/packages/block-library/src/list-item/icons.native.js @@ -0,0 +1,34 @@ +/** + * WordPress dependencies + */ +import { SVG, Rect } from '@wordpress/components'; + +export const circle = ( size, color ) => ( + + + +); + +export const circleOutline = ( size, color ) => ( + + + +); + +export const square = ( size, color ) => ( + + + +); diff --git a/packages/block-library/src/list-item/list-style-type.native.js b/packages/block-library/src/list-item/list-style-type.native.js new file mode 100644 index 0000000000000..c3bd787ff2960 --- /dev/null +++ b/packages/block-library/src/list-item/list-style-type.native.js @@ -0,0 +1,139 @@ +/** + * External dependencies + */ +import { View, Text } from 'react-native'; + +/** + * WordPress dependencies + */ +import { Icon } from '@wordpress/components'; +import { Platform } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import styles from './style.scss'; +import { circle, circleOutline, square } from './icons'; + +const DEFAULT_ICON_SIZE = 6; + +function getListNumberIndex( start, blockIndex, reversed, numberOfListItems ) { + if ( start ) { + return reversed + ? numberOfListItems - 1 + start - blockIndex + : start + blockIndex; + } + + if ( reversed ) { + return numberOfListItems - blockIndex; + } + + return blockIndex + 1; +} + +function OrderedList( { + blockIndex, + color, + fontSize, + numberOfListItems, + reversed, + start, + style, +} ) { + const orderedStyles = [ + styles[ 'wp-block-list-item__list-item-container--ordered' ], + Platform.isIOS && + styles[ 'wp-block-list-item__list-item-ordered--default' ], + Platform.isIOS && + style?.fontSize && + styles[ 'wp-block-list-item__list-item-ordered--custom' ], + ]; + const numberStyle = [ { fontSize, color } ]; + + const currentIndex = getListNumberIndex( + start, + blockIndex, + reversed, + numberOfListItems + ); + + return ( + + { currentIndex }. + + ); +} + +function IconList( { fontSize, color, defaultFontSize, indentationLevel } ) { + const iconSize = parseInt( + ( fontSize * DEFAULT_ICON_SIZE ) / defaultFontSize, + 10 + ); + + let listIcon = circle( iconSize, color ); + if ( indentationLevel === 1 ) { + listIcon = circleOutline( iconSize, color ); + } else if ( indentationLevel > 1 ) { + listIcon = square( iconSize, color ); + } + + const listStyles = [ + styles[ 'wp-block-list-item__list-item-container' ], + { marginTop: fontSize / 2 }, + ]; + + return ( + + + + ); +} + +export default function ListStyleType( { + blockIndex, + indentationLevel, + numberOfListItems, + ordered, + reversed, + start, + style, +} ) { + let defaultFontSize = + styles[ 'wp-block-list-item__list-item--default' ].fontSize; + + if ( style?.baseColors?.typography?.fontSize ) { + defaultFontSize = parseInt( style.baseColors.typography.fontSize, 10 ); + } + + const fontSize = parseInt( + style?.fontSize ? style.fontSize : defaultFontSize, + 10 + ); + const defaultColor = style?.baseColors?.color?.text + ? style.baseColors.color.text + : styles[ 'wp-block-list-item__list-item--default' ].color; + const color = style?.color ? style.color : defaultColor; + + if ( ordered ) { + return ( + + ); + } + + return ( + + ); +} diff --git a/packages/block-library/src/list-item/style.native.scss b/packages/block-library/src/list-item/style.native.scss new file mode 100644 index 0000000000000..6b4f2dcc04356 --- /dev/null +++ b/packages/block-library/src/list-item/style.native.scss @@ -0,0 +1,45 @@ +.wp-block-list-item__list-item-parent { + margin-left: $solid-border-space; + margin-right: $solid-border-space; +} + +.wp-block-list-item__nested-blocks { + margin-top: 14; +} + +.wp-block-list-item__list-item { + flex: 1; + flex-direction: row; +} + +.wp-block-list-item__list-item-icon { + align-items: center; + flex-grow: 0; +} + +.wp-block-list-item__list-item-content { + flex-grow: 1; + flex-shrink: 1; + background-color: transparent; +} + +.wp-block-list-item__list-item--default { + color: $black; + font-size: $editor-font-size; +} + +.wp-block-list-item__list-item-ordered--default { + margin-top: 2; +} + +.wp-block-list-item__list-item-ordered--custom { + margin-top: 3; +} + +.wp-block-list-item__list-item-container--ordered { + margin-right: 3; +} + +.wp-block-list-item__list-item-container { + margin-right: 8; +} diff --git a/packages/block-library/src/list/index.js b/packages/block-library/src/list/index.js index bef6b6558df89..a401d75eb1458 100644 --- a/packages/block-library/src/list/index.js +++ b/packages/block-library/src/list/index.js @@ -15,7 +15,7 @@ import settingsV2 from './v2'; const { name } = metadata; -export { metadata, name }; +export { metadata, name, settingsV2 }; const settingsV1 = { icon, diff --git a/packages/block-library/src/list/test/__snapshots__/edit.native.js.snap b/packages/block-library/src/list/test/__snapshots__/edit.native.js.snap new file mode 100644 index 0000000000000..3fe53069b1775 --- /dev/null +++ b/packages/block-library/src/list/test/__snapshots__/edit.native.js.snap @@ -0,0 +1,133 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`List V2 block adds one item to the list 1`] = ` +" +
      +
    • First list item
    • +
    +" +`; + +exports[`List V2 block changes the indentation level 1`] = ` +" +
      +
    • Item 1 +
        +
      • Item 2
      • +
      +
    • +
    +" +`; + +exports[`List V2 block changes to ordered list 1`] = ` +" +
      +
    1. Item 1
    2. + + + +
    3. Item 2
    4. + + + +
    5. Item 3
    6. +
    +" +`; + +exports[`List V2 block changes to reverse ordered list 1`] = ` +" +
      +
    1. Item 1
    2. + + + +
    3. Item 2
    4. + + + +
    5. Item 3
    6. +
    +" +`; + +exports[`List V2 block inserts block 1`] = ` +" +
      +
    • +
    +" +`; + +exports[`List V2 block removes the indentation level 1`] = ` +" +
      +
    • Item 1
    • + + + +
    • Item 2
    • +
    +" +`; + +exports[`List V2 block sets a start value to an ordered list 1`] = ` +" +
      +
    1. Item 1
    2. + + + +
    3. Item 2
    4. + + + +
    5. Item 3
    6. +
    +" +`; + +exports[`List V2 block shows different indentation levels 1`] = ` +" +
      +
    • List item 1
    • + + + +
    • List item 2 +
        +
      • List item nested 1
      • + + + +
      • List item nested 2 +
          +
        • Extra item 1
        • + + + +
        • Extra item 2
        • +
        +
      • +
      +
    • + + + +
    • List item 3
    • +
    +" +`; + +exports[`List block inserts block 1`] = ` +" +
    +" +`; + +exports[`List block renders a list with a few items 1`] = ` +" +
    • Item 1
    • Item 2
    • Item 3
    +" +`; diff --git a/packages/block-library/src/list/test/edit.native.js b/packages/block-library/src/list/test/edit.native.js index 73a15b9604e4d..62738da807dc4 100644 --- a/packages/block-library/src/list/test/edit.native.js +++ b/packages/block-library/src/list/test/edit.native.js @@ -1,16 +1,520 @@ /** * External dependencies */ -import { render } from 'test/helpers'; +import { + changeTextOfRichText, + fireEvent, + getEditorHtml, + initializeEditor, + waitFor, + within, +} from 'test/helpers'; /** - * Internal dependencies + * WordPress dependencies */ -import ListEdit from '../edit'; +import { getBlockTypes, unregisterBlockType } from '@wordpress/blocks'; +import { registerCoreBlocks } from '@wordpress/block-library'; -describe( 'ListEdit component', () => { - it( 'renders without crashing', () => { - const screen = render( ); - expect( screen.container ).toBeTruthy(); +describe( 'List block', () => { + beforeAll( () => { + // Register all core blocks + registerCoreBlocks( { + __experimentalEnableListBlockV2: false, + } ); + } ); + + afterAll( () => { + // Clean up registered blocks + getBlockTypes().forEach( ( block ) => { + unregisterBlockType( block.name ); + } ); + } ); + + it( 'inserts block', async () => { + const { getByA11yLabel, getByTestId, getByText } = + await initializeEditor(); + + fireEvent.press( getByA11yLabel( 'Add block' ) ); + + const blockList = getByTestId( 'InserterUI-Blocks' ); + // onScroll event used to force the FlatList to render all items + fireEvent.scroll( blockList, { + nativeEvent: { + contentOffset: { y: 0, x: 0 }, + contentSize: { width: 100, height: 100 }, + layoutMeasurement: { width: 100, height: 100 }, + }, + } ); + + fireEvent.press( await waitFor( () => getByText( 'List' ) ) ); + + expect( getByA11yLabel( /List Block\. Row 1/ ) ).toBeVisible(); + expect( getEditorHtml() ).toMatchSnapshot(); + } ); + + it( 'renders a list with a few items', async () => { + const initialHtml = ` +
    • Item 1
    • Item 2
    • Item 3
    + `; + + const { getByA11yLabel } = await initializeEditor( { + initialHtml, + } ); + + // Select List block + const listBlock = getByA11yLabel( /List Block\. Row 1/ ); + fireEvent.press( listBlock ); + + expect( getEditorHtml() ).toMatchSnapshot(); + } ); +} ); + +describe( 'List V2 block', () => { + beforeAll( () => { + // Register all core blocks + registerCoreBlocks( { + __experimentalEnableListBlockV2: true, + } ); + } ); + + afterAll( () => { + // Clean up registered blocks + getBlockTypes().forEach( ( block ) => { + unregisterBlockType( block.name ); + } ); + } ); + + it( 'inserts block', async () => { + const { getByA11yLabel, getByTestId, getByText } = + await initializeEditor(); + + fireEvent.press( getByA11yLabel( 'Add block' ) ); + + const blockList = getByTestId( 'InserterUI-Blocks' ); + // onScroll event used to force the FlatList to render all items + fireEvent.scroll( blockList, { + nativeEvent: { + contentOffset: { y: 0, x: 0 }, + contentSize: { width: 100, height: 100 }, + layoutMeasurement: { width: 100, height: 100 }, + }, + } ); + + fireEvent.press( await waitFor( () => getByText( 'List' ) ) ); + + expect( getByA11yLabel( /List Block\. Row 1/ ) ).toBeVisible(); + expect( getEditorHtml() ).toMatchSnapshot(); + } ); + + it( 'adds one item to the list', async () => { + const initialHtml = ` +
      +
    + `; + + const { getByA11yLabel } = await initializeEditor( { + initialHtml, + } ); + + // Select List block + const listBlock = getByA11yLabel( /List Block\. Row 1/ ); + + fireEvent( + within( listBlock ).getByTestId( 'block-list-wrapper' ), + 'layout', + { + nativeEvent: { + layout: { + width: 100, + height: 50, + }, + }, + } + ); + + fireEvent.press( listBlock ); + + // Select List Item block + const listItemBlock = getByA11yLabel( /List item Block\. Row 1/ ); + fireEvent.press( listItemBlock ); + + const listItemField = + within( listBlock ).getByPlaceholderText( 'List' ); + changeTextOfRichText( listItemField, 'First list item' ); + + expect( getEditorHtml() ).toMatchSnapshot(); + } ); + + it( 'shows different indentation levels', async () => { + const initialHtml = ` +
      +
    • List item 1
    • + + +
    • List item 2 +
        +
      • List item nested 1
      • + + +
      • List item nested 2 +
          +
        • Extra item 1
        • + + +
        • Extra item 2
        • +
        +
      • +
      +
    • + + +
    • List item 3
    • +
    + `; + + const { getByA11yLabel } = await initializeEditor( { + initialHtml, + } ); + + // Select List block + const listBlock = getByA11yLabel( /List Block\. Row 1/ ); + + fireEvent( + within( listBlock ).getByTestId( 'block-list-wrapper' ), + 'layout', + { + nativeEvent: { + layout: { + width: 100, + height: 50, + }, + }, + } + ); + + fireEvent.press( listBlock ); + + // Select List Item block + const firstNestedLevelBlock = within( listBlock ).getByA11yLabel( + /List item Block\. Row 2/ + ); + + fireEvent( + within( firstNestedLevelBlock ).getByTestId( 'block-list-wrapper' ), + 'layout', + { + nativeEvent: { + layout: { + width: 100, + height: 350, + }, + }, + } + ); + + fireEvent.press( firstNestedLevelBlock ); + + // Select second level list + const secondNestedLevelBlock = within( + firstNestedLevelBlock + ).getByA11yLabel( /List Block\. Row 1/ ); + + fireEvent( + within( secondNestedLevelBlock ).getByTestId( + 'block-list-wrapper' + ), + 'layout', + { + nativeEvent: { + layout: { + width: 100, + height: 50, + }, + }, + } + ); + + fireEvent.press( secondNestedLevelBlock ); + + expect( getEditorHtml() ).toMatchSnapshot(); + } ); + + it( 'changes the indentation level', async () => { + const initialHtml = ` +
      +
    • Item 1
    • + + +
    • Item 2
    • +
    + `; + + const { getByA11yLabel } = await initializeEditor( { + initialHtml, + } ); + + // Select List block + const listBlock = getByA11yLabel( /List Block\. Row 1/ ); + + fireEvent( + within( listBlock ).getByTestId( 'block-list-wrapper' ), + 'layout', + { + nativeEvent: { + layout: { + width: 100, + height: 50, + }, + }, + } + ); + + fireEvent.press( listBlock ); + + // Select Secont List Item block + const listItemBlock = getByA11yLabel( /List item Block\. Row 2/ ); + fireEvent.press( listItemBlock ); + + // Update indentation + const indentButton = getByA11yLabel( 'Indent' ); + fireEvent.press( indentButton ); + + expect( getEditorHtml() ).toMatchSnapshot(); + } ); + + it( 'removes the indentation level', async () => { + const initialHtml = ` +
      +
    • Item 1 +
        +
      • Item 2
      • +
      +
    • +
    + `; + + const { getByA11yLabel } = await initializeEditor( { + initialHtml, + } ); + + // Select List block + const listBlock = getByA11yLabel( /List Block\. Row 1/ ); + + fireEvent( + within( listBlock ).getByTestId( 'block-list-wrapper' ), + 'layout', + { + nativeEvent: { + layout: { + width: 100, + height: 50, + }, + }, + } + ); + + fireEvent.press( listBlock ); + + // Select List Item block + const firstNestedLevelBlock = within( listBlock ).getByA11yLabel( + /List item Block\. Row 1/ + ); + + fireEvent( + within( firstNestedLevelBlock ).getByTestId( 'block-list-wrapper' ), + 'layout', + { + nativeEvent: { + layout: { + width: 100, + height: 350, + }, + }, + } + ); + + fireEvent.press( firstNestedLevelBlock ); + + // Select Inner block List + const innerBlockList = within( firstNestedLevelBlock ).getByA11yLabel( + /List Block\. Row 1/ + ); + + fireEvent( + within( innerBlockList ).getByTestId( 'block-list-wrapper' ), + 'layout', + { + nativeEvent: { + layout: { + width: 100, + height: 50, + }, + }, + } + ); + + // Select nested List Item block + const listItemBlock = within( innerBlockList ).getByA11yLabel( + /List item Block\. Row 1/ + ); + fireEvent.press( listItemBlock ); + + // Update indentation + const outdentButton = getByA11yLabel( 'Outdent' ); + fireEvent.press( outdentButton ); + + expect( getEditorHtml() ).toMatchSnapshot(); + } ); + + it( 'changes to ordered list', async () => { + const initialHtml = ` +
      +
    • Item 1
    • + + +
    • Item 2
    • + + +
    • Item 3
    • +
    + `; + + const { getByA11yLabel } = await initializeEditor( { + initialHtml, + } ); + + // Select List block + const listBlock = getByA11yLabel( /List Block\. Row 1/ ); + + fireEvent( + within( listBlock ).getByTestId( 'block-list-wrapper' ), + 'layout', + { + nativeEvent: { + layout: { + width: 100, + height: 50, + }, + }, + } + ); + + fireEvent.press( listBlock ); + + // Update to ordered list + const orderedButton = getByA11yLabel( 'Ordered' ); + fireEvent.press( orderedButton ); + + expect( getEditorHtml() ).toMatchSnapshot(); + } ); + + it( 'changes to reverse ordered list', async () => { + const initialHtml = ` +
      +
    • Item 1
    • + + +
    • Item 2
    • + + +
    • Item 3
    • +
    + `; + + const { getByA11yLabel, getByTestId } = await initializeEditor( { + initialHtml, + } ); + + // Select List block + const listBlock = getByA11yLabel( /List Block\. Row 1/ ); + + fireEvent( + within( listBlock ).getByTestId( 'block-list-wrapper' ), + 'layout', + { + nativeEvent: { + layout: { + width: 100, + height: 50, + }, + }, + } + ); + + fireEvent.press( listBlock ); + + // Update to ordered list + const orderedButton = getByA11yLabel( 'Ordered' ); + fireEvent.press( orderedButton ); + + // Set order to reverse + + // Open block settings + fireEvent.press( getByA11yLabel( 'Open Settings' ) ); + await waitFor( + () => getByTestId( 'block-settings-modal' ).props.isVisible + ); + + const reverseButton = getByA11yLabel( /Reverse list numbering\. Off/ ); + fireEvent.press( reverseButton ); + + expect( getEditorHtml() ).toMatchSnapshot(); + } ); + + it( 'sets a start value to an ordered list', async () => { + const initialHtml = ` +
      +
    • Item 1
    • + + +
    • Item 2
    • + + +
    • Item 3
    • +
    + `; + + const { getByA11yLabel, getByTestId } = await initializeEditor( { + initialHtml, + } ); + + // Select List block + const listBlock = getByA11yLabel( /List Block\. Row 1/ ); + + fireEvent( + within( listBlock ).getByTestId( 'block-list-wrapper' ), + 'layout', + { + nativeEvent: { + layout: { + width: 100, + height: 50, + }, + }, + } + ); + + fireEvent.press( listBlock ); + + // Update to ordered list + const orderedButton = getByA11yLabel( 'Ordered' ); + fireEvent.press( orderedButton ); + + // Set order to reverse + + // Open block settings + fireEvent.press( getByA11yLabel( 'Open Settings' ) ); + await waitFor( + () => getByTestId( 'block-settings-modal' ).props.isVisible + ); + + const startValueButton = getByA11yLabel( /Start value\. Empty/ ); + fireEvent.press( startValueButton ); + const startValueInput = + within( startValueButton ).getByDisplayValue( '' ); + fireEvent.changeText( startValueInput, '25' ); + + expect( getEditorHtml() ).toMatchSnapshot(); } ); } ); diff --git a/packages/block-library/src/list/v2/edit.js b/packages/block-library/src/list/v2/edit.js index 77029179d2879..9ef320b53b001 100644 --- a/packages/block-library/src/list/v2/edit.js +++ b/packages/block-library/src/list/v2/edit.js @@ -24,7 +24,7 @@ import { formatOutdentRTL, } from '@wordpress/icons'; import { createBlock } from '@wordpress/blocks'; -import { useCallback, useEffect } from '@wordpress/element'; +import { useCallback, useEffect, Platform } from '@wordpress/element'; import deprecated from '@wordpress/deprecated'; /** @@ -32,8 +32,10 @@ import deprecated from '@wordpress/deprecated'; */ import OrderedListSettings from '../ordered-list-settings'; import { migrateToListV2 } from './migrate'; +import TagName from './tag-name'; const TEMPLATE = [ [ 'core/list-item' ] ]; +const NATIVE_MARGIN_SPACING = 8; /** * At the moment, deprecations don't handle create blocks from attributes @@ -126,16 +128,21 @@ function IndentUI( { clientId } ) { ); } -function Edit( { attributes, setAttributes, clientId } ) { - const blockProps = useBlockProps(); +function Edit( { attributes, setAttributes, clientId, style } ) { + const blockProps = useBlockProps( { + ...( Platform.isNative && { style } ), + } ); const innerBlocksProps = useInnerBlocksProps( blockProps, { allowedBlocks: [ 'core/list-item' ], template: TEMPLATE, templateInsertUpdatesSelection: true, + ...( Platform.isNative && { + marginVertical: NATIVE_MARGIN_SPACING, + marginHorizontal: NATIVE_MARGIN_SPACING, + } ), } ); useMigrateOnLoad( attributes, clientId ); const { ordered, reversed, start } = attributes; - const TagName = ordered ? 'ol' : 'ul'; const controls = ( @@ -164,6 +171,7 @@ function Edit( { attributes, setAttributes, clientId } ) { return ( <> ; +} + +export default forwardRef( TagName ); diff --git a/packages/block-library/src/list/v2/tag-name.native.js b/packages/block-library/src/list/v2/tag-name.native.js new file mode 100644 index 0000000000000..ddf9987bfa515 --- /dev/null +++ b/packages/block-library/src/list/v2/tag-name.native.js @@ -0,0 +1,12 @@ +/** + * WordPress dependencies + */ +import { forwardRef } from '@wordpress/element'; +import { View } from '@wordpress/primitives'; + +function TagName( props, ref ) { + const { start, ...extraProps } = props; + return ; +} + +export default forwardRef( TagName ); diff --git a/packages/block-library/src/media-text/deprecated.js b/packages/block-library/src/media-text/deprecated.js index b81e1632188d3..f79dd94764146 100644 --- a/packages/block-library/src/media-text/deprecated.js +++ b/packages/block-library/src/media-text/deprecated.js @@ -17,9 +17,19 @@ import { /** * Internal dependencies */ -import { imageFillStyles } from './media-container'; import { DEFAULT_MEDIA_SIZE_SLUG } from './constants'; +const v1ToV5ImageFillStyles = ( url, focalPoint ) => { + return url + ? { + backgroundImage: `url(${ url })`, + backgroundPosition: focalPoint + ? `${ focalPoint.x * 100 }% ${ focalPoint.y * 100 }%` + : `50% 50%`, + } + : {}; +}; + const DEFAULT_MEDIA_WIDTH = 50; const noop = () => {}; @@ -43,9 +53,6 @@ const baseAttributes = { type: 'string', default: 'wide', }, - backgroundColor: { - type: 'string', - }, mediaAlt: { type: 'string', source: 'attribute', @@ -73,257 +80,464 @@ const baseAttributes = { }, }; -export default [ - // Version with CSS grid - { - attributes: { - align: { - type: 'string', - default: 'wide', - }, - mediaAlt: { - type: 'string', - source: 'attribute', - selector: 'figure img', - attribute: 'alt', - default: '', - }, - mediaPosition: { - type: 'string', - default: 'left', - }, - mediaId: { - type: 'number', - }, - mediaUrl: { - type: 'string', - source: 'attribute', - selector: 'figure video,figure img', - attribute: 'src', - }, - mediaLink: { - type: 'string', - }, - linkDestination: { - type: 'string', - }, - linkTarget: { - type: 'string', - source: 'attribute', - selector: 'figure a', - attribute: 'target', - }, - href: { - type: 'string', - source: 'attribute', - selector: 'figure a', - attribute: 'href', - }, - rel: { - type: 'string', - source: 'attribute', - selector: 'figure a', - attribute: 'rel', - }, - linkClass: { - type: 'string', - source: 'attribute', - selector: 'figure a', - attribute: 'class', - }, - mediaType: { - type: 'string', - }, - mediaWidth: { - type: 'number', - default: 50, - }, - mediaSizeSlug: { - type: 'string', - }, - isStackedOnMobile: { - type: 'boolean', - default: true, - }, - verticalAlignment: { - type: 'string', - }, - imageFill: { - type: 'boolean', - }, - focalPoint: { - type: 'object', - }, - }, - supports: { - anchor: true, - align: [ 'wide', 'full' ], - html: false, - color: { - gradients: true, - link: true, - }, - }, - save( { attributes } ) { - const { - isStackedOnMobile, - mediaAlt, - mediaPosition, - mediaType, - mediaUrl, - mediaWidth, - mediaId, - verticalAlignment, - imageFill, - focalPoint, - linkClass, - href, - linkTarget, - rel, - } = attributes; - const mediaSizeSlug = - attributes.mediaSizeSlug || DEFAULT_MEDIA_SIZE_SLUG; - const newRel = isEmpty( rel ) ? undefined : rel; - - const imageClasses = classnames( { - [ `wp-image-${ mediaId }` ]: mediaId && mediaType === 'image', - [ `size-${ mediaSizeSlug }` ]: mediaId && mediaType === 'image', - } ); - - let image = ( - { +const v4ToV5BlockAttributes = { + ...baseAttributes, + mediaUrl: { + type: 'string', + source: 'attribute', + selector: 'figure video,figure img', + attribute: 'src', + }, + mediaLink: { + type: 'string', + }, + linkDestination: { + type: 'string', + }, + linkTarget: { + type: 'string', + source: 'attribute', + selector: 'figure a', + attribute: 'target', + }, + href: { + type: 'string', + source: 'attribute', + selector: 'figure a', + attribute: 'href', + }, + rel: { + type: 'string', + source: 'attribute', + selector: 'figure a', + attribute: 'rel', + }, + linkClass: { + type: 'string', + source: 'attribute', + selector: 'figure a', + attribute: 'class', + }, + mediaSizeSlug: { + type: 'string', + }, + verticalAlignment: { + type: 'string', + }, + imageFill: { + type: 'boolean', + }, + focalPoint: { + type: 'object', + }, +}; + +const v4ToV5Supports = { + anchor: true, + align: [ 'wide', 'full' ], + html: false, + color: { + gradients: true, + link: true, + }, +}; + +const v5 = { + attributes: v4ToV5BlockAttributes, + supports: v4ToV5Supports, + save( { attributes } ) { + const { + isStackedOnMobile, + mediaAlt, + mediaPosition, + mediaType, + mediaUrl, + mediaWidth, + mediaId, + verticalAlignment, + imageFill, + focalPoint, + linkClass, + href, + linkTarget, + rel, + } = attributes; + const mediaSizeSlug = + attributes.mediaSizeSlug || DEFAULT_MEDIA_SIZE_SLUG; + const newRel = isEmpty( rel ) ? undefined : rel; + + const imageClasses = classnames( { + [ `wp-image-${ mediaId }` ]: mediaId && mediaType === 'image', + [ `size-${ mediaSizeSlug }` ]: mediaId && mediaType === 'image', + } ); + + let image = ( + { + ); + + if ( href ) { + image = ( + + { image } + ); + } - if ( href ) { - image = ( - - { image } - - ); - } - - const mediaTypeRenders = { - image: () => image, - video: () =>