diff --git a/.github/patch-initial-checklist.md b/.github/patch-initial-checklist.md index c1ef0ce8557..3e1453fbe6e 100644 --- a/.github/patch-initial-checklist.md +++ b/.github/patch-initial-checklist.md @@ -21,7 +21,7 @@ The release pull request has been created! This checklist is a guide to follow f - [ ] Run `npm ci` - [ ] Run `npm run package-plugin:deploy`. This will create a zip of the current branch build locally. - [ ] Create the testing notes for the release. - - [ ] For each pull request that belongs to the current release, grab the `User Facing Testing` notes from the PR's description. + - [ ] For each pull request that belongs to the current release, grab the `User Facing Testing` notes from the PR's description. - If a PR has the `Should be tested by the development team exclusively` checkbox checked, create a new section called 'Testing notes for the development team' and copy the `User Facing Testing` notes from the PR to this section. - If a PR has the `Experimental` checkbox checked, do not include it in the testing instructions. - If a PR has the `Do not include in the Testing Notes` checkbox checked, as the description suggests, do not include it in the release instructions. @@ -66,7 +66,7 @@ Each porter is responsible for testing the PRs that fall under the focus of thei ## After Deploy -- [ ] Port to `trunk` the changes to the changelog, testing steps and required versions that you did in the previous steps. You can do so copy-and-pasting the changes in a new commit directly to `trunk`, or cherry-picking the commits that introduced those changes. +- [ ] Move the changes to the changelog, testing steps and required versions that you did in the previous steps to `trunk`. You can do so copy-and-pasting the changes in a new commit directly to `trunk`, or cherry-picking the commits that introduced those changes. - [ ] Update the schedules p2 with the shipped date for the release (PdToLP-K-p2). - [ ] Edit the GitHub milestone of the release you just shipped and add the current date as the due date (this is used to track ship date as well). diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 77dcfbddef5..77f23181e58 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,47 +1,19 @@ - + - +## What Fixes # - - +## Why -#### Accessibility + - - -- [ ] I've tested using only a keyboard (no mouse) -- [ ] I've tested using a screen reader -- [ ] All animations respect [`prefers-reduced-motion`](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion) -- [ ] All text has [at least a 4.5 color contrast with its background](https://webaim.org/resources/contrastchecker/) - -#### Other Checks - -- [ ] This PR has either a `[type]` label or a `[skip-changelog]` label. -- [ ] This PR adds/removes a feature flag & I've updated [this doc](https://github.com/woocommerce/woocommerce-blocks/blob/trunk/docs/internal-developers/blocks/feature-flags-and-experimental-interfaces.md). -- [ ] This PR adds/removes an experimental interfaces and I've updated [this doc](https://github.com/woocommerce/woocommerce-blocks/blob/trunk/docs/internal-developers/blocks/feature-flags-and-experimental-interfaces.md). -- [ ] I tagged two reviewers because this PR makes queries to the database or I think it might have some security impact. - -### Screenshots - - - -| Before | After | -| ------ | ----- | -| | | - -### Testing - -#### Automated Tests -* [ ] Changes in this PR are covered by Automated Tests. - * [ ] Unit tests - * [ ] E2E tests - -#### User Facing Testing +## Testing Instructions +_Please consider any edge cases this change may have, and also other areas of the product this may impact._ + 1. 2. 3. @@ -49,18 +21,38 @@ Fixes # * [ ] Do not include in the Testing Notes * [ ] Should be tested by the development team exclusively -### WooCommerce Visibility +## Screenshots or screencast + + + +| Before | After | +| ------ | ----- | +| | | - +## WooCommerce Visibility + + +Required: * [ ] WooCommerce Core * [ ] Feature plugin * [ ] Experimental +* [ ] N/A + +## Checklist -### Performance Impact +Required: +* [ ] This PR has either a `[type]` label or a `[skip-changelog]` label. +* [ ] This PR is assigned to a milestone. - +Conditional: +* [ ] This PR has a changelog description (if `[skip-changelog]` label is not present). +* [ ] This PR adds/removes a feature flag & I've updated [this doc](https://github.com/woocommerce/woocommerce-blocks/blob/trunk/docs/internal-developers/blocks/feature-flags-and-experimental-interfaces.md). +* [ ] This PR adds/removes an experimental interfaces, and I've updated [this doc](https://github.com/woocommerce/woocommerce-blocks/blob/trunk/docs/internal-developers/blocks/feature-flags-and-experimental-interfaces.md). +* [ ] This PR has been accessibility tested. +* [ ] This PR has had any necessary documentation added/updated. -### Changelog +## Changelog + > Add suggested changelog entry here. diff --git a/.github/release-initial-checklist.md b/.github/release-initial-checklist.md index 1c64ff15f77..958a8bc038e 100644 --- a/.github/release-initial-checklist.md +++ b/.github/release-initial-checklist.md @@ -81,7 +81,7 @@ Each porter is responsible for testing the PRs that fall under the focus of thei ## After Workflow completes -- [ ] Port to `trunk` the changes to the changelog, testing steps and required versions that you did in the previous steps. You can do so copy-and-pasting the changes in a new commit directly to `trunk`, or cherry-picking the commits that introduced those changes. +- [ ] Move the changes to the changelog, testing steps and required versions that you did in the previous steps to `trunk`. You can do so copy-and-pasting the changes in a new commit directly to `trunk`, or cherry-picking the commits that introduced those changes. - [ ] Run `npm run change-versions` to update the version in `trunk` to the next version of the plugin and include the `dev` suffix. For example, if you released 2.5.0, you should update the version in `trunk` to 2.6.0-dev. - [ ] Update the schedules p2 with the shipped date for the release (PdToLP-K-p2). - [ ] Edit the GitHub milestone of the release you just shipped and add the current date as the due date (this is used to track ship date as well). diff --git a/.github/workflows/check-doc-links.yml b/.github/workflows/check-doc-links.yml index 805a85be97b..058b2fb3747 100644 --- a/.github/workflows/check-doc-links.yml +++ b/.github/workflows/check-doc-links.yml @@ -11,18 +11,23 @@ concurrency: permissions: {} jobs: - markdown-link-check: - runs-on: ubuntu-latest - permissions: - contents: read - steps: - - uses: actions/checkout@v3 - - uses: gaurav-nelson/github-action-markdown-link-check@v1 - with: - use-quiet-mode: 'yes' - use-verbose-mode: 'no' - config-file: '.github/workflows/check-doc-links-config.json' - folder-path: './docs' - file-path: './README.md' - max-depth: 3 - base-branch: 'trunk' + markdown_link_check: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Install Node.js + uses: actions/setup-node@v3 + with: + node-version-file: '.nvmrc' + cache: 'npm' + + - name: Install markdown-link-check + run: npm install -g markdown-link-check + + - name: Run markdown-link-check + run: | + find ./docs -path ./docs/internal-developers/testing/releases -prune -o -name "*.md" -print0 | xargs -0 -n1 markdown-link-check -c .github/workflows/check-doc-links-config.json + diff --git a/.github/workflows/php-js-e2e-tests.yml b/.github/workflows/php-js-e2e-tests.yml index 157d3e00244..3000500b053 100644 --- a/.github/workflows/php-js-e2e-tests.yml +++ b/.github/workflows/php-js-e2e-tests.yml @@ -153,6 +153,7 @@ jobs: env: WOOCOMMERCE_BLOCKS_PHASE: 3 run: | + node ./bin/wp-env-with-wp-622.js npm run wp-env start npm run wp-env:config && npx cross-env NODE_CONFIG_DIR=tests/e2e-jest/config wp-scripts test-e2e --config tests/e2e-jest/config/jest.config.js --listTests > ~/.jest-e2e-tests npx cross-env JEST_PUPPETEER_CONFIG=tests/e2e-jest/config/jest-puppeteer.config.js cross-env NODE_CONFIG_DIR=tests/e2e-jest/config wp-scripts test-e2e --config tests/e2e-jest/config/jest.config.js --runInBand --runTestsByPath $( awk 'NR % 5 == ${{ matrix.part }} - 1' < ~/.jest-e2e-tests ) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 5410fe1e3ae..db56521ef34 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -7,13 +7,32 @@ on: jobs: PlaywrightE2ETests: - name: Playwright E2E tests + name: Playwright E2E tests - ${{ matrix.config.name }} timeout-minutes: 60 runs-on: ubuntu-latest + strategy: + matrix: + config: [ + { name: Normal, file: playwright.config.ts, resultPath: test-results }, + { name: SideEffects, file: playwright.side-effects.config.ts, resultPath: test-results-side-effects }, + ] steps: - uses: actions/checkout@v3 + - name: Cache node_modules + id: cache-node-modules + uses: actions/cache@v3 + env: + cache-name: cache-node-modules + with: + path: node_modules + key: ${{ runner.os }}-modified-build-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-modified-build-${{ env.cache-name }}- + ${{ runner.os }}-modified-build- + ${{ runner.os }}-modified- + - name: Setup node version and npm cache uses: actions/setup-node@v3 with: @@ -21,6 +40,7 @@ jobs: cache: 'npm' - name: Install Node dependencies + if: steps.cache-node-modules.outputs.cache-hit != 'true' run: npm ci - name: Build Assets @@ -37,7 +57,8 @@ jobs: with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: ${{ runner.os }}-composer- + restore-keys: | + ${{ runner.os }}-composer- - name: Set up PHP uses: shivammathur/setup-php@v2 @@ -52,18 +73,17 @@ jobs: - name: Install Playwright run: npx playwright install --with-deps - - name: Load wp-env run: npm run env:start - name: Run Playwright tests - run: npm run test:e2e + run: npm run test:e2e -- --config=tests/e2e/${{ matrix.config.file }} - uses: actions/upload-artifact@v3 if: ${{ failure() }} with: - name: playwright-report - path: artifacts/test-results + name: playwright-report-${{ matrix.config.name }} + path: artifacts/${{ matrix.config.resultPath }} if-no-files-found: error # 'warn' or 'ignore' are also available, defaults to `warn` diff --git a/.wordpress-org/banner-1544x500.png b/.wordpress-org/banner-1544x500.png index 0571083ad86..3a83246f164 100644 Binary files a/.wordpress-org/banner-1544x500.png and b/.wordpress-org/banner-1544x500.png differ diff --git a/.wordpress-org/banner-772x250.png b/.wordpress-org/banner-772x250.png index 0ca87162671..b932f21dd77 100644 Binary files a/.wordpress-org/banner-772x250.png and b/.wordpress-org/banner-772x250.png differ diff --git a/.wordpress-org/icon-128x128.png b/.wordpress-org/icon-128x128.png index 26530882c0c..6d5a0f50715 100644 Binary files a/.wordpress-org/icon-128x128.png and b/.wordpress-org/icon-128x128.png differ diff --git a/.wordpress-org/icon-256x256.png b/.wordpress-org/icon-256x256.png index 127951966e6..1ff4a1d6106 100644 Binary files a/.wordpress-org/icon-256x256.png and b/.wordpress-org/icon-256x256.png differ diff --git a/.wp-env.json b/.wp-env.json index c3a5c2d1d6a..d290c174e0d 100644 --- a/.wp-env.json +++ b/.wp-env.json @@ -1,5 +1,5 @@ { - "core": "WordPress/WordPress#6.2.2", + "core": null, "plugins": [ "https://downloads.wordpress.org/plugin/woocommerce.latest-stable.zip", "https://github.com/WP-API/Basic-Auth/archive/master.zip", diff --git a/assets/css/editor.scss b/assets/css/editor.scss index 8ed065aded1..b721f90811c 100644 --- a/assets/css/editor.scss +++ b/assets/css/editor.scss @@ -8,6 +8,10 @@ .wc-block-grid__product { margin: 0 0 $gap-large 0; + + .wc-block-grid__product-onsale { + position: absolute; + } } } diff --git a/assets/css/style.scss b/assets/css/style.scss index c1f78af42f6..f024fe53caf 100644 --- a/assets/css/style.scss +++ b/assets/css/style.scss @@ -139,7 +139,8 @@ } } } -.wc-block-grid__product-onsale { +.wc-block-grid__product-image .wc-block-grid__product-onsale, +.wc-block-grid .wc-block-grid__product-onsale { @include font-size(small); padding: em($gap-smallest) em($gap-small); display: inline-block; diff --git a/assets/js/atomic/blocks/product-elements/button/style.scss b/assets/js/atomic/blocks/product-elements/button/style.scss index 6bcdaaf834d..4df68af32ab 100644 --- a/assets/js/atomic/blocks/product-elements/button/style.scss +++ b/assets/js/atomic/blocks/product-elements/button/style.scss @@ -3,6 +3,7 @@ white-space: normal; display: flex; justify-content: center; + flex-direction: column; align-items: center; gap: $gap-small; diff --git a/assets/js/atomic/blocks/product-elements/product-details/block.json b/assets/js/atomic/blocks/product-elements/product-details/block.json index 2919a826fab..a8e95dd56ac 100644 --- a/assets/js/atomic/blocks/product-elements/product-details/block.json +++ b/assets/js/atomic/blocks/product-elements/product-details/block.json @@ -3,11 +3,14 @@ "version": "1.0.0", "icon": "info", "title": "Product Details", - "description": "Display a product’s description, attributes, and reviews.", + "description": "Display a product's description, attributes, and reviews.", "category": "woocommerce", "keywords": [ "WooCommerce" ], "supports": { - "align": true + "align": true, + "spacing": { + "margin": true + } }, "textdomain": "woo-gutenberg-products-block", "apiVersion": 2, diff --git a/assets/js/blocks/attribute-filter/edit.tsx b/assets/js/blocks/attribute-filter/edit.tsx index 8bcf54e4f75..5cf53e044bf 100644 --- a/assets/js/blocks/attribute-filter/edit.tsx +++ b/assets/js/blocks/attribute-filter/edit.tsx @@ -352,6 +352,7 @@ const Edit = ( { href={ getAdminLink( 'edit.php?post_type=product&page=product_attributes' ) } + target="_top" > { __( 'Add new attribute', 'woo-gutenberg-products-block' ) + ' ' } @@ -361,6 +362,7 @@ const Edit = ( { className="wc-block-attribute-filter__read_more_button" isTertiary href="https://docs.woocommerce.com/document/managing-product-taxonomies/" + target="_blank" > { __( 'Learn more', 'woo-gutenberg-products-block' ) } diff --git a/assets/js/blocks/breadcrumbs/icon.tsx b/assets/js/blocks/breadcrumbs/icon.tsx new file mode 100644 index 00000000000..db33406509a --- /dev/null +++ b/assets/js/blocks/breadcrumbs/icon.tsx @@ -0,0 +1,33 @@ +/** + * External dependencies + */ +import { SVG, Rect } from '@wordpress/primitives'; + +export const queryPaginationIcon = ( + + + + + +); diff --git a/assets/js/blocks/breadcrumbs/index.tsx b/assets/js/blocks/breadcrumbs/index.tsx index ee6d49066b5..2ec9f98b90a 100644 --- a/assets/js/blocks/breadcrumbs/index.tsx +++ b/assets/js/blocks/breadcrumbs/index.tsx @@ -3,13 +3,14 @@ */ import { registerBlockType } from '@wordpress/blocks'; import { isFeaturePluginBuild } from '@woocommerce/block-settings'; -import { Icon, queryPagination } from '@wordpress/icons'; +import { Icon } from '@wordpress/icons'; /** * Internal dependencies */ import metadata from './block.json'; import edit from './edit'; +import { queryPaginationIcon } from './icon'; import './style.scss'; const featurePluginSupport = { @@ -32,7 +33,7 @@ registerBlockType( metadata, { icon: { src: ( ), diff --git a/assets/js/blocks/cart-checkout-shared/payment-methods/express-payment/style.scss b/assets/js/blocks/cart-checkout-shared/payment-methods/express-payment/style.scss index 990809e7fac..9fac0bd0e15 100644 --- a/assets/js/blocks/cart-checkout-shared/payment-methods/express-payment/style.scss +++ b/assets/js/blocks/cart-checkout-shared/payment-methods/express-payment/style.scss @@ -5,18 +5,13 @@ $border-radius: 5px; margin: auto; position: relative; + // nested class to avoid conflict with .editor-styles-wrapper ul .wc-block-components-express-payment__event-buttons { - list-style: none; - display: grid; - grid-template-columns: repeat(auto-fit, minmax(calc(33% - 10px), 1fr)); - grid-gap: 10px; - box-sizing: border-box; width: 100%; padding: 0; margin: 0; overflow: hidden; text-align: center; - > li { margin: 0; width: 100%; @@ -27,18 +22,23 @@ $border-radius: 5px; } } } - - @include breakpoint("<782px") { - .wc-block-components-express-payment__event-buttons { - grid-template-columns: 1fr; - } - } } .wc-block-components-express-payment--checkout { /* stylelint-disable-next-line function-calc-no-unspaced-operator */ margin-top: calc($border-radius * 3); + .wc-block-components-express-payment__event-buttons { + list-style: none; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(calc(33% - 10px), 1fr)); + grid-gap: 10px; + + @include breakpoint("<782px") { + grid-template-columns: 1fr; + } + } + .wc-block-components-express-payment__title-container { display: flex; flex-direction: row; diff --git a/assets/js/blocks/migration-products-to-product-collection/constants.ts b/assets/js/blocks/migration-products-to-product-collection/constants.ts new file mode 100644 index 00000000000..2f68b429ecf --- /dev/null +++ b/assets/js/blocks/migration-products-to-product-collection/constants.ts @@ -0,0 +1,19 @@ +/** + * Internal dependencies + */ +import type { UpgradeNoticeStatus, UpgradeNoticeStatuses } from './types'; + +export const AUTO_REPLACE_PRODUCTS_WITH_PRODUCT_COLLECTION = false; +export const MANUAL_REPLACE_PRODUCTS_WITH_PRODUCT_COLLECTION = false; +export const HOURS_TO_DISPLAY_UPGRADE_NOTICE = 72; +export const UPGRADE_NOTICE_DISPLAY_COUNT_THRESHOLD = 4; +export const MIGRATION_STATUS_LS_KEY = + 'wc-blocks_upgraded-products-to-product-collection'; +// Initial status used in the localStorage +export const INITIAL_STATUS_LS_VALUE: UpgradeNoticeStatuses = 'notseen'; + +export const getInitialStatusLSValue: () => UpgradeNoticeStatus = () => ( { + status: INITIAL_STATUS_LS_VALUE, + time: Date.now(), + displayCount: 0, +} ); diff --git a/assets/js/blocks/shared/scripts/index.tsx b/assets/js/blocks/migration-products-to-product-collection/index.ts similarity index 59% rename from assets/js/blocks/shared/scripts/index.tsx rename to assets/js/blocks/migration-products-to-product-collection/index.ts index b255b01a57d..9067c26005e 100644 --- a/assets/js/blocks/shared/scripts/index.tsx +++ b/assets/js/blocks/migration-products-to-product-collection/index.ts @@ -1,2 +1,5 @@ export * from './migration-from-products-to-product-collection'; export * from './migration-from-product-collection-to-products'; +export * from './migration-utils'; +export * from './constants'; +export * from './types'; diff --git a/assets/js/blocks/shared/scripts/migration-from-product-collection-to-products.tsx b/assets/js/blocks/migration-products-to-product-collection/migration-from-product-collection-to-products.ts similarity index 91% rename from assets/js/blocks/shared/scripts/migration-from-product-collection-to-products.tsx rename to assets/js/blocks/migration-products-to-product-collection/migration-from-product-collection-to-products.ts index 57bca80ad16..18444ae11ee 100644 --- a/assets/js/blocks/shared/scripts/migration-from-product-collection-to-products.tsx +++ b/assets/js/blocks/migration-products-to-product-collection/migration-from-product-collection-to-products.ts @@ -7,17 +7,21 @@ import { select, dispatch } from '@wordpress/data'; /** * Internal dependencies */ +import { disableAutoUpdate } from './migration-from-products-to-product-collection'; import { getProductCollectionBlockClientIds, checkIfBlockCanBeInserted, postTemplateHasSupportForGridView, - type TransformBlock, - type IsBlockType, - type ProductGridLayout, - type ProductGridLayoutTypes, - type PostTemplateLayout, - type PostTemplateLayoutTypes, + setUpgradeStatus, } from './migration-utils'; +import type { + TransformBlock, + IsBlockType, + ProductGridLayout, + ProductGridLayoutTypes, + PostTemplateLayout, + PostTemplateLayoutTypes, +} from './types'; const VARIATION_NAME = 'woocommerce/product-query'; @@ -45,6 +49,10 @@ const mapAttributes = ( attributes ) => { mappedQuery.__woocommerceOnSale = woocommerceOnSale; } + if ( taxQuery ) { + mappedQuery.taxQuery = taxQuery; + } + return { ...restAttributes, namespace: VARIATION_NAME, @@ -207,3 +215,12 @@ export const replaceProductCollectionWithProducts = () => { productCollectionBlockClientIds.map( replaceProductCollectionBlock ); }; + +export const revertMigration = () => { + disableAutoUpdate(); + setUpgradeStatus( { + status: 'reverted', + time: Date.now(), + } ); + replaceProductCollectionWithProducts(); +}; diff --git a/assets/js/blocks/shared/scripts/migration-from-products-to-product-collection.tsx b/assets/js/blocks/migration-products-to-product-collection/migration-from-products-to-product-collection.ts similarity index 82% rename from assets/js/blocks/shared/scripts/migration-from-products-to-product-collection.tsx rename to assets/js/blocks/migration-products-to-product-collection/migration-from-products-to-product-collection.ts index 2a803057442..0de18ef3e08 100644 --- a/assets/js/blocks/shared/scripts/migration-from-products-to-product-collection.tsx +++ b/assets/js/blocks/migration-products-to-product-collection/migration-from-products-to-product-collection.ts @@ -2,22 +2,31 @@ * External dependencies */ import { createBlock, BlockInstance } from '@wordpress/blocks'; -import { select, dispatch } from '@wordpress/data'; +import { select, dispatch, subscribe } from '@wordpress/data'; +import { isWpVersion } from '@woocommerce/settings'; /** * Internal dependencies */ +import { + AUTO_REPLACE_PRODUCTS_WITH_PRODUCT_COLLECTION, + getInitialStatusLSValue, +} from './constants'; import { getProductsBlockClientIds, checkIfBlockCanBeInserted, postTemplateHasSupportForGridView, - type TransformBlock, - type IsBlockType, - type ProductGridLayout, - type ProductGridLayoutTypes, - type PostTemplateLayout, - type PostTemplateLayoutTypes, + getUpgradeStatus, + setUpgradeStatus, } from './migration-utils'; +import type { + TransformBlock, + IsBlockType, + ProductGridLayout, + ProductGridLayoutTypes, + PostTemplateLayout, + PostTemplateLayoutTypes, +} from './types'; const mapAttributes = ( attributes: Record< string, unknown > ) => { const { query, namespace, ...restAttributes } = attributes; @@ -41,7 +50,7 @@ const mapAttributes = ( attributes: Record< string, unknown > ) => { isProductCollectionBlock: true, ...restQuery, }, - displayUpgradeNotice: true, + convertedFromProducts: true, }; }; @@ -194,9 +203,7 @@ const replaceProductsBlocks = ( productsBlockClientIds: string[] ) => { return !! results.length && results.every( ( result ) => !! result ); }; -export const replaceProductsWithProductCollection = ( - unsubscribe?: () => void -) => { +export const replaceProductsWithProductCollection = () => { const queryBlocksCount = select( 'core/block-editor' ).getGlobalBlockCount( 'core/query' ); if ( queryBlocksCount === 0 ) { @@ -211,10 +218,32 @@ export const replaceProductsWithProductCollection = ( return; } - const replaced = replaceProductsBlocks( productsBlockClientIds ); + replaceProductsBlocks( productsBlockClientIds ); +}; + +export const manualUpdate = () => { + setUpgradeStatus( getInitialStatusLSValue() ); + replaceProductsWithProductCollection(); +}; - if ( unsubscribe && replaced ) { - // @todo: unsubscribe on user reverting migration +let unsubscribe: ( () => void ) | undefined; +export const disableAutoUpdate = () => { + if ( unsubscribe ) { unsubscribe(); } }; +export const enableAutoUpdate = () => { + if ( isWpVersion( '6.1', '>=' ) ) { + const { status } = getUpgradeStatus(); + + if ( + AUTO_REPLACE_PRODUCTS_WITH_PRODUCT_COLLECTION && + status !== 'reverted' && + ! unsubscribe + ) { + unsubscribe = subscribe( () => { + replaceProductsWithProductCollection(); + }, 'core/block-editor' ); + } + } +}; diff --git a/assets/js/blocks/shared/scripts/migration-utils.tsx b/assets/js/blocks/migration-products-to-product-collection/migration-utils.ts similarity index 60% rename from assets/js/blocks/shared/scripts/migration-utils.tsx rename to assets/js/blocks/migration-products-to-product-collection/migration-utils.ts index 9748ab82de0..a88a0af297f 100644 --- a/assets/js/blocks/shared/scripts/migration-utils.tsx +++ b/assets/js/blocks/migration-products-to-product-collection/migration-utils.ts @@ -4,33 +4,25 @@ import { getSettingWithCoercion } from '@woocommerce/settings'; import { type BlockInstance } from '@wordpress/blocks'; import { select } from '@wordpress/data'; -import { isBoolean } from '@woocommerce/types'; +import { isBoolean, isNumber } from '@woocommerce/types'; -type GetBlocksClientIds = ( blocks: BlockInstance[] ) => string[]; -export type IsBlockType = ( block: BlockInstance ) => boolean; -export type TransformBlock = ( - block: BlockInstance, - innerBlock: BlockInstance[] -) => BlockInstance; -export type ProductGridLayoutTypes = 'flex' | 'list'; -export type PostTemplateLayoutTypes = 'grid' | 'default'; - -export type ProductGridLayout = { - type: ProductGridLayoutTypes; - columns: number; -}; - -export type PostTemplateLayout = { - type: PostTemplateLayoutTypes; - columnCount: number; -}; +/** + * Internal dependencies + */ +import { MIGRATION_STATUS_LS_KEY, getInitialStatusLSValue } from './constants'; +import type { + IsBlockType, + GetBlocksClientIds, + UpgradeNoticeStatus, +} from './types'; const isProductsBlock: IsBlockType = ( block ) => block.name === 'core/query' && block.attributes.namespace === 'woocommerce/product-query'; -const isProductCollectionBlock: IsBlockType = ( block ) => - block.name === 'woocommerce/product-collection'; +const isConvertedProductCollectionBlock: IsBlockType = ( block ) => + block.name === 'woocommerce/product-collection' && + block.attributes.convertedFromProducts; const getBlockClientIdsByPredicate = ( blocks: BlockInstance[], @@ -53,7 +45,7 @@ const getProductsBlockClientIds: GetBlocksClientIds = ( blocks ) => getBlockClientIdsByPredicate( blocks, isProductsBlock ); const getProductCollectionBlockClientIds: GetBlocksClientIds = ( blocks ) => - getBlockClientIdsByPredicate( blocks, isProductCollectionBlock ); + getBlockClientIdsByPredicate( blocks, isConvertedProductCollectionBlock ); const checkIfBlockCanBeInserted = ( clientId: string, @@ -78,9 +70,35 @@ const postTemplateHasSupportForGridView = getSettingWithCoercion( isBoolean ); +const getUpgradeStatus = (): UpgradeNoticeStatus => { + const status = window.localStorage.getItem( MIGRATION_STATUS_LS_KEY ); + return status ? JSON.parse( status ) : getInitialStatusLSValue(); +}; + +const setUpgradeStatus = ( newStatus: UpgradeNoticeStatus ) => { + window.localStorage.setItem( + MIGRATION_STATUS_LS_KEY, + JSON.stringify( newStatus ) + ); +}; + +const incrementUpgradeStatusDisplayCount = () => { + const status = getUpgradeStatus(); + const displayCount = isNumber( status.displayCount ) + ? status.displayCount + 1 + : 0; + setUpgradeStatus( { + ...status, + displayCount, + } ); +}; + export { getProductsBlockClientIds, getProductCollectionBlockClientIds, checkIfBlockCanBeInserted, postTemplateHasSupportForGridView, + getUpgradeStatus, + setUpgradeStatus, + incrementUpgradeStatusDisplayCount, }; diff --git a/assets/js/blocks/migration-products-to-product-collection/types.ts b/assets/js/blocks/migration-products-to-product-collection/types.ts new file mode 100644 index 00000000000..1fd795a6636 --- /dev/null +++ b/assets/js/blocks/migration-products-to-product-collection/types.ts @@ -0,0 +1,29 @@ +/** + * External dependencies + */ +import { type BlockInstance } from '@wordpress/blocks'; + +export type GetBlocksClientIds = ( blocks: BlockInstance[] ) => string[]; +export type IsBlockType = ( block: BlockInstance ) => boolean; +export type TransformBlock = ( + block: BlockInstance, + innerBlock: BlockInstance[] +) => BlockInstance; +export type ProductGridLayoutTypes = 'flex' | 'list'; +export type PostTemplateLayoutTypes = 'grid' | 'default'; + +export type ProductGridLayout = { + type: ProductGridLayoutTypes; + columns: number; +}; + +export type PostTemplateLayout = { + type: PostTemplateLayoutTypes; + columnCount: number; +}; +export type UpgradeNoticeStatuses = 'notseen' | 'seen' | 'reverted'; +export type UpgradeNoticeStatus = { + status: UpgradeNoticeStatuses; + time: number; + displayCount?: number; +}; diff --git a/assets/js/blocks/price-filter/edit.tsx b/assets/js/blocks/price-filter/edit.tsx index 637cdfd5853..25e3744a295 100644 --- a/assets/js/blocks/price-filter/edit.tsx +++ b/assets/js/blocks/price-filter/edit.tsx @@ -136,6 +136,7 @@ export default function ( { className="wc-block-price-slider__add-product-button" isSecondary href={ getAdminLink( 'post-new.php?post_type=product' ) } + target="_top" > { __( 'Add new product', 'woo-gutenberg-products-block' ) + ' ' } @@ -145,6 +146,7 @@ export default function ( { className="wc-block-price-slider__read_more_button" isTertiary href="https://docs.woocommerce.com/document/managing-products/" + target="_blank" > { __( 'Learn more', 'woo-gutenberg-products-block' ) } diff --git a/assets/js/blocks/product-collection/block.json b/assets/js/blocks/product-collection/block.json index bf82ceb9b10..6c81a9f55a2 100644 --- a/assets/js/blocks/product-collection/block.json +++ b/assets/js/blocks/product-collection/block.json @@ -21,7 +21,7 @@ "displayLayout": { "type": "object" }, - "displayUpgradeNotice": { + "convertedFromProducts": { "type": "boolean", "default": false } diff --git a/assets/js/blocks/product-collection/inspector-controls/index.tsx b/assets/js/blocks/product-collection/inspector-controls/index.tsx index c75141c6113..0f7537fb219 100644 --- a/assets/js/blocks/product-collection/inspector-controls/index.tsx +++ b/assets/js/blocks/product-collection/inspector-controls/index.tsx @@ -1,14 +1,20 @@ /** * External dependencies */ -import type { ElementType } from 'react'; import type { BlockEditProps } from '@wordpress/blocks'; import { InspectorControls, BlockControls } from '@wordpress/block-editor'; import { __ } from '@wordpress/i18n'; -import { useMemo } from '@wordpress/element'; +import { type ElementType, useMemo } from '@wordpress/element'; import { EditorBlock } from '@woocommerce/types'; import { addFilter } from '@wordpress/hooks'; import { ProductCollectionFeedbackPrompt } from '@woocommerce/editor-components/feedback-prompt'; +import { + enableAutoUpdate, + revertMigration, + getUpgradeStatus, + HOURS_TO_DISPLAY_UPGRADE_NOTICE, + UPGRADE_NOTICE_DISPLAY_COUNT_THRESHOLD, +} from '@woocommerce/blocks/migration-products-to-product-collection'; import { // @ts-expect-error Using experimental features // eslint-disable-next-line @wordpress/no-unsafe-wp-apis @@ -34,7 +40,6 @@ import TaxonomyControls from './taxonomy-controls'; import HandPickedProductsControl from './hand-picked-products-control'; import AuthorControl from './author-control'; import DisplayLayoutControl from './display-layout-control'; -import { replaceProductCollectionWithProducts } from '../../shared/scripts'; const ProductCollectionInspectorControls = ( props: BlockEditProps< ProductCollectionAttributes > @@ -106,29 +111,92 @@ const ProductCollectionInspectorControls = ( export default ProductCollectionInspectorControls; -const isProductCollection = ( - block: EditorBlock< ProductCollectionAttributes > -) => block.name === metadata.name; +// Trigger Auto Upgrade of Products only once when module is loaded. +// This triggers subscription but only if: +// - auto update is enabled +// - user haven't reverted the migration +// - no other subscription is in place +enableAutoUpdate(); + +const isProductCollection = ( blockName: string ) => + blockName === metadata.name; + +const lessThanThresholdSinceUpdate = ( t: number ) => { + // Xh * 60m * 60s * 1000ms + const xHoursFromT = t + HOURS_TO_DISPLAY_UPGRADE_NOTICE * 60 * 60 * 1000; + return Date.now() < xHoursFromT; +}; + +const displayedLessThanThreshold = ( displayCount = 0 ) => { + return displayCount <= UPGRADE_NOTICE_DISPLAY_COUNT_THRESHOLD; +}; + +// Upgrade Notice should be displayed only if: +// - block is converted from Products +// - user haven't acknowledged seeing the notice +// - less than X hours since the notice was first displayed +// - notice was displayed less than X times +const shouldDisplayUpgradeNotice = ( props ) => { + const { attributes } = props; + const { convertedFromProducts } = attributes; + const { status, time, displayCount } = getUpgradeStatus(); + + return ( + convertedFromProducts && + status === 'notseen' && + lessThanThresholdSinceUpdate( time ) && + displayedLessThanThreshold( displayCount ) + ); +}; + +// Block should be unmarked as converted from Products if: +// block is converted from Products and either: +// - user acknowledged seeing the notice +// - it's more than X hours since the notice was first displayed +// - notice was displayed more than X times +// We do that to prevent showing the notice again after Products on +// other page were updated or local storage was cleared or user +// switched to another machine/browser etc. +const shouldBeUnmarkedAsConverted = ( props ) => { + const { attributes } = props; + const { convertedFromProducts } = attributes; + const { status, time, displayCount } = getUpgradeStatus(); + + return ( + convertedFromProducts && + ( status === 'seen' || + ! lessThanThresholdSinceUpdate( time ) || + ! displayedLessThanThreshold( displayCount ) ) + ); +}; export const withUpgradeNoticeControls = < T extends EditorBlock< T > >( BlockEdit: ElementType ) => - ( props: EditorBlock< ProductCollectionAttributes > ) => { - return isProductCollection( props ) ? ( + ( props: BlockEditProps< ProductCollectionAttributes > ) => { + if ( ! isProductCollection( props.name ) ) { + return ; + } + + const displayUpgradeNotice = shouldDisplayUpgradeNotice( props ); + const unmarkAsConverted = shouldBeUnmarkedAsConverted( props ); + + if ( unmarkAsConverted ) { + props.setAttributes( { convertedFromProducts: false } ); + } + + return ( <> - - { props.attributes.displayUpgradeNotice && ( - - ) } - + { displayUpgradeNotice && ( + + { + + } + + ) } - ) : ( - ); }; diff --git a/assets/js/blocks/product-collection/inspector-controls/upgrade-notice.tsx b/assets/js/blocks/product-collection/inspector-controls/upgrade-notice.tsx index d9fe5b9607e..df557e6a9f6 100644 --- a/assets/js/blocks/product-collection/inspector-controls/upgrade-notice.tsx +++ b/assets/js/blocks/product-collection/inspector-controls/upgrade-notice.tsx @@ -3,60 +3,81 @@ */ import { __ } from '@wordpress/i18n'; import { Notice, Button } from '@wordpress/components'; -import { BlockEditProps } from '@wordpress/blocks'; -import { createInterpolateElement } from '@wordpress/element'; +import { useLocalStorageState } from '@woocommerce/base-hooks'; +import { + createInterpolateElement, + useEffect, + useRef, +} from '@wordpress/element'; +import { + MIGRATION_STATUS_LS_KEY, + getInitialStatusLSValue, + incrementUpgradeStatusDisplayCount, +} from '@woocommerce/blocks/migration-products-to-product-collection'; -/** - * Internal dependencies - */ -import { ProductCollectionAttributes } from '../types'; - -const UpgradeNotice = ( - props: BlockEditProps< ProductCollectionAttributes > & { - revertMigration: () => void; - } -) => { - const { displayUpgradeNotice } = props.attributes; - const notice = createInterpolateElement( - __( - 'Products (Beta) block was upgraded to , an updated version with new features and simplified settings.', - 'woo-gutenberg-products-block' +const notice = createInterpolateElement( + __( + 'Products (Beta) block was upgraded to , an updated version with new features and simplified settings.', + 'woo-gutenberg-products-block' + ), + { + strongText: ( + + { __( `Product Collection`, 'woo-gutenberg-products-block' ) } + ), - { - strongText: ( - - { __( - `Product Collection`, - 'woo-gutenberg-products-block' - ) } - - ), - } - ); + } +); - const buttonLabel = __( - 'Revert to Products (Beta)', - 'woo-gutenberg-products-block' - ); +const buttonLabel = __( + 'Revert to Products (Beta)', + 'woo-gutenberg-products-block' +); + +type UpgradeNoticeProps = { + revertMigration: () => void; +}; + +const UpgradeNotice = ( { revertMigration }: UpgradeNoticeProps ) => { + const [ upgradeNoticeStatus, setUpgradeNoticeStatus ] = + useLocalStorageState( + MIGRATION_STATUS_LS_KEY, + getInitialStatusLSValue() + ); + + const canCountDisplays = useRef( true ); + const { status } = upgradeNoticeStatus; const handleRemove = () => { - // @todo: this logic needs to be extended to be hidden for all - // Product Collection blocks and whole store - props.setAttributes( { - displayUpgradeNotice: false, + setUpgradeNoticeStatus( { + status: 'seen', + time: Date.now(), } ); }; - const handleClick = () => { - props.revertMigration(); + const handleRevert = () => { + revertMigration(); }; - return displayUpgradeNotice ? ( + // Prevent the possibility to count displays multiple times when the + // block is selected and Inspector Controls are re-rendered multiple times. + useEffect( () => { + const countDisplay = () => { + if ( canCountDisplays.current ) { + incrementUpgradeStatusDisplayCount(); + canCountDisplays.current = false; + } + }; + + return countDisplay; + }, [ canCountDisplays ] ); + + return status === 'notseen' ? ( <>{ notice }

-
diff --git a/assets/js/blocks/product-collection/types.ts b/assets/js/blocks/product-collection/types.ts index 80fe339e80c..5d01793d5c7 100644 --- a/assets/js/blocks/product-collection/types.ts +++ b/assets/js/blocks/product-collection/types.ts @@ -14,7 +14,7 @@ export interface ProductCollectionAttributes { templateSlug: string; displayLayout: ProductCollectionDisplayLayout; tagName: string; - displayUpgradeNotice: boolean; + convertedFromProducts: boolean; } export interface ProductCollectionDisplayLayout { diff --git a/assets/js/blocks/product-gallery/icon.tsx b/assets/js/blocks/product-gallery/icon.tsx index 9fff759ec0d..a5587e33b3f 100644 --- a/assets/js/blocks/product-gallery/icon.tsx +++ b/assets/js/blocks/product-gallery/icon.tsx @@ -1,35 +1,34 @@ const Icon = () => ( - - + - - - - - - ); diff --git a/assets/js/blocks/product-query/constants.ts b/assets/js/blocks/product-query/constants.ts index e017460906e..a5d0fc5c8d4 100644 --- a/assets/js/blocks/product-query/constants.ts +++ b/assets/js/blocks/product-query/constants.ts @@ -13,9 +13,6 @@ import { VARIATION_NAME as PRODUCT_TITLE_ID } from './variations/elements/produc import { VARIATION_NAME as PRODUCT_TEMPLATE_ID } from './variations/elements/product-template'; import { ImageSizing } from '../../atomic/blocks/product-elements/image/types'; -export const AUTO_REPLACE_PRODUCTS_WITH_PRODUCT_COLLECTION = false; -export const MANUAL_REPLACE_PRODUCTS_WITH_PRODUCT_COLLECTION = false; - export const PRODUCT_QUERY_VARIATION_NAME = 'woocommerce/product-query'; export const EDIT_ATTRIBUTES_URL = diff --git a/assets/js/blocks/product-query/inspector-controls.tsx b/assets/js/blocks/product-query/inspector-controls.tsx index 05ea211b4f7..0ae16dd1287 100644 --- a/assets/js/blocks/product-query/inspector-controls.tsx +++ b/assets/js/blocks/product-query/inspector-controls.tsx @@ -1,15 +1,19 @@ /** * External dependencies */ -import type { ElementType } from 'react'; import { __ } from '@wordpress/i18n'; import { InspectorControls } from '@wordpress/block-editor'; -import { useSelect, subscribe } from '@wordpress/data'; +import { useSelect } from '@wordpress/data'; import { addFilter } from '@wordpress/hooks'; +import { type ElementType } from '@wordpress/element'; import { ProductQueryFeedbackPrompt } from '@woocommerce/editor-components/feedback-prompt'; import { EditorBlock, isNumber } from '@woocommerce/types'; import { usePrevious } from '@woocommerce/base-hooks'; -import { isWpVersion, getSettingWithCoercion } from '@woocommerce/settings'; +import { + manualUpdate, + MANUAL_REPLACE_PRODUCTS_WITH_PRODUCT_COLLECTION, +} from '@woocommerce/blocks/migration-products-to-product-collection'; +import { getSettingWithCoercion } from '@woocommerce/settings'; import { ProductQueryBlockQuery } from '@woocommerce/blocks/product-query/types'; import { FormTokenField, @@ -39,14 +43,11 @@ import { QUERY_DEFAULT_ATTRIBUTES, QUERY_LOOP_ID, STOCK_STATUS_OPTIONS, - AUTO_REPLACE_PRODUCTS_WITH_PRODUCT_COLLECTION, - MANUAL_REPLACE_PRODUCTS_WITH_PRODUCT_COLLECTION, } from './constants'; import { AttributesFilter } from './inspector-controls/attributes-filter'; import { PopularPresets } from './inspector-controls/popular-presets'; import { ProductSelector } from './inspector-controls/product-selector'; import { UpgradeNotice } from './inspector-controls/upgrade-notice'; -import { replaceProductsWithProductCollection } from '../shared/scripts'; import './editor.scss'; @@ -237,9 +238,7 @@ const ProductQueryControls = ( props: ProductQueryBlock ) => { <> { MANUAL_REPLACE_PRODUCTS_WITH_PRODUCT_COLLECTION && ( - + ) } { allowedControls?.includes( 'presets' ) && ( @@ -289,16 +288,3 @@ export const withProductQueryControls = }; addFilter( 'editor.BlockEdit', QUERY_LOOP_ID, withProductQueryControls ); - -if ( isWpVersion( '6.1', '>=' ) ) { - let unsubscribe: ( () => void ) | undefined; - if ( AUTO_REPLACE_PRODUCTS_WITH_PRODUCT_COLLECTION && ! unsubscribe ) { - unsubscribe = subscribe( () => { - replaceProductsWithProductCollection( () => { - if ( unsubscribe ) { - unsubscribe(); - } - } ); - }, 'core/block-editor' ); - } -} diff --git a/assets/js/blocks/product-tag/block.tsx b/assets/js/blocks/product-tag/block.tsx index 6dd138382d5..fb240d1382a 100644 --- a/assets/js/blocks/product-tag/block.tsx +++ b/assets/js/blocks/product-tag/block.tsx @@ -85,7 +85,6 @@ const ProductsByTagBlock = ( { ) } initialOpen={ ! attributes.tags.length && ! isEditing } > - { /* @ts-expect-error ProductTagControl is yet to be converted to tsx*/ } { @@ -203,16 +202,21 @@ const ProductsByTagBlock = ( { 'woo-gutenberg-products-block' ) }
- { /* @ts-expect-error ProductTagControl is yet to be converted to tsx*/ } { const ids = value.map( ( { id } ) => id ); - setChangedAttributes( { tags: ids } ); + setChangedAttributes( { + ...changedAttributes, + tags: ids, + } ); } } operator={ currentAttributes.tagOperator } onOperatorChange={ ( value = 'any' ) => - setChangedAttributes( { tagOperator: value } ) + setChangedAttributes( { + ...changedAttributes, + tagOperator: value, + } ) } /> diff --git a/assets/js/editor-components/product-tag-control/index.js b/assets/js/editor-components/product-tag-control/index.js deleted file mode 100644 index 4c00c169187..00000000000 --- a/assets/js/editor-components/product-tag-control/index.js +++ /dev/null @@ -1,213 +0,0 @@ -/** - * External dependencies - */ -import { __, _n, sprintf } from '@wordpress/i18n'; -import { Component } from '@wordpress/element'; -import { debounce } from '@woocommerce/base-utils'; -import PropTypes from 'prop-types'; -import { - SearchListControl, - SearchListItem, -} from '@woocommerce/editor-components/search-list-control'; -import { SelectControl } from '@wordpress/components'; -import { getSetting } from '@woocommerce/settings'; -import classNames from 'classnames'; - -/** - * Internal dependencies - */ -import { getProductTags } from '../utils'; -import './style.scss'; - -/** - * Component to handle searching and selecting product tags. - */ -class ProductTagControl extends Component { - constructor() { - super( ...arguments ); - this.state = { - list: [], - loading: true, - }; - this.renderItem = this.renderItem.bind( this ); - this.debouncedOnSearch = debounce( this.onSearch.bind( this ), 400 ); - } - - componentDidMount() { - const { selected } = this.props; - - getProductTags( { selected } ) - .then( ( list ) => { - this.setState( { list, loading: false } ); - } ) - .catch( () => { - this.setState( { list: [], loading: false } ); - } ); - } - - onSearch( search ) { - const { selected } = this.props; - this.setState( { loading: true } ); - - getProductTags( { selected, search } ) - .then( ( list ) => { - this.setState( { list, loading: false } ); - } ) - .catch( () => { - this.setState( { list: [], loading: false } ); - } ); - } - - renderItem( args ) { - const { item, search, depth = 0 } = args; - - const accessibleName = ! item.breadcrumbs.length - ? item.name - : `${ item.breadcrumbs.join( ', ' ) }, ${ item.name }`; - - return ( - 0, - 'is-skip-level': depth === 0 && item.parent !== 0, - } - ) } - { ...args } - aria-label={ sprintf( - /* translators: %1$d is the count of products, %2$s is the name of the tag. */ - _n( - '%1$d product tagged as %2$s', - '%1$d products tagged as %2$s', - item.count, - 'woo-gutenberg-products-block' - ), - item.count, - accessibleName - ) } - /> - ); - } - - render() { - const { list, loading } = this.state; - const { isCompact, onChange, onOperatorChange, operator, selected } = - this.props; - - const messages = { - clear: __( - 'Clear all product tags', - 'woo-gutenberg-products-block' - ), - list: __( 'Product Tags', 'woo-gutenberg-products-block' ), - noItems: __( - 'You have not set up any product tags on your store.', - 'woo-gutenberg-products-block' - ), - search: __( - 'Search for product tags', - 'woo-gutenberg-products-block' - ), - selected: ( n ) => - sprintf( - /* translators: %d is the count of selected tags. */ - _n( - '%d tag selected', - '%d tags selected', - n, - 'woo-gutenberg-products-block' - ), - n - ), - updated: __( - 'Tag search results updated.', - 'woo-gutenberg-products-block' - ), - }; - - const limitTags = getSetting( 'limitTags', false ); - - return ( - <> - - list.find( ( listItem ) => listItem.id === id ) - ) - .filter( Boolean ) } - onChange={ onChange } - onSearch={ limitTags ? this.debouncedOnSearch : null } - renderItem={ this.renderItem } - messages={ messages } - isCompact={ isCompact } - isHierarchical - /> - { !! onOperatorChange && ( - - ) } - - ); - } -} - -ProductTagControl.propTypes = { - /** - * Callback to update the selected product categories. - */ - onChange: PropTypes.func.isRequired, - /** - * Callback to update the category operator. If not passed in, setting is not used. - */ - onOperatorChange: PropTypes.func, - /** - * Setting for whether products should match all or any selected categories. - */ - operator: PropTypes.oneOf( [ 'all', 'any' ] ), - /** - * The list of currently selected tags. - */ - selected: PropTypes.array.isRequired, - isCompact: PropTypes.bool, -}; - -ProductTagControl.defaultProps = { - isCompact: false, - operator: 'any', -}; - -export default ProductTagControl; diff --git a/assets/js/editor-components/product-tag-control/index.tsx b/assets/js/editor-components/product-tag-control/index.tsx new file mode 100644 index 00000000000..9339dece00e --- /dev/null +++ b/assets/js/editor-components/product-tag-control/index.tsx @@ -0,0 +1,142 @@ +/** + * External dependencies + */ +import { __, _n, sprintf } from '@wordpress/i18n'; +import { useState, useEffect, useCallback, useMemo } from '@wordpress/element'; +import { SearchListControl } from '@woocommerce/editor-components/search-list-control'; +import { SelectControl } from '@wordpress/components'; +import { getSetting } from '@woocommerce/settings'; +import { useDebouncedCallback } from 'use-debounce'; + +/** + * Internal dependencies + */ +import type { SearchListItem as SearchListItemProps } from '../search-list-control/types'; +import ProductTagItem from './product-tag-item'; +import type { ProductTagControlProps } from './types'; +import { getProductTags } from '../utils'; +import './style.scss'; + +/** + * Component to handle searching and selecting product tags. + */ +const ProductTagControl = ( { + isCompact = false, + onChange, + onOperatorChange, + operator = 'any', + selected, +}: ProductTagControlProps ): JSX.Element => { + const [ list, setList ] = useState< SearchListItemProps[] >( [] ); + const [ loading, setLoading ] = useState( true ); + const [ isMounted, setIsMounted ] = useState( false ); + const limitTags = getSetting( 'limitTags', false ); + + const selectedTags = useMemo< SearchListItemProps[] >( () => { + return list.filter( ( item ) => selected.includes( item.id ) ); + }, [ list, selected ] ); + + const onSearch = useCallback( + ( search: string ) => { + setLoading( true ); + getProductTags( { selected, search } ) + .then( ( newList ) => { + setList( newList ); + setLoading( false ); + } ) + .catch( () => { + setLoading( false ); + } ); + }, + [ selected ] + ); + + // Load on mount. + useEffect( () => { + if ( isMounted ) { + return; + } + onSearch( '' ); + setIsMounted( true ); + }, [ onSearch, isMounted ] ); + + const debouncedOnSearch = useDebouncedCallback( onSearch, 400 ); + + const messages = { + clear: __( 'Clear all product tags', 'woo-gutenberg-products-block' ), + list: __( 'Product Tags', 'woo-gutenberg-products-block' ), + noItems: __( + 'You have not set up any product tags on your store.', + 'woo-gutenberg-products-block' + ), + search: __( 'Search for product tags', 'woo-gutenberg-products-block' ), + selected: ( n: number ) => + sprintf( + /* translators: %d is the count of selected tags. */ + _n( + '%d tag selected', + '%d tags selected', + n, + 'woo-gutenberg-products-block' + ), + n + ), + updated: __( + 'Tag search results updated.', + 'woo-gutenberg-products-block' + ), + }; + + return ( + <> + + { !! onOperatorChange && ( + + ) } + + ); +}; + +export default ProductTagControl; diff --git a/assets/js/editor-components/product-tag-control/product-tag-item.tsx b/assets/js/editor-components/product-tag-control/product-tag-item.tsx new file mode 100644 index 00000000000..db656cbcd1e --- /dev/null +++ b/assets/js/editor-components/product-tag-control/product-tag-item.tsx @@ -0,0 +1,52 @@ +/** + * External dependencies + */ +import { _n, sprintf } from '@wordpress/i18n'; +import { SearchListItem } from '@woocommerce/editor-components/search-list-control'; +import classNames from 'classnames'; + +/** + * Internal dependencies + */ +import type { renderItemArgs } from '../search-list-control/types'; + +export const ProductTagItem = ( { + item, + search, + depth = 0, + ...rest +}: renderItemArgs ): JSX.Element => { + const accessibleName = ! item.breadcrumbs.length + ? item.name + : `${ item.breadcrumbs.join( ', ' ) }, ${ item.name }`; + + return ( + 0, + 'is-skip-level': depth === 0 && item.parent !== 0, + } + ) } + item={ item } + search={ search } + depth={ depth } + { ...rest } + ariaLabel={ sprintf( + /* translators: %1$d is the count of products, %2$s is the name of the tag. */ + _n( + '%1$d product tagged as %2$s', + '%1$d products tagged as %2$s', + item.count, + 'woo-gutenberg-products-block' + ), + item.count, + accessibleName + ) } + /> + ); +}; + +export default ProductTagItem; diff --git a/assets/js/editor-components/product-tag-control/types.ts b/assets/js/editor-components/product-tag-control/types.ts new file mode 100644 index 00000000000..3004048bcd4 --- /dev/null +++ b/assets/js/editor-components/product-tag-control/types.ts @@ -0,0 +1,13 @@ +/** + * Internal dependencies + */ +import type { SearchListItem as SearchListItemProps } from '../search-list-control/types'; + +export type ProductTagControlProps = { + isCompact?: boolean; + onChange: ( selected: SearchListItemProps[] ) => void; + onOperatorChange?: ( operator: string ) => void; + operator?: string; + // Selected tag ids. + selected: ( number | string )[]; +}; diff --git a/assets/js/editor-components/search-list-control/types.ts b/assets/js/editor-components/search-list-control/types.ts index b7852a251ac..043a1848c07 100644 --- a/assets/js/editor-components/search-list-control/types.ts +++ b/assets/js/editor-components/search-list-control/types.ts @@ -90,6 +90,8 @@ export interface renderItemArgs extends ItemProps { * If not provided, a default name will be generated using the controlId. */ name?: string; + // Aria label for the input. If not provided, a default label will be generated using the item name. + ariaLabel?: string; } export interface SearchListControlProps { @@ -110,7 +112,7 @@ export interface SearchListControlProps { // Callback fired when selected items change, whether added, cleared, or removed. Passed an array of item objects (as passed in via props.list). onChange: ( search: SearchListItem[] ) => void; // Callback fired when the search field is used. - onSearch?: ( search: string ) => void; + onSearch?: ( ( search: string ) => void ) | undefined; // Callback to render each item in the selection list, allows any custom object-type rendering. renderItem?: ( args: renderItemArgs ) => JSX.Element; // The list of currently selected items. diff --git a/bin/hook-docs/data/actions.json b/bin/hook-docs/data/actions.json index b317628eb7f..9c6c1650a80 100644 --- a/bin/hook-docs/data/actions.json +++ b/bin/hook-docs/data/actions.json @@ -603,46 +603,6 @@ }, "args": 3 }, - { - "name": "woocommerce_rest_checkout_process_payment_with_context", - "file": "StoreApi/Routes/V1/Checkout.php", - "type": "action_reference", - "doc": { - "description": "Process payment with context.", - "long_description": "", - "tags": [ - { - "name": "hook", - "content": "woocommerce_rest_checkout_process_payment_with_context" - }, - { - "name": "throws", - "content": "If there is an error taking payment, an \\Exception object can be thrown with an error message.", - "types": [ - "\\Exception" - ] - }, - { - "name": "param", - "content": "Holds context for the payment, including order ID and payment method.", - "types": [ - "\\Automattic\\WooCommerce\\StoreApi\\Payments\\PaymentContext" - ], - "variable": "$context" - }, - { - "name": "param", - "content": "Result object for the transaction.", - "types": [ - "\\Automattic\\WooCommerce\\StoreApi\\Payments\\PaymentResult" - ], - "variable": "$payment_result" - } - ], - "long_description_html": "" - }, - "args": 1 - }, { "name": "woocommerce_shop_loop", "file": "BlockTypes/ClassicTemplate.php", @@ -813,6 +773,40 @@ }, "args": 2 }, + { + "name": "woocommerce_store_api_checkout_order_processed", + "file": "StoreApi/Routes/V1/CheckoutOrder.php", + "type": "action", + "doc": { + "description": "Fires before an order is processed by the Checkout Block/Store API.", + "long_description": "This hook informs extensions that $order has completed processing and is ready for payment.\n This is similar to existing core hook woocommerce_checkout_order_processed. We're using a new action: - To keep the interface focused (only pass $order, not passing request data). - This also explicitly indicates these orders are from checkout block/StoreAPI.", + "tags": [ + { + "name": "since", + "content": "7.2.0" + }, + { + "name": "see", + "content": "", + "refers": "https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3238" + }, + { + "name": "example", + "content": "docs/examples/checkout-order-processed.md" + }, + { + "name": "param", + "content": "Order object.", + "types": [ + "\\WC_Order" + ], + "variable": "$order" + } + ], + "long_description_html": "

This hook informs extensions that $order has completed processing and is ready for payment.

This is similar to existing core hook woocommerce_checkout_order_processed. We're using a new action:

  • To keep the interface focused (only pass $order, not passing request data).
  • This also explicitly indicates these orders are from checkout block/StoreAPI.
" + }, + "args": 1 + }, { "name": "woocommerce_store_api_checkout_order_processed", "file": "StoreApi/Routes/V1/Checkout.php", @@ -849,7 +843,7 @@ }, { "name": "woocommerce_store_api_checkout_update_customer_from_request", - "file": "StoreApi/Routes/V1/Checkout.php", + "file": "StoreApi/Routes/V1/CheckoutOrder.php", "type": "action", "doc": { "description": "Fires when the Checkout Block/Store API updates a customer from the API request data.", @@ -881,24 +875,24 @@ "args": 2 }, { - "name": "woocommerce_store_api_checkout_update_order_from_request", + "name": "woocommerce_store_api_checkout_update_customer_from_request", "file": "StoreApi/Routes/V1/Checkout.php", "type": "action", "doc": { - "description": "Fires when the Checkout Block/Store API updates an order's from the API request data.", - "long_description": "This hook gives extensions the chance to update orders based on the data in the request. This can be used in conjunction with the ExtendSchema class to post custom data and then process it.", + "description": "Fires when the Checkout Block/Store API updates a customer from the API request data.", + "long_description": "", "tags": [ { "name": "since", - "content": "7.2.0" + "content": "8.2.0" }, { "name": "param", - "content": "Order object.", + "content": "Customer object.", "types": [ - "\\WC_Order" + "\\WC_Customer" ], - "variable": "$order" + "variable": "$customer" }, { "name": "param", @@ -909,7 +903,7 @@ "variable": "$request" } ], - "long_description_html": "

This hook gives extensions the chance to update orders based on the data in the request. This can be used in conjunction with the ExtendSchema class to post custom data and then process it.

" + "long_description_html": "" }, "args": 2 }, diff --git a/bin/hook-docs/data/filters.json b/bin/hook-docs/data/filters.json index b9edf39f0a8..e8a110dd56c 100644 --- a/bin/hook-docs/data/filters.json +++ b/bin/hook-docs/data/filters.json @@ -120,6 +120,30 @@ }, "args": 1 }, + { + "name": "loop_shop_per_page", + "file": "BlockTypes/ProductQuery.php", + "type": "filter", + "doc": { + "description": "", + "long_description": "", + "tags": [], + "long_description_html": "" + }, + "args": 1 + }, + { + "name": "loop_shop_per_page", + "file": "BlockTypes/ProductCollection.php", + "type": "filter", + "doc": { + "description": "", + "long_description": "", + "tags": [], + "long_description_html": "" + }, + "args": 1 + }, { "name": "wc_session_expiration", "file": "StoreApi/Routes/V1/AbstractCartRoute.php", @@ -249,6 +273,39 @@ }, "args": 4 }, + { + "name": "woocommerce_add_to_cart_quantity", + "file": "BlockTypes/ProductButton.php", + "type": "filter", + "doc": { + "description": "Filters the change the quantity to add to cart.", + "long_description": "", + "tags": [ + { + "name": "since", + "content": "10.9.0" + }, + { + "name": "param", + "content": "The default quantity.", + "types": [ + "\\Automattic\\WooCommerce\\Blocks\\BlockTypes\\number" + ], + "variable": "$default_quantity" + }, + { + "name": "param", + "content": "The product id.", + "types": [ + "\\Automattic\\WooCommerce\\Blocks\\BlockTypes\\number" + ], + "variable": "$product_id" + } + ], + "long_description_html": "" + }, + "args": 2 + }, { "name": "woocommerce_add_to_cart_sold_individually_quantity", "file": "StoreApi/Utilities/CartController.php", @@ -734,6 +791,47 @@ }, "args": 1 }, + { + "name": "woocommerce_cart_item_permalink", + "file": "StoreApi/Schemas/V1/CartItemSchema.php", + "type": "filter", + "doc": { + "description": "Filter the product permalink.", + "long_description": "This is a hook taken from the legacy cart/mini-cart templates that allows the permalink to be changed for a product. This is specific to the cart endpoint.", + "tags": [ + { + "name": "since", + "content": "9.9.0" + }, + { + "name": "param", + "content": "Product permalink.", + "types": [ + "string" + ], + "variable": "$product_permalink" + }, + { + "name": "param", + "content": "Cart item array.", + "types": [ + "array" + ], + "variable": "$cart_item" + }, + { + "name": "param", + "content": "Cart item key.", + "types": [ + "string" + ], + "variable": "$cart_item_key" + } + ], + "long_description_html": "

This is a hook taken from the legacy cart/mini-cart templates that allows the permalink to be changed for a product. This is specific to the cart endpoint.

" + }, + "args": 3 + }, { "name": "woocommerce_disable_compatibility_layer", "file": "Templates/AbstractTemplateCompatibility.php", @@ -933,6 +1031,88 @@ }, "args": 1 }, + { + "name": "woocommerce_pay_order_product_has_enough_stock", + "file": "StoreApi/Utilities/OrderController.php", + "type": "filter", + "doc": { + "description": "Filters whether or not the product has enough stock.", + "long_description": "", + "tags": [ + { + "name": "param", + "content": "True if has enough stock.", + "types": [ + "boolean" + ], + "variable": "" + }, + { + "name": "param", + "content": "Product.", + "types": [ + "\\WC_Product" + ], + "variable": "$product" + }, + { + "name": "param", + "content": "Order.", + "types": [ + "\\WC_Order" + ], + "variable": "$order" + }, + { + "name": "since", + "content": "9.8.0-dev" + } + ], + "long_description_html": "" + }, + "args": 3 + }, + { + "name": "woocommerce_pay_order_product_in_stock", + "file": "StoreApi/Utilities/OrderController.php", + "type": "filter", + "doc": { + "description": "Filters whether or not the product is in stock for this pay for order.", + "long_description": "", + "tags": [ + { + "name": "param", + "content": "True if in stock.", + "types": [ + "boolean" + ], + "variable": "" + }, + { + "name": "param", + "content": "Product.", + "types": [ + "\\WC_Product" + ], + "variable": "$product" + }, + { + "name": "param", + "content": "Order.", + "types": [ + "\\WC_Order" + ], + "variable": "$order" + }, + { + "name": "since", + "content": "9.8.0-dev" + } + ], + "long_description_html": "" + }, + "args": 3 + }, { "name": "woocommerce_registration_errors", "file": "StoreApi/Routes/V1/Checkout.php", @@ -1102,6 +1282,39 @@ }, "args": 1 }, + { + "name": "woocommerce_single_product_image_thumbnail_html", + "file": "BlockTypes/ProductGalleryThumbnails.php", + "type": "filter", + "doc": { + "description": "Filter the HTML markup for a single product image thumbnail in the gallery.", + "long_description": "", + "tags": [ + { + "name": "param", + "content": "The HTML markup for the thumbnail.", + "types": [ + "string" + ], + "variable": "$thumbnail_html" + }, + { + "name": "param", + "content": "The attachment ID of the thumbnail.", + "types": [ + "int" + ], + "variable": "$attachment_id" + }, + { + "name": "since", + "content": "7.9.0" + } + ], + "long_description_html": "" + }, + "args": 2 + }, { "name": "woocommerce_store_api_add_to_cart_data", "file": "StoreApi/Routes/V1/CartAddItem.php", @@ -1286,66 +1499,6 @@ "long_description_html": "" }, "args": 1 - }, - { - "name": "woocommerce_variation_option_name", - "file": "StoreApi/Schemas/V1/CartItemSchema.php", - "type": "filter", - "doc": { - "description": "Filters the variation option name.", - "long_description": "Filters the variation option name for custom option slugs.", - "tags": [ - { - "name": "since", - "content": "2.5.0" - }, - { - "name": "internal", - "content": "Matches filter name in WooCommerce core." - }, - { - "name": "param", - "content": "The name to display.", - "types": [ - "string" - ], - "variable": "$value" - }, - { - "name": "param", - "content": "Unused because this is not a variation taxonomy.", - "types": [ - "null" - ], - "variable": "$unused" - }, - { - "name": "param", - "content": "Taxonomy or product attribute name.", - "types": [ - "string" - ], - "variable": "$taxonomy" - }, - { - "name": "param", - "content": "Product data.", - "types": [ - "\\WC_Product" - ], - "variable": "$product" - }, - { - "name": "return", - "content": "", - "types": [ - "string" - ] - } - ], - "long_description_html": "

Filters the variation option name for custom option slugs.

" - }, - "args": 4 } ] } \ No newline at end of file diff --git a/bin/hook-docs/utilities/generate-toc.js b/bin/hook-docs/utilities/generate-toc.js index 6ec1e80aec5..ae96ff12a85 100644 --- a/bin/hook-docs/utilities/generate-toc.js +++ b/bin/hook-docs/utilities/generate-toc.js @@ -12,11 +12,14 @@ const generateToc = ( hooks ) => { const heading = isDeprecated ? `~~${ hookName }~~` : `${ hookName }`; - let anchor = heading .trim() .toLowerCase() + .replace( /\(\)/g, '' ) + .replace( /\{\$(.*?)->(.*?)}/g, '$1-$2' ) + .replace( /\{\$(.*?)}/g, '$1' ) .replace( /[^\w\- ]+/g, ' ' ) + .trim() .replace( /\s+/g, '-' ) .replace( /\-+$/, '' ); if ( usedHeaders.indexOf( anchor ) !== -1 ) { @@ -28,7 +31,6 @@ const generateToc = ( hooks ) => { anchor = anchor + '-' + i; } usedHeaders.push( anchor ); - return `[${ hook.name }](#${ anchor })`; } ), }, diff --git a/bin/webpack-configs.js b/bin/webpack-configs.js index 3dd7a25347d..84de696091a 100644 --- a/bin/webpack-configs.js +++ b/bin/webpack-configs.js @@ -733,7 +733,7 @@ const getSiteEditorConfig = ( options = {} ) => { * @param {Object} options Build options. */ const getStylingConfig = ( options = {} ) => { - let { fileSuffix } = options; + let { fileSuffix, isClassicThemeConfig } = options; const { alias, resolvePlugins = [] } = options; fileSuffix = fileSuffix ? `-${ fileSuffix }` : ''; const resolve = alias @@ -775,11 +775,58 @@ const getStylingConfig = ( options = {} ) => { chunks: 'all', priority: 10, }, + ...( isClassicThemeConfig && { + vendorsStyle: { + test: /[\/\\]node_modules[\/\\].*?style\.s?css$/, + name: 'wc-blocks-vendors-style', + chunks: 'all', + priority: 7, + }, + blocksStyle: { + // Capture all stylesheets with name `style` or name that starts with underscore (abstracts). + test: /(style|_.*)\.scss$/, + name: 'wc-all-blocks-style', + chunks: 'all', + priority: 5, + }, + } ), }, }, }, module: { rules: [ + { + test: /[\/\\]node_modules[\/\\].*?style\.s?css$/, + use: [ + MiniCssExtractPlugin.loader, + { loader: 'css-loader', options: { importLoaders: 1 } }, + 'postcss-loader', + { + loader: 'sass-loader', + options: { + sassOptions: { + includePaths: [ 'node_modules' ], + }, + additionalData: ( content ) => { + const styleImports = [ + 'colors', + 'breakpoints', + 'variables', + 'mixins', + 'animations', + 'z-index', + ] + .map( + ( imported ) => + `@import "~@wordpress/base-styles/${ imported }";` + ) + .join( ' ' ); + return styleImports + content; + }, + }, + }, + ], + }, { test: /\.(j|t)sx?$/, use: { @@ -800,6 +847,7 @@ const getStylingConfig = ( options = {} ) => { }, { test: /\.s?css$/, + exclude: /node_modules/, use: [ MiniCssExtractPlugin.loader, 'css-loader', diff --git a/bin/webpack-entries.js b/bin/webpack-entries.js index 0d92167f615..ac2499cd932 100644 --- a/bin/webpack-entries.js +++ b/bin/webpack-entries.js @@ -118,6 +118,16 @@ const getBlockEntries = ( relativePath ) => { const entries = { styling: { + // @wordpress/components styles + 'custom-select-control-style': + './node_modules/wordpress-components/src/custom-select-control/style.scss', + 'snackbar-notice-style': + './node_modules/wordpress-components/src/snackbar/style.scss', + 'combobox-control-style': + './node_modules/wordpress-components/src/combobox-control/style.scss', + 'form-token-field-style': + './node_modules/wordpress-components/src/form-token-field/style.scss', + // Packages styles 'packages-style': glob.sync( './packages/**/index.js' ), diff --git a/bin/wp-env-with-wp-622.js b/bin/wp-env-with-wp-622.js new file mode 100755 index 00000000000..b27fbfcb2e9 --- /dev/null +++ b/bin/wp-env-with-wp-622.js @@ -0,0 +1,19 @@ +const fs = require( 'fs' ); +const path = require( 'path' ); + +const wpEnvRaw = fs.readFileSync( + path.join( __dirname, '..', '.wp-env.json' ) +); +const wpEnv = JSON.parse( wpEnvRaw ); + +// Pin the core version to 6.2.2 for Jest E2E test so we can keep the test +// passing when new WordPress versions are released. We do this because we're +// moving to Playwright and will abandon the Jest E2E tests once the migration +// is complete. +wpEnv.core = 'WordPress/WordPress#6.2.2'; + +// We write the new file to .wp-env.override.json (https://developer.wordpress.org/block-editor/reference-guides/packages/packages-env/#wp-env-override-json) +fs.writeFileSync( + path.join( __dirname, '..', '.wp-env.override.json' ), + JSON.stringify( wpEnv ) +); diff --git a/composer.json b/composer.json index d2c6654610e..1f30a59f997 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "description": "WooCommerce blocks for the Gutenberg editor.", "homepage": "https://woocommerce.com/", "type": "wordpress-plugin", - "version": "10.9.0-dev", + "version": "11.0.0-dev", "keywords": [ "gutenberg", "woocommerce", diff --git a/docs/README.md b/docs/README.md index 5f6529f0859..ea940e2e8ef 100644 --- a/docs/README.md +++ b/docs/README.md @@ -138,6 +138,7 @@ The following posts from [developer.woocommerce.com](https://developer.woocommer The following tutorials from [developer.woocommerce.com](https://developer.woocommerce.com/category/tutorials/) help you with extending the WooCommerce Blocks plugin. +- [📺 Tutorial: Extending the WooCommerce Checkout Block](https://developer.woocommerce.com/2023/08/07/extending-the-woocommerce-checkout-block-to-add-custom-shipping-options/) - [Hiding Shipping and Payment Options in the Cart and Checkout Blocks](https://developer.woocommerce.com/2022/05/20/hiding-shipping-and-payment-options-in-the-cart-and-checkout-blocks/) - [Integrating your Payment Method with Cart and Checkout Blocks](https://developer.woocommerce.com/2021/03/15/integrating-your-payment-method-with-cart-and-checkout-blocks/) - [Exposing Payment Options in the Checkout Block](https://developer.woocommerce.com/2022/07/07/exposing-payment-options-in-the-checkout-block/) @@ -151,3 +152,4 @@ The following tutorials from [developer.woocommerce.com](https://developer.wooco 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/README.md) + diff --git a/docs/contributors/README.md b/docs/contributors/README.md index 54615cf240b..a43293e5131 100644 --- a/docs/contributors/README.md +++ b/docs/contributors/README.md @@ -36,6 +36,8 @@ Our [JavaScript Build System](javascript-build-system.md) guide offers a detaile Last but not least, to get an insight into how CSS is built, refer to the [CSS Build System](css-build-system.md) guide. A firm grasp of this will ensure your CSS files meet the standards and quality expected. + + --- [We're hiring!](https://woocommerce.com/careers/) Come work with us! @@ -43,3 +45,4 @@ Last but not least, to get an insight into how CSS is built, refer to the [CSS B 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/contributors/README.md) + diff --git a/docs/contributors/block-assets.md b/docs/contributors/block-assets.md index 63f2a916cc3..d60663d4db0 100644 --- a/docs/contributors/block-assets.md +++ b/docs/contributors/block-assets.md @@ -95,6 +95,7 @@ wc.wcSettings.getSetting( 'key' ); [We're hiring!](https://woocommerce.com/careers/) Come work with us! -🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/contributors/documentation-guidelines.md) +🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/contributors/block-assets.md) + diff --git a/docs/contributors/coding-guidelines.md b/docs/contributors/coding-guidelines.md index 70a095e6a24..099fbacfdad 100644 --- a/docs/contributors/coding-guidelines.md +++ b/docs/contributors/coding-guidelines.md @@ -179,6 +179,7 @@ Notice in the worst case scenario we would have increased selector specificity b [We're hiring!](https://woocommerce.com/careers/) Come work with us! -🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/contributors/documentation-guidelines.md) +🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/contributors/coding-guidelines.md) + diff --git a/docs/contributors/components.md b/docs/contributors/components.md index cb17a0281c8..71081ad3673 100644 --- a/docs/contributors/components.md +++ b/docs/contributors/components.md @@ -46,6 +46,7 @@ If you're stuck, copy source of an existing story to get started. [We're hiring!](https://woocommerce.com/careers/) Come work with us! -🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/contributors/documentation-guidelines.md) +🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/contributors/components.md) + diff --git a/docs/contributors/css-build-system.md b/docs/contributors/css-build-system.md index 0402b368542..6ef51402101 100644 --- a/docs/contributors/css-build-system.md +++ b/docs/contributors/css-build-system.md @@ -31,6 +31,7 @@ Webpack config is split between several files, some relevant ones for the CSS bu [We're hiring!](https://woocommerce.com/careers/) Come work with us! -🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/contributors/documentation-guidelines.md) +🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/contributors/css-build-system.md) + diff --git a/docs/contributors/documentation-guidelines.md b/docs/contributors/documentation-guidelines.md index 445d3ef1408..eb515d535e2 100644 --- a/docs/contributors/documentation-guidelines.md +++ b/docs/contributors/documentation-guidelines.md @@ -168,3 +168,4 @@ When referencing other documentations, the corresponding document should be link 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/contributors/documentation-guidelines.md) + diff --git a/docs/contributors/e2e-guidelines.md b/docs/contributors/e2e-guidelines.md index 1bcc1e46c48..e7c26644120 100644 --- a/docs/contributors/e2e-guidelines.md +++ b/docs/contributors/e2e-guidelines.md @@ -62,6 +62,7 @@ By using these packages, you can make your code more modular and easier to maint [We're hiring!](https://woocommerce.com/careers/) Come work with us! -🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/contributors/documentation-guidelines.md) +🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/contributors/e2e-guidelines.md) + diff --git a/docs/contributors/folder-structure.md b/docs/contributors/folder-structure.md index 9ead474b67e..9e4edc88885 100644 --- a/docs/contributors/folder-structure.md +++ b/docs/contributors/folder-structure.md @@ -197,3 +197,4 @@ This file is inspired by the great work of @JustinyAhin and @gziolo in + diff --git a/docs/contributors/getting-started.md b/docs/contributors/getting-started.md index 32b009f5b8b..8c21f8f1042 100644 --- a/docs/contributors/getting-started.md +++ b/docs/contributors/getting-started.md @@ -151,3 +151,4 @@ To find out more about how to run automated JavaScript tests, check out the docu 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/contributors/getting-started.md) + diff --git a/docs/contributors/javascript-build-system.md b/docs/contributors/javascript-build-system.md index 53ca09223f5..f1bd44bbc2c 100644 --- a/docs/contributors/javascript-build-system.md +++ b/docs/contributors/javascript-build-system.md @@ -84,3 +84,4 @@ Webpack config is split between several files: 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/contributors/javascript-build-system.md) + diff --git a/docs/contributors/javascript-testing.md b/docs/contributors/javascript-testing.md index 98dc2d65ba3..0268c7684d8 100644 --- a/docs/contributors/javascript-testing.md +++ b/docs/contributors/javascript-testing.md @@ -118,3 +118,4 @@ When preparing for a new version of WordPress, it's a good practice to search fo 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/contributors/javascript-testing.md) + diff --git a/docs/contributors/storybook-and-components.md b/docs/contributors/storybook-and-components.md index ad7fe3f78a2..823de03da5d 100644 --- a/docs/contributors/storybook-and-components.md +++ b/docs/contributors/storybook-and-components.md @@ -53,3 +53,4 @@ If you're stuck, copy source of an existing story to get started. 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/contributors/storybook-and-components.md) + diff --git a/docs/designers/theming/README.md b/docs/designers/theming/README.md index 9ce791b5a18..ac14bf5a114 100644 --- a/docs/designers/theming/README.md +++ b/docs/designers/theming/README.md @@ -89,3 +89,4 @@ WooCommerce Blocks avoids using legacy unprefixed classes as much as possible. H 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/designers/theming/README.md) + diff --git a/docs/designers/theming/cart-and-checkout.md b/docs/designers/theming/cart-and-checkout.md index 04dc7d9cf0b..2e12ca7d70d 100644 --- a/docs/designers/theming/cart-and-checkout.md +++ b/docs/designers/theming/cart-and-checkout.md @@ -87,3 +87,4 @@ By default, it uses a combination of black and white borders and shadows so it h 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/designers/theming/cart-and-checkout.md) + diff --git a/docs/designers/theming/class-names-update-280.md b/docs/designers/theming/class-names-update-280.md index e6201393be4..75ae51248ea 100644 --- a/docs/designers/theming/class-names-update-280.md +++ b/docs/designers/theming/class-names-update-280.md @@ -97,3 +97,4 @@ For example, given that `wc-block-error` changed to `wc-block-components-error` 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/designers/theming/class-names-update-280.md) + diff --git a/docs/designers/theming/class-names-update-330.md b/docs/designers/theming/class-names-update-330.md index cabd5d21319..53d452411b5 100644 --- a/docs/designers/theming/class-names-update-330.md +++ b/docs/designers/theming/class-names-update-330.md @@ -26,3 +26,4 @@ In [WooCommerce Blocks 3.3.0](https://developer.woocommerce.com/2020/09/02/wooco 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/designers/theming/class-names-update-330.md) + diff --git a/docs/designers/theming/class-names-update-340.md b/docs/designers/theming/class-names-update-340.md index ef5e4cc5f20..e4b56b87df8 100644 --- a/docs/designers/theming/class-names-update-340.md +++ b/docs/designers/theming/class-names-update-340.md @@ -17,3 +17,4 @@ In [WooCommerce Blocks 3.4.0](https://developer.woocommerce.com/2020/09/15/wooco 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/designers/theming/class-names-update-340.md) + diff --git a/docs/designers/theming/class-names-update-460.md b/docs/designers/theming/class-names-update-460.md index a4530ebafd2..5862a1a47d0 100644 --- a/docs/designers/theming/class-names-update-460.md +++ b/docs/designers/theming/class-names-update-460.md @@ -20,3 +20,4 @@ In [WooCommerce Blocks 4.6.0](https://developer.woocommerce.com/2021/03/02/wooco 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/designers/theming/class-names-update-460.md) + diff --git a/docs/designers/theming/filter-blocks.md b/docs/designers/theming/filter-blocks.md index 75665eef188..14cfd3ec80d 100644 --- a/docs/designers/theming/filter-blocks.md +++ b/docs/designers/theming/filter-blocks.md @@ -37,3 +37,4 @@ Notice the code snippet above uses a CSS custom property, so the default color m 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/designers/theming/filter-blocks.md) + diff --git a/docs/designers/theming/product-grid-270.md b/docs/designers/theming/product-grid-270.md index 076d251297e..688004c134d 100644 --- a/docs/designers/theming/product-grid-270.md +++ b/docs/designers/theming/product-grid-270.md @@ -52,3 +52,4 @@ _All Products_ block was updated so prices follow the same layout as the other p 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/designers/theming/product-grid-270.md) + diff --git a/docs/internal-developers/block-client-apis/checkout/checkout-api.md b/docs/internal-developers/block-client-apis/checkout/checkout-api.md index ea8afbd495d..58b9e93b14b 100644 --- a/docs/internal-developers/block-client-apis/checkout/checkout-api.md +++ b/docs/internal-developers/block-client-apis/checkout/checkout-api.md @@ -17,7 +17,7 @@ - [Examples](#examples) - [Passing a value from the client through to server side payment processing](#passing-a-value-from-the-client-through-to-server-side-payment-processing) -This document gives an overview of some of the major architectural components/APIs for the checkout block. If you haven't already, you may also want to read about the [Checkout Flow and Events](../../extensibility/checkout-flow-and-events.md). +This document gives an overview of some of the major architectural components/APIs for the checkout block. If you haven't already, you may also want to read about the [Checkout Flow and Events](checkout-flow-and-events.md). ## Data Stores diff --git a/docs/internal-developers/block-client-apis/checkout/checkout-flow-and-events.md b/docs/internal-developers/block-client-apis/checkout/checkout-flow-and-events.md index 77a0bb7e96a..bb00a7bed69 100644 --- a/docs/internal-developers/block-client-apis/checkout/checkout-flow-and-events.md +++ b/docs/internal-developers/block-client-apis/checkout/checkout-flow-and-events.md @@ -9,7 +9,7 @@ - [`ShippingProvider` Exposed Statuses](#shippingprovider-exposed-statuses) - [Payment Method Data Store Status](#payment-method-data-store-status) - [Emitting Events](#emitting-events) - - [`onCheckoutValidation`](#onCheckoutValidation) + - [`onCheckoutValidation`](#oncheckoutvalidation) - [`onPaymentProcessing`](#onpaymentprocessing) - [Success](#success) - [Fail](#fail) @@ -52,7 +52,7 @@ The following statuses exist in the Checkout. #### Checkout Data Store Status -There are various statuses that are exposed on the Checkout data store via selectors. All the selectors are detailed below and in the [Checkout API docs](https://github.com/woocommerce/woocommerce-gutenberg-products-block/blob/trunk/docs/block-client-apis/checkout/checkout-api.md). +There are various statuses that are exposed on the Checkout data store via selectors. All the selectors are detailed below and in the [Checkout API docs](https://github.com/woocommerce/woocommerce-blocks/blob/trunk/docs/internal-developers/block-client-apis/checkout/checkout-api.md). You can use them in your component like so diff --git a/docs/internal-developers/blocks/feature-flags-and-experimental-interfaces.md b/docs/internal-developers/blocks/feature-flags-and-experimental-interfaces.md index be627273db2..e2febc8d81e 100644 --- a/docs/internal-developers/blocks/feature-flags-and-experimental-interfaces.md +++ b/docs/internal-developers/blocks/feature-flags-and-experimental-interfaces.md @@ -7,7 +7,6 @@ - [Experimental flag](#experimental-flag) - [Features behind flags](#features-behind-flags) - [Feature plugin flag](#feature-plugin-flag-1) - - [Experimental plugin flag](#experimental-plugin-flag) - [Processes and commands that use a flag](#processes-and-commands-that-use-a-flag) - [Usages of `__experimental` prefix](#usages-of-__experimental-prefix) - [PHP filters and actions](#php-filters-and-actions) diff --git a/docs/internal-developers/testing/cart-checkout/data-stores.md b/docs/internal-developers/testing/cart-checkout/data-stores.md index e8686e5ad6e..f100b7f5e50 100644 --- a/docs/internal-developers/testing/cart-checkout/data-stores.md +++ b/docs/internal-developers/testing/cart-checkout/data-stores.md @@ -46,7 +46,7 @@ Go to: [https://github.com/woocommerce/woocommerce-gateway-stripe/blob/8ffd22aff ### Interaction with unusable payment methods -- Install and activate [WooCommerce Bookings](https://github.com/woocommerce/woocommerce-bookings). Add a bookable product, ensure to add a cost to it on the edit product page, then: +- Install and activate [WooCommerce Bookings](https://woocommerce.com/products/woocommerce-bookings/). Add a bookable product, ensure to add a cost to it on the edit product page, then: - Add a _normal_ (i.e. Beanie, Hoodie etc.) product to the cart and ensure you can check out successfully. - Then add a bookable product, ensure you can check out successfully. diff --git a/docs/internal-developers/testing/releases/1083.md b/docs/internal-developers/testing/releases/1083.md new file mode 100644 index 00000000000..6f7a226df45 --- /dev/null +++ b/docs/internal-developers/testing/releases/1083.md @@ -0,0 +1,24 @@ +# Testing notes and ZIP for release 10.8.3 + +Zip file for testing: [woocommerce-gutenberg-products-block.zip](https://github.com/woocommerce/woocommerce-blocks/files/12322309/woocommerce-gutenberg-products-block.zip) + +## WooCommerce Core + +### Create wc-all-block-styles chunk with all blocks stylesheet for classic themes. [#10543](https://github.com/woocommerce/woocommerce-blocks/pull/10543) + +⚠️: Following these testing instruction for a classic theme (Storefront) and a block theme (TT3) + +#### For classic theme ensure that is loaded only `wc-all-blocks-style.css` and `wc-blocks-vendors-style.css` stylesheets + +#### For block theme sure that is loaded only the stylesheets of blocks visible in the page + +1. Create a post or page and add the All Products block. Verify styles are loaded correctly. +2. Visit the page in the frontend and verify styles are loaded correctly in the frontend as well. +3. Repeat steps 1 and 2 with all blocks listed on [this page](https://wordpress.org/plugins/woo-gutenberg-products-block/). Make sure to test each block individually. So, when possible, try with only one block on the page (in some cases, that's not possible, ie: filter blocks, in that case, try with as few blocks as possible on the page). The reason is that we want to make sure each block includes the style dependencies that it needs, so they need to be tested in isolation, otherwise styles from other blocks might leak into other blocks and "help fix issues". + +### Fix the "On Sale" badge position. [#10550](https://github.com/woocommerce/woocommerce-blocks/pull/10550) + +1. Enable the `Storefront` theme. +2. Create a new page or post. +3. Add the `Products by Attribute`, `Products by Tag`, `Products by Category`, `Handpicked products` and `All products` blocks. +4. Check the `Sale` back shows on the top-right corner of the image on all of them, in the editor and in the frontend. diff --git a/docs/internal-developers/testing/releases/1090.md b/docs/internal-developers/testing/releases/1090.md new file mode 100644 index 00000000000..6c530e6fd2e --- /dev/null +++ b/docs/internal-developers/testing/releases/1090.md @@ -0,0 +1,196 @@ +# Testing notes and ZIP for release 10.9.0 + +Zip file for testing: [woocommerce-gutenberg-products-block.zip](https://github.com/woocommerce/woocommerce-blocks/files/12343048/woocommerce-gutenberg-products-block.zip) + +## WooCommerce Core + +### Enhancements + +#### Add the `wc-blocks-footer-pattern` class identifier to all footer patterns. [#10542](https://github.com/woocommerce/woocommerce-blocks/pull/10542) + +1. Create a new post +2. Insert the following footer patterns to the post: + +- Large Footer +- Large Footer Dark +- Simple Footer +- Simple Footer Dark +- Footer with Simple Menu and Cart +- Footer with 2 Menus +- Footer with 2 Menus Dark +- Footer with 3 Menus + +3. Open the code editor and make sure you can see the `wc-blocks-footer-pattern` class in all footer patterns: + +Screenshot 2023-08-11 at 11 16 38 + +4. No changes should be observed by the end users: all patterns listed above should work as expected both on the editor side and on the front end. + +#### Add the `wc-blocks-header-pattern` class identifier to all header patterns. [#10541](https://github.com/woocommerce/woocommerce-blocks/pull/10541) + +1. Create a new post +2. Insert the following header patterns to the post: + +- Centered Header Menu with Search +- Essential Header +- Essential Header Dark +- Large Header +- Large Header Dark +- Minimal Header + +3. Open the code editor and make sure you can see the `wc-blocks-header-pattern` class in all header patterns: + +Screenshot 2023-08-11 at 10 55 27 + +4. No changes should be observed by the end users: all patterns listed above should work as expected both on the editor side and on the front end. + +#### Featured Products: Fresh & Tasty pattern: Enhance mobile view and optimize images. [#10521](https://github.com/woocommerce/woocommerce-blocks/pull/10521) + +1. Create a new post +2. Insert the **Featured Products: Fresh & Tasty** pattern +3. Make sure the pattern is properly displayed in the editor without any problems +4. Save the post and head over to the front-end +5. Make sure the pattern is correctly displayed and the mobile view matches the screenshot provided on the description of this PR. + +##### Screenshots + + + + + + +
Before: +

+Screenshot 2023-08-09 at 18 11 40 +
After: +

+Screenshot 2023-08-09 at 18 11 57 +
+ +#### Add placeholder images and update text styles for the Alternating Image and Text pattern. [#10479](https://github.com/woocommerce/woocommerce-blocks/pull/10479) + +1. Create a new post. +2. Insert the **Alternating Image and Text** pattern. +3. Save the post and ensure everything is working as expected both in the editor and on the frontend. The designs should match the "After" screenshot on this PR. + +##### Screenshots + + + + + + +
Before: +

+Screenshot 2023-08-04 at 15 57 46 +
After: +

+Screenshot 2023-08-04 at 16 02 36 +
+ +#### Performance: Selecting shipping rates during checkout, and API calls in general, are now faster. Shipping selection improved by at least 1 second. [#10472](https://github.com/woocommerce/woocommerce-blocks/pull/10472) + +1. Add items to the cart and head to checkout. +2. Enter your address. Ensure your store has a few shipping methods to choose from. +3. Select a shipping rate. Confirm the UI is blocked (cursor change, faded out radio button). +4. Confirm shipping totals etc update successfully. + +#### Checkout: Prevent postcode validation error notice appearing after pushing changes for other fields. [#10315](https://github.com/woocommerce/woocommerce-blocks/pull/10315) + +1. Add some items to the cart and go to the checkout page +2. Fill out your shipping address and ensure rates appear. You need to complete all required fields before this occurs. +3. Type into a shipping address field. After a short delay confirm that the shipping rates refresh. +4. Type into a different field. Without waiting, tab out of the field. The refresh should happen immediately. +5. Interact with the postcode + country fields. + - Choose Algeria. Enter invalid postcode e.g. ABC. Notice the inline validation. + - Choose Albania. Inline validation should disappear. The postcode is now valid. + - Go back to Algeria. The postcode will clear. There should be no validation message visible. + - Place order. Empty postcode field now has a validation message. +6. Correct all errors and successfully place the order. + +#### Product Button block: Integrate Interactivity API to make the block dynamically. [#10006](https://github.com/woocommerce/woocommerce-blocks/pull/10006) + +1. Ensure that you are using the Blockified Product Catalog Template. If not, enable it. +2. Open the Site Editor and add the Mini Cart Block on the header. Save. +3. Visit the Product Catalog (`/shop`). +4. Click the button to ensure the product is added to the cart. +5. Ensure that the transition Add to cart -> loading status -> 1 in the cart is smooth. +6. Click on the Mini Cart. +7. Edit the quantity of the product. +8. Ensure that the changes are reflected in the Product Button. +9. Via dev tools ensure that the button element has the class `added` when the product is in the cart, and the button element has the class `loading` while the product is added to the cart. + +##### Test ProductButton with cache plugin + +1. Install the plugin [WP Optimize](https://wordpress.org/plugins/wp-optimize/). +2. Ensure that your cart is empty. +3. Ensure that you have the Mini Cart block in the header. +4. Enable the cache. +5. Visit the page with the Products block. +6. Refresh the page. +7. Add a product. +8. Refresh the page. +9. Ensure that the counter is updated with a smoother animation. +10. Open the Mini Cart block and change the quantity of the product in the cart. +11. Ensure that the counter inside the button is updated with a smoother animation. +12. Disable the plugin. +13. Visit the page with the Products block. +14. Open the Mini Cart block and change the quantity of the product in the cart. +15. Ensure that the counter inside the button is updated with a smoother animation. +16. Ensure that there isn't any regression. + +#### Interactivity API: Update interactive regions during client-side navigation [#10200](https://github.com/woocommerce/woocommerce-blocks/pull/10200) + +1. Ensure that you are using the Blockified Product Catalog Template. If not, enable it. +2. Open the Site Editor and go to the Product Catalog Template. +3. In order to make pagination more noticeable, in the Product query block, disable the inherited query settings and manually modify the block markup to set the `perPage` prop inside the `query` attribute to `1`. +4. Visit the Product Catalog (`/shop`). +5. Click on any link inside the Pagination block. +6. Via dev tools, ensure that only the HTML inside the Query block is updated. +7. Navigate back and forward. +8. Via dev tools, ensure that only the HTML inside the Query block is updated. +9. Click on any link outside the Pagination block +10. Ensure that the browser navigates to the selected link. + +##### Screenshots + + + + + + +
Before: +

+ +
After: +

+ +
+ +### Bug Fixes + +#### Fix Express Payments buttons display in the Cart block. [#10534](https://github.com/woocommerce/woocommerce-blocks/pull/10534) + +1. activate Stripe and PayPal and make sure they are active +2. add a product to cart +3. visit the Cart block and make sure buttons are stacked +4. go to the Checkout block and make sure buttons are in a grid +5. repeat the testing in the editor as well +6. repeat the steps with different screen sizes +7. Mini cart does not display express payments so it does not need testing + +#### Fixed a bug which caused theme border colors to not correctly show on the blocks on the editor side. [#10468](https://github.com/woocommerce/woocommerce-blocks/pull/10468) + +1. Add a “Featured Category” block to your page. +2. Open the Inspector Controls → Styles tab → Add a border. +3. Select a custom width and select a color from the theme colors. +4. Ensure this color is shown correctly in the editor. +5. [Regression test] Ensure custom colors are shown correctly in the editor. +6. [Regression test] Ensure both are shown in the front-end. + +#### Fix an issue where inner Cart blocks were incorrectly nested. [#10447](https://github.com/woocommerce/woocommerce-blocks/pull/10447) + +1. Enable a block theme. +2. Go to Appearance -> Editor -> Templates -> Cart. +3. Edit the template and click the "Cart" button at the top of the editor - a dropdown will appear. Click "Clear customizations" here (If it does not show then proceed anyway) +4. Open the list view of blocks, and expand the Cart block, and the Empty Cart block. Ensure there are no duplicate Empty/Filled cart blocks in the top-level Empty Cart block. diff --git a/docs/internal-developers/testing/releases/1091.md b/docs/internal-developers/testing/releases/1091.md new file mode 100644 index 00000000000..4eb41036f68 --- /dev/null +++ b/docs/internal-developers/testing/releases/1091.md @@ -0,0 +1,42 @@ +# Testing notes and ZIP for release 10.9.1 + +Zip file for testing: [woocommerce-gutenberg-products-block.zip](https://github.com/woocommerce/woocommerce-blocks/files/12370561/woocommerce-gutenberg-products-block.zip) + +## WooCommerce Core + +### Bug Fixes + +#### Remove client side navigation from Products beta block. [#10636](https://github.com/woocommerce/woocommerce-blocks/pull/10636) + +1. Create a new post +2. Add Products (Beta) block & publish it +3. On Frontend, verify that + 1. Client-side navigation isn't there anymore i.e. changing the page should also refresh the page + 2. Verify that Product button(Add to cart) still works as expected. + +## Testing notes for the development team + +### Bug Fixes + +1. Checkout to the PR branch and run `npm run start`. +2. Enable a blocks theme (like TT3). +3. Create a new page or post. +4. Add the Products (Beta), Products Collection, Products by Attribute, Products by Tag, Products by Category, Handpicked products, and All products blocks. +5. Check the Sale badge is shown on the top-right corner of the image on all of them, in the editor, and in the frontend. +6. Go to the classic shop page and check the Sale badge also shows in the top-right corner of the product image. +7. Repeat steps 3 to 6 with Storefront enabled. + +#### Screenshots + + + + + + +
Before: +

+Screenshot 2023-08-17 at 09 57 30 +
After: +

+Screenshot 2023-08-17 at 09 56 36 +
diff --git a/docs/internal-developers/testing/releases/1092.md b/docs/internal-developers/testing/releases/1092.md new file mode 100644 index 00000000000..82af63c573f --- /dev/null +++ b/docs/internal-developers/testing/releases/1092.md @@ -0,0 +1,74 @@ +# Testing notes and ZIP for release 10.9.2 + +Zip file for testing: [woocommerce-gutenberg-products-block.zip](https://github.com/woocommerce/woocommerce-blocks/files/12397992/woocommerce-gutenberg-products-block.zip) + +## WooCommerce Core + +### Bug Fixes + +#### Load Interactivity API in `bootstrap.php`. [#10657](https://github.com/woocommerce/woocommerce-blocks/pull/10657) + +> **Note** +> Ignore the first step if testing in WooCommerce Core. + +1. Install this custom build of WooCommerce that includes this patch: [woocommerce.zip](https://github.com/woocommerce/woocommerce-blocks/files/12397185/woocommerce.zip). +2. Make sure that `WooCommerce Blocks` plugin is not active. +3. Open the Site Editor and ensure that you are using the blockified template on the Product Catalog template. +4. Visit the `/shop` page and ensure that the Product Button(Add to Cart) works as expected. + +#### Make View Cart link displayed below the Add to Cart button. [#10675](https://github.com/woocommerce/woocommerce-blocks/pull/10675) + +1. Edit Product Catalog template +2. Add Products (Beta) block if it's not there already +3. Save and go to frontend +4. Add a simple product to cart +5. Expected: "View Cart" link appears BELOW the Add to Cart button + + + + + + +
Before: +

+image +
After: +

+image +
+ +## Should be tested by the development team exclusively + +### Bug Fixes + +#### Fix: Made migration migrate block templates in the current theme. [#10641](https://github.com/woocommerce/woocommerce-blocks/pull/10641) + +1. Install a theme that uses block templates. In my case I used FotaWP. +2. Go to Appearance > Edit > Templates and reset the cart/checkout templates to default. +3. Delete has_migrated_cart and has_migrated_checkout options from your options database. +4. View a page on the store. +5. Confirm by viewing the cart and checkout pages that they inherited the block template from the theme. In this case for instance, instead of the default distraction free template we had, you'll see something like this: + +![Screenshot 2023-08-17 at 12 55 00](https://github.com/woocommerce/woocommerce-blocks/assets/90977/bf55ff6c-e8f7-440e-99ed-ec1e676a988b) + +#### Fix/10530 Inconsistent new install behaviour for templates when using block themes. [#10608](https://github.com/woocommerce/woocommerce-blocks/pull/10608) + +1. Get a new env ready to install WP/WC using WP-CLI. You can use this [quick docker setup](https://github.com/woocommerce/woocommerce-blocks/files/12394720/new-test-env.zip) +2. Alias or copy this branch, built ready to use as a plugin into the env +3. Using WP-CLI set up WC using the following command sequence (alter args to suit your case) + +```sh +wp config create --dbname=wordpress --dbuser=wordpress --dbpass=wordpress --dbhost=db --force +wp core install --url=http://localhost --title='WP Staging' --admin_user=admin --admin_password=pass --admin_email=admin@wp.loc +wp option set blog_public 0 +wp plugin activate woocommerce-blocks +wp plugin install woocommerce --version=6.0.0 +wp plugin activate woocommerce +wp plugin install wordpress-importer --activate +wp import ./wp-content/plugins/woocommerce/sample-data/sample_products.xml --authors=skip +wp plugin update woocommerce +``` + +4. Visit the store for the first time, head to Appearance > Editor > Templates > Manage all templates verify that Cart and Checkout have customizations saved +5. Open each one and verify they contain the shortcode version +6. Test the complete checkout flow. diff --git a/docs/internal-developers/testing/releases/README.md b/docs/internal-developers/testing/releases/README.md index 4789b58035e..230e2544b2c 100644 --- a/docs/internal-developers/testing/releases/README.md +++ b/docs/internal-developers/testing/releases/README.md @@ -168,7 +168,10 @@ Every release includes specific testing instructions for new features and bug fi - [10.8.0](./1080.md) - [10.8.1](./1081.md) - [10.8.2](./1082.md) - + - [10.8.3](./1083.md) +- [10.9.0](./1090.md) + - [10.9.1](./1091.md) + - [10.9.2](./1092.md) diff --git a/docs/third-party-developers/extensibility/README.md b/docs/third-party-developers/extensibility/README.md index dd285d196b7..aa4aa2ba092 100644 --- a/docs/third-party-developers/extensibility/README.md +++ b/docs/third-party-developers/extensibility/README.md @@ -56,3 +56,4 @@ In addition to the reference material below, [please see the `block-checkout` pa 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/README.md) + diff --git a/docs/third-party-developers/extensibility/checkout-block/available-filters.md b/docs/third-party-developers/extensibility/checkout-block/available-filters.md index fe72e5e53e0..9fec5051140 100644 --- a/docs/third-party-developers/extensibility/checkout-block/available-filters.md +++ b/docs/third-party-developers/extensibility/checkout-block/available-filters.md @@ -367,3 +367,4 @@ The error will also be shown in your console. 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/checkout-block/available-filters.md) + diff --git a/docs/third-party-developers/extensibility/checkout-block/available-slot-fills.md b/docs/third-party-developers/extensibility/checkout-block/available-slot-fills.md index 76048d71edf..d172643c5f8 100644 --- a/docs/third-party-developers/extensibility/checkout-block/available-slot-fills.md +++ b/docs/third-party-developers/extensibility/checkout-block/available-slot-fills.md @@ -101,3 +101,4 @@ Checkout: 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/checkout-block/available-slot-fills.md) + diff --git a/docs/third-party-developers/extensibility/checkout-block/dom-events.md b/docs/third-party-developers/extensibility/checkout-block/dom-events.md index 7245d6f179e..d4310b72d62 100644 --- a/docs/third-party-developers/extensibility/checkout-block/dom-events.md +++ b/docs/third-party-developers/extensibility/checkout-block/dom-events.md @@ -50,3 +50,4 @@ _Example usage in WC Blocks:_ Cart and Mini-Cart blocks (via the `useStoreCart() 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/checkout-block/dom-events.md) + diff --git a/docs/third-party-developers/extensibility/checkout-block/how-checkout-processes-an-order.md b/docs/third-party-developers/extensibility/checkout-block/how-checkout-processes-an-order.md index 0b4cb420f63..7aba8f5d4ac 100644 --- a/docs/third-party-developers/extensibility/checkout-block/how-checkout-processes-an-order.md +++ b/docs/third-party-developers/extensibility/checkout-block/how-checkout-processes-an-order.md @@ -145,3 +145,4 @@ The `checkPaymentMethodsCanPay()` [function](https://github.com/woocommerce/wooc 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/checkout-block/how-checkout-processes-an-order.md) + diff --git a/docs/third-party-developers/extensibility/checkout-block/integration-interface.md b/docs/third-party-developers/extensibility/checkout-block/integration-interface.md index 915c6d1205c..2ad690389c4 100644 --- a/docs/third-party-developers/extensibility/checkout-block/integration-interface.md +++ b/docs/third-party-developers/extensibility/checkout-block/integration-interface.md @@ -213,3 +213,4 @@ The value returned here is a plain old JavaScript object, keyed by the keys of t 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/checkout-block/integration-interface.md) + diff --git a/docs/third-party-developers/extensibility/checkout-block/slot-fills.md b/docs/third-party-developers/extensibility/checkout-block/slot-fills.md index e6dd133ba3c..10a0525b071 100644 --- a/docs/third-party-developers/extensibility/checkout-block/slot-fills.md +++ b/docs/third-party-developers/extensibility/checkout-block/slot-fills.md @@ -72,3 +72,4 @@ For this to work, your script must be enqueued after Cart and Checkout. You can 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/checkout-block/slot-fills.md) + diff --git a/docs/third-party-developers/extensibility/checkout-payment-methods/checkout-flow-and-events.md b/docs/third-party-developers/extensibility/checkout-payment-methods/checkout-flow-and-events.md index 666b762f320..bcadd370160 100644 --- a/docs/third-party-developers/extensibility/checkout-payment-methods/checkout-flow-and-events.md +++ b/docs/third-party-developers/extensibility/checkout-payment-methods/checkout-flow-and-events.md @@ -4,6 +4,8 @@ To see the Checkout Flow and Events please consult the following document: [Checkout Flow and Events](../../../../docs/internal-developers/block-client-apis/checkout/checkout-flow-and-events.md) + + --- [We're hiring!](https://woocommerce.com/careers/) Come work with us! @@ -11,3 +13,4 @@ To see the Checkout Flow and Events please consult the following document: 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/checkout-payment-methods/checkout-flow-and-events.md) + diff --git a/docs/third-party-developers/extensibility/checkout-payment-methods/filtering-payment-methods.md b/docs/third-party-developers/extensibility/checkout-payment-methods/filtering-payment-methods.md index e0041826a38..ceba6960536 100644 --- a/docs/third-party-developers/extensibility/checkout-payment-methods/filtering-payment-methods.md +++ b/docs/third-party-developers/extensibility/checkout-payment-methods/filtering-payment-methods.md @@ -174,3 +174,4 @@ If you've added your payment method correctly with the correct `supports` values 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/checkout-payment-methods/filtering-payment-methods.md) + diff --git a/docs/third-party-developers/extensibility/checkout-payment-methods/payment-method-integration.md b/docs/third-party-developers/extensibility/checkout-payment-methods/payment-method-integration.md index 53ac3235165..fdff219c994 100644 --- a/docs/third-party-developers/extensibility/checkout-payment-methods/payment-method-integration.md +++ b/docs/third-party-developers/extensibility/checkout-payment-methods/payment-method-integration.md @@ -265,3 +265,4 @@ As an example, you can see how the Stripe extension adds it's integration in thi 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/checkout-payment-methods/payment-method-integration.md) + diff --git a/docs/third-party-developers/extensibility/data-store/README.md b/docs/third-party-developers/extensibility/data-store/README.md index 50ace2aa889..17849c1c915 100644 --- a/docs/third-party-developers/extensibility/data-store/README.md +++ b/docs/third-party-developers/extensibility/data-store/README.md @@ -16,3 +16,4 @@ 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/data-store/README.md) + diff --git a/docs/third-party-developers/extensibility/data-store/cart.md b/docs/third-party-developers/extensibility/data-store/cart.md index f15e6915227..29ba2289408 100644 --- a/docs/third-party-developers/extensibility/data-store/cart.md +++ b/docs/third-party-developers/extensibility/data-store/cart.md @@ -410,3 +410,4 @@ const isShippingRateBeingSelected = store.isShippingRateBeingSelected(); 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/data-store/cart.md) + diff --git a/docs/third-party-developers/extensibility/data-store/checkout.md b/docs/third-party-developers/extensibility/data-store/checkout.md index ac05a5e5d6a..c94a0de8d31 100644 --- a/docs/third-party-developers/extensibility/data-store/checkout.md +++ b/docs/third-party-developers/extensibility/data-store/checkout.md @@ -167,3 +167,4 @@ This is true when the total is being re-calculated for the order. There are nume 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/data-store/checkout.md) + diff --git a/docs/third-party-developers/extensibility/data-store/payment.md b/docs/third-party-developers/extensibility/data-store/payment.md index be2313a5ccb..a3201b49561 100644 --- a/docs/third-party-developers/extensibility/data-store/payment.md +++ b/docs/third-party-developers/extensibility/data-store/payment.md @@ -13,7 +13,7 @@ - [getSavedPaymentMethods](#getsavedpaymentmethods) - [getActiveSavedPaymentMethods](#getactivesavedpaymentmethods) - [getShouldSavePaymentMethod](#getshouldsavepaymentmethod) - - [getCurrentStatus](#getcurrentstatus) + - [getCurrentStatus](#deprecated-getcurrentstatus) - [paymentMethodsInitialized](#paymentmethodsinitialized) - [expressPaymentMethodsInitialized](#expresspaymentmethodsinitialized) @@ -478,3 +478,4 @@ const expressPaymentMethodsInitialized = 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/data-store/payment.md) + diff --git a/docs/third-party-developers/extensibility/data-store/validation.md b/docs/third-party-developers/extensibility/data-store/validation.md index 50dda790a3d..531b134f350 100644 --- a/docs/third-party-developers/extensibility/data-store/validation.md +++ b/docs/third-party-developers/extensibility/data-store/validation.md @@ -206,3 +206,4 @@ showAllValidationErrors(); 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/data-store/validation.md) + diff --git a/docs/third-party-developers/extensibility/hooks/actions.md b/docs/third-party-developers/extensibility/hooks/actions.md index 8811bedbd18..8143c7a1925 100644 --- a/docs/third-party-developers/extensibility/hooks/actions.md +++ b/docs/third-party-developers/extensibility/hooks/actions.md @@ -6,46 +6,46 @@ ## Table of Contents -- [deprecated_function_run](#deprecated_function_run) -- [woocommerce_add_to_cart](#woocommerce_add_to_cart) -- [woocommerce_after_main_content](#woocommerce_after_main_content) -- [woocommerce_after_shop_loop](#woocommerce_after_shop_loop) -- [woocommerce_applied_coupon](#woocommerce_applied_coupon) -- [woocommerce_archive_description](#woocommerce_archive_description) -- [woocommerce_before_main_content](#woocommerce_before_main_content) -- [woocommerce_before_shop_loop](#woocommerce_before_shop_loop) -- [woocommerce_blocks_cart_enqueue_data](#woocommerce_blocks_cart_enqueue_data) -- [woocommerce_blocks_checkout_enqueue_data](#woocommerce_blocks_checkout_enqueue_data) -- [woocommerce_blocks_enqueue_cart_block_scripts_after](#woocommerce_blocks_enqueue_cart_block_scripts_after) -- [woocommerce_blocks_enqueue_cart_block_scripts_before](#woocommerce_blocks_enqueue_cart_block_scripts_before) -- [woocommerce_blocks_enqueue_checkout_block_scripts_after](#woocommerce_blocks_enqueue_checkout_block_scripts_after) -- [woocommerce_blocks_enqueue_checkout_block_scripts_before](#woocommerce_blocks_enqueue_checkout_block_scripts_before) -- [woocommerce_blocks_loaded](#woocommerce_blocks_loaded) -- [woocommerce*blocks*{$this->registry_identifier}\_registration](#woocommerce_blocks_-this--registry_identifier-_registration) -- [woocommerce_check_cart_items](#-woocommerce_check_cart_items) -- [woocommerce_created_customer](#woocommerce_created_customer) -- [woocommerce_no_products_found](#woocommerce_no_products_found) -- [woocommerce_register_post](#woocommerce_register_post) -- [woocommerce_rest_checkout_process_payment_with_context](#woocommerce_rest_checkout_process_payment_with_context) -- [woocommerce_shop_loop](#woocommerce_shop_loop) -- [woocommerce_store_api_cart_errors](#woocommerce_store_api_cart_errors) -- [woocommerce_store_api_cart_select_shipping_rate](#woocommerce_store_api_cart_select_shipping_rate) -- [woocommerce_store_api_cart_update_customer_from_request](#woocommerce_store_api_cart_update_customer_from_request) -- [woocommerce_store_api_cart_update_order_from_request](#woocommerce_store_api_cart_update_order_from_request) -- [woocommerce_store_api_checkout_order_processed](#woocommerce_store_api_checkout_order_processed) -- [woocommerce_store_api_checkout_update_customer_from_request](#woocommerce_store_api_checkout_update_customer_from_request) -- [woocommerce_store_api_checkout_update_order_from_request](#woocommerce_store_api_checkout_update_order_from_request) -- [woocommerce_store_api_checkout_update_order_meta](#woocommerce_store_api_checkout_update_order_meta) -- [woocommerce_store_api_rate_limit_exceeded](#woocommerce_store_api_rate_limit_exceeded) -- [woocommerce_store_api_validate_add_to_cart](#woocommerce_store_api_validate_add_to_cart) -- [woocommerce_store_api_validate_cart_item](#woocommerce_store_api_validate_cart_item) -- [woocommerce\_{$product->get_type()}\_add_to_cart](#woocommerce_-product--get_type-_add_to_cart) -- [{$hook}](#-hook) + + - [deprecated_function_run](#deprecated_function_run) + - [woocommerce_add_to_cart](#woocommerce_add_to_cart) + - [woocommerce_after_main_content](#woocommerce_after_main_content) + - [woocommerce_after_shop_loop](#woocommerce_after_shop_loop) + - [woocommerce_applied_coupon](#woocommerce_applied_coupon) + - [woocommerce_archive_description](#woocommerce_archive_description) + - [woocommerce_before_main_content](#woocommerce_before_main_content) + - [woocommerce_before_shop_loop](#woocommerce_before_shop_loop) + - [woocommerce_blocks_cart_enqueue_data](#woocommerce_blocks_cart_enqueue_data) + - [woocommerce_blocks_checkout_enqueue_data](#woocommerce_blocks_checkout_enqueue_data) + - [woocommerce_blocks_enqueue_cart_block_scripts_after](#woocommerce_blocks_enqueue_cart_block_scripts_after) + - [woocommerce_blocks_enqueue_cart_block_scripts_before](#woocommerce_blocks_enqueue_cart_block_scripts_before) + - [woocommerce_blocks_enqueue_checkout_block_scripts_after](#woocommerce_blocks_enqueue_checkout_block_scripts_after) + - [woocommerce_blocks_enqueue_checkout_block_scripts_before](#woocommerce_blocks_enqueue_checkout_block_scripts_before) + - [woocommerce_blocks_loaded](#woocommerce_blocks_loaded) + - [woocommerce_blocks_{$this->registry_identifier}_registration](#woocommerce_blocks_this-registry_identifier_registration) + - [woocommerce_check_cart_items](#woocommerce_check_cart_items) + - [woocommerce_created_customer](#woocommerce_created_customer) + - [woocommerce_no_products_found](#woocommerce_no_products_found) + - [woocommerce_register_post](#woocommerce_register_post) + - [woocommerce_shop_loop](#woocommerce_shop_loop) + - [woocommerce_store_api_cart_errors](#woocommerce_store_api_cart_errors) + - [woocommerce_store_api_cart_select_shipping_rate](#woocommerce_store_api_cart_select_shipping_rate) + - [woocommerce_store_api_cart_update_customer_from_request](#woocommerce_store_api_cart_update_customer_from_request) + - [woocommerce_store_api_cart_update_order_from_request](#woocommerce_store_api_cart_update_order_from_request) + - [woocommerce_store_api_checkout_order_processed](#woocommerce_store_api_checkout_order_processed) + - [woocommerce_store_api_checkout_update_customer_from_request](#woocommerce_store_api_checkout_update_customer_from_request) + - [woocommerce_store_api_checkout_update_order_meta](#woocommerce_store_api_checkout_update_order_meta) + - [woocommerce_store_api_rate_limit_exceeded](#woocommerce_store_api_rate_limit_exceeded) + - [woocommerce_store_api_validate_add_to_cart](#woocommerce_store_api_validate_add_to_cart) + - [woocommerce_store_api_validate_cart_item](#woocommerce_store_api_validate_cart_item) + - [woocommerce_{$product->get_type()}_add_to_cart](#woocommerce_product-get_type_add_to_cart) + - [{$hook}](#hook) --- ## deprecated_function_run + Fires when a deprecated function is called. ```php @@ -54,18 +54,21 @@ do_action( 'deprecated_function_run' ) ### Source -- [Domain/Bootstrap.php](../../../../src/Domain/Bootstrap.php) + + - [Domain/Bootstrap.php](../../../../src/Domain/Bootstrap.php) --- ## woocommerce_add_to_cart + Fires when an item is added to the cart. ```php do_action( 'woocommerce_add_to_cart', string $cart_id, integer $product_id, integer $request_quantity, integer $variation_id, array $variation, array $cart_item_data ) ``` + **Note: Matches action name in WooCommerce core.** ### Description @@ -74,23 +77,25 @@ do_action( 'woocommerce_add_to_cart', string $cart_id, integer $product_id, inte ### Parameters -| Argument | Type | Description | -| ----------------- | ------- | ---------------------------------------------- | -| $cart_id | string | ID of the item in the cart. | -| $product_id | integer | ID of the product added to the cart. | -| $request_quantity | integer | Quantity of the item added to the cart. | -| $variation_id | integer | Variation ID of the product added to the cart. | -| $variation | array | Array of variation data. | -| $cart_item_data | array | Array of other cart item data. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $cart_id | string | ID of the item in the cart. | +| $product_id | integer | ID of the product added to the cart. | +| $request_quantity | integer | Quantity of the item added to the cart. | +| $variation_id | integer | Variation ID of the product added to the cart. | +| $variation | array | Array of variation data. | +| $cart_item_data | array | Array of other cart item data. | ### Source -- [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) + + - [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) --- ## woocommerce_after_main_content + Hook: woocommerce_after_main_content ```php @@ -103,17 +108,20 @@ do_action( 'woocommerce_after_main_content' ) ### See -- woocommerce_output_content_wrapper_end() - Outputs closing DIV for the content (priority 10) + + - woocommerce_output_content_wrapper_end() - Outputs closing DIV for the content (priority 10) ### Source -- [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) -- [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) + + - [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) + - [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) --- ## woocommerce_after_shop_loop + Hook: woocommerce_after_shop_loop. ```php @@ -122,38 +130,44 @@ do_action( 'woocommerce_after_shop_loop' ) ### See -- woocommerce_pagination() - Renders pagination (priority 10) + + - woocommerce_pagination() - Renders pagination (priority 10) ### Source -- [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) + + - [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) --- ## woocommerce_applied_coupon + Fires after a coupon has been applied to the cart. ```php do_action( 'woocommerce_applied_coupon', string $coupon_code ) ``` + **Note: Matches action name in WooCommerce core.** ### Parameters -| Argument | Type | Description | -| ------------ | ------ | --------------------------------- | +| Argument | Type | Description | +| -------- | ---- | ----------- | | $coupon_code | string | The coupon code that was applied. | ### Source -- [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) + + - [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) --- ## woocommerce_archive_description + Hook: woocommerce_archive_description. ```php @@ -162,17 +176,20 @@ do_action( 'woocommerce_archive_description' ) ### See -- woocommerce_taxonomy_archive_description() - Renders the taxonomy archive description (priority 10) -- woocommerce_product_archive_description() - Renders the product archive description (priority 10) + + - woocommerce_taxonomy_archive_description() - Renders the taxonomy archive description (priority 10) + - woocommerce_product_archive_description() - Renders the product archive description (priority 10) ### Source -- [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) + + - [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) --- ## woocommerce_before_main_content + Hook: woocommerce_before_main_content ```php @@ -185,19 +202,22 @@ do_action( 'woocommerce_before_main_content' ) ### See -- woocommerce_output_content_wrapper() - Outputs opening DIV for the content (priority 10) -- woocommerce_breadcrumb() - Outputs breadcrumb trail to the current product (priority 20) -- WC_Structured_Data::generate_website_data() - Outputs schema markup (priority 30) + + - woocommerce_output_content_wrapper() - Outputs opening DIV for the content (priority 10) + - woocommerce_breadcrumb() - Outputs breadcrumb trail to the current product (priority 20) + - WC_Structured_Data::generate_website_data() - Outputs schema markup (priority 30) ### Source -- [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) -- [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) + + - [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) + - [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) --- ## woocommerce_before_shop_loop + Hook: woocommerce_before_shop_loop. ```php @@ -206,18 +226,21 @@ do_action( 'woocommerce_before_shop_loop' ) ### See -- woocommerce_output_all_notices() - Render error notices (priority 10) -- woocommerce_result_count() - Show number of results found (priority 20) -- woocommerce_catalog_ordering() - Show form to control sort order (priority 30) + + - woocommerce_output_all_notices() - Render error notices (priority 10) + - woocommerce_result_count() - Show number of results found (priority 20) + - woocommerce_catalog_ordering() - Show form to control sort order (priority 30) ### Source -- [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) + + - [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) --- ## woocommerce_blocks_cart_enqueue_data + Fires after cart block data is registered. ```php @@ -226,13 +249,15 @@ do_action( 'woocommerce_blocks_cart_enqueue_data' ) ### Source -- [BlockTypes/MiniCart.php](../../../../src/BlockTypes/MiniCart.php) -- [BlockTypes/Cart.php](../../../../src/BlockTypes/Cart.php) + + - [BlockTypes/MiniCart.php](../../../../src/BlockTypes/MiniCart.php) + - [BlockTypes/Cart.php](../../../../src/BlockTypes/Cart.php) --- ## woocommerce_blocks_checkout_enqueue_data + Fires after checkout block data is registered. ```php @@ -241,12 +266,14 @@ do_action( 'woocommerce_blocks_checkout_enqueue_data' ) ### Source -- [BlockTypes/Checkout.php](../../../../src/BlockTypes/Checkout.php) + + - [BlockTypes/Checkout.php](../../../../src/BlockTypes/Checkout.php) --- ## woocommerce_blocks_enqueue_cart_block_scripts_after + Fires after cart block scripts are enqueued. ```php @@ -255,12 +282,14 @@ do_action( 'woocommerce_blocks_enqueue_cart_block_scripts_after' ) ### Source -- [BlockTypes/Cart.php](../../../../src/BlockTypes/Cart.php) + + - [BlockTypes/Cart.php](../../../../src/BlockTypes/Cart.php) --- ## woocommerce_blocks_enqueue_cart_block_scripts_before + Fires before cart block scripts are enqueued. ```php @@ -269,12 +298,14 @@ do_action( 'woocommerce_blocks_enqueue_cart_block_scripts_before' ) ### Source -- [BlockTypes/Cart.php](../../../../src/BlockTypes/Cart.php) + + - [BlockTypes/Cart.php](../../../../src/BlockTypes/Cart.php) --- ## woocommerce_blocks_enqueue_checkout_block_scripts_after + Fires after checkout block scripts are enqueued. ```php @@ -283,12 +314,14 @@ do_action( 'woocommerce_blocks_enqueue_checkout_block_scripts_after' ) ### Source -- [BlockTypes/Checkout.php](../../../../src/BlockTypes/Checkout.php) + + - [BlockTypes/Checkout.php](../../../../src/BlockTypes/Checkout.php) --- ## woocommerce_blocks_enqueue_checkout_block_scripts_before + Fires before checkout block scripts are enqueued. ```php @@ -297,12 +330,14 @@ do_action( 'woocommerce_blocks_enqueue_checkout_block_scripts_before' ) ### Source -- [BlockTypes/Checkout.php](../../../../src/BlockTypes/Checkout.php) + + - [BlockTypes/Checkout.php](../../../../src/BlockTypes/Checkout.php) --- ## woocommerce_blocks_loaded + Fires when the woocommerce blocks are loaded and ready to use. ```php @@ -315,11 +350,13 @@ do_action( 'woocommerce_blocks_loaded' ) ### Source -- [Domain/Bootstrap.php](../../../../src/Domain/Bootstrap.php) + + - [Domain/Bootstrap.php](../../../../src/Domain/Bootstrap.php) --- -## woocommerce*blocks*{$this->registry_identifier}\_registration +## woocommerce_blocks_{$this->registry_identifier}_registration + Fires when the IntegrationRegistry is initialized. @@ -333,26 +370,30 @@ do_action( 'woocommerce_blocks_{$this->registry_identifier}_registration', \Auto ### Parameters -| Argument | Type | Description | -| -------- | --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | -| $this | \Automattic\WooCommerce\Blocks\Integrations\IntegrationRegistry | Instance of the IntegrationRegistry class which exposes the IntegrationRegistry::register() method. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $this | \Automattic\WooCommerce\Blocks\Integrations\IntegrationRegistry | Instance of the IntegrationRegistry class which exposes the IntegrationRegistry::register() method. | ### Source -- [Integrations/IntegrationRegistry.php](../../../../src/Integrations/IntegrationRegistry.php) + + - [Integrations/IntegrationRegistry.php](../../../../src/Integrations/IntegrationRegistry.php) --- ## ~~woocommerce_check_cart_items~~ + Fires when cart items are being validated. ```php do_action( 'woocommerce_check_cart_items' ) ``` + **Deprecated: This hook is deprecated and will be removed** + **Note: Matches action name in WooCommerce core.** ### Description @@ -361,18 +402,21 @@ do_action( 'woocommerce_check_cart_items' ) ### Source -- [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) + + - [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) --- ## woocommerce_created_customer + Fires after a customer account has been registered. ```php do_action( 'woocommerce_created_customer', integer $customer_id, array $new_customer_data, string $password_generated ) ``` + **Note: Matches filter name in WooCommerce core.** ### Description @@ -381,20 +425,22 @@ do_action( 'woocommerce_created_customer', integer $customer_id, array $new_cust ### Parameters -| Argument | Type | Description | -| ------------------- | ------- | --------------------------------------- | -| $customer_id | integer | New customer (user) ID. | -| $new_customer_data | array | Array of customer (user) data. | -| $password_generated | string | The generated password for the account. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $customer_id | integer | New customer (user) ID. | +| $new_customer_data | array | Array of customer (user) data. | +| $password_generated | string | The generated password for the account. | ### Source -- [StoreApi/Routes/V1/Checkout.php](../../../../src/StoreApi/Routes/V1/Checkout.php) + + - [StoreApi/Routes/V1/Checkout.php](../../../../src/StoreApi/Routes/V1/Checkout.php) --- ## woocommerce_no_products_found + Hook: woocommerce_no_products_found. ```php @@ -403,22 +449,26 @@ do_action( 'woocommerce_no_products_found' ) ### See -- wc_no_products_found() - Default no products found content (priority 10) + + - wc_no_products_found() - Default no products found content (priority 10) ### Source -- [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) + + - [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) --- ## woocommerce_register_post + Fires before a customer account is registered. ```php do_action( 'woocommerce_register_post', string $username, string $user_email, \WP_Error $errors ) ``` + **Note: Matches filter name in WooCommerce core.** ### Description @@ -427,45 +477,22 @@ do_action( 'woocommerce_register_post', string $username, string $user_email, \W ### Parameters -| Argument | Type | Description | -| ----------- | --------- | ----------------------- | -| $username | string | Customer username. | -| $user_email | string | Customer email address. | -| $errors | \WP_Error | Error object. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $username | string | Customer username. | +| $user_email | string | Customer email address. | +| $errors | \WP_Error | Error object. | ### Source -- [StoreApi/Routes/V1/Checkout.php](../../../../src/StoreApi/Routes/V1/Checkout.php) ---- - -## woocommerce_rest_checkout_process_payment_with_context - -Process payment with context. - -```php -do_action_ref_array( 'woocommerce_rest_checkout_process_payment_with_context', [ \Automattic\WooCommerce\StoreApi\Payments\PaymentContext $context, \Automattic\WooCommerce\StoreApi\Payments\PaymentResult $payment_result ] ) -``` - -### Parameters - -| Argument | Type | Description | -| --------------- | -------------------------------------------------------- | --------------------------------------------------------------------- | -| $context | \Automattic\WooCommerce\StoreApi\Payments\PaymentContext | Holds context for the payment, including order ID and payment method. | -| $payment_result | \Automattic\WooCommerce\StoreApi\Payments\PaymentResult | Result object for the transaction. | - -### Exceptions - -`\Exception` If there is an error taking payment, an \Exception object can be thrown with an error message. - -### Source - -- [StoreApi/Routes/V1/Checkout.php](../../../../src/StoreApi/Routes/V1/Checkout.php) + - [StoreApi/Routes/V1/Checkout.php](../../../../src/StoreApi/Routes/V1/Checkout.php) --- ## woocommerce_shop_loop + Hook: woocommerce_shop_loop. ```php @@ -474,12 +501,14 @@ do_action( 'woocommerce_shop_loop' ) ### Source -- [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) + + - [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) --- ## woocommerce_store_api_cart_errors + Fires an action to validate the cart. ```php @@ -492,10 +521,10 @@ do_action( 'woocommerce_store_api_cart_errors', \WP_Error $errors, \WC_Cart $car ### Parameters -| Argument | Type | Description | -| -------- | --------- | ---------------- | -| $errors | \WP_Error | WP_Error object. | -| $cart | \WC_Cart | Cart object. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $errors | \WP_Error | WP_Error object. | +| $cart | \WC_Cart | Cart object. | ### Example @@ -514,14 +543,17 @@ function my_function_callback( $errors, $cart ) { add_action( 'woocommerce_store_api_cart_errors', 'my_function_callback', 10 ); ``` + ### Source -- [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) + + - [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) --- ## woocommerce_store_api_cart_select_shipping_rate + Fires an action after a shipping method has been chosen for package(s) via the Store API. ```php @@ -534,20 +566,22 @@ do_action( 'woocommerce_store_api_cart_select_shipping_rate', string|null $packa ### Parameters -| Argument | Type | Description | -| ----------- | ---------------- | -------------------------------------------------------------------------------------- | -| $package_id | string, null | The sanitized ID of the package being updated. Null if all packages are being updated. | -| $rate_id | string | The sanitized chosen rate ID for the package. | -| $request | \WP_REST_Request | Full details about the request. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $package_id | string, null | The sanitized ID of the package being updated. Null if all packages are being updated. | +| $rate_id | string | The sanitized chosen rate ID for the package. | +| $request | \WP_REST_Request | Full details about the request. | ### Source -- [StoreApi/Routes/V1/CartSelectShippingRate.php](../../../../src/StoreApi/Routes/V1/CartSelectShippingRate.php) + + - [StoreApi/Routes/V1/CartSelectShippingRate.php](../../../../src/StoreApi/Routes/V1/CartSelectShippingRate.php) --- ## woocommerce_store_api_cart_update_customer_from_request + Fires when the Checkout Block/Store API updates a customer from the API request data. ```php @@ -556,19 +590,21 @@ do_action( 'woocommerce_store_api_cart_update_customer_from_request', \WC_Custom ### Parameters -| Argument | Type | Description | -| --------- | ---------------- | ------------------------------- | -| $customer | \WC_Customer | Customer object. | -| $request | \WP_REST_Request | Full details about the request. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $customer | \WC_Customer | Customer object. | +| $request | \WP_REST_Request | Full details about the request. | ### Source -- [StoreApi/Routes/V1/CartUpdateCustomer.php](../../../../src/StoreApi/Routes/V1/CartUpdateCustomer.php) + + - [StoreApi/Routes/V1/CartUpdateCustomer.php](../../../../src/StoreApi/Routes/V1/CartUpdateCustomer.php) --- ## woocommerce_store_api_cart_update_order_from_request + Fires when the order is synced with cart data from a cart route. ```php @@ -577,20 +613,22 @@ do_action( 'woocommerce_store_api_cart_update_order_from_request', \WC_Order $dr ### Parameters -| Argument | Type | Description | -| ------------ | ---------------- | ------------------------------- | -| $draft_order | \WC_Order | Order object. | -| $customer | \WC_Customer | Customer object. | -| $request | \WP_REST_Request | Full details about the request. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $draft_order | \WC_Order | Order object. | +| $customer | \WC_Customer | Customer object. | +| $request | \WP_REST_Request | Full details about the request. | ### Source -- [StoreApi/Routes/V1/AbstractCartRoute.php](../../../../src/StoreApi/Routes/V1/AbstractCartRoute.php) + + - [StoreApi/Routes/V1/AbstractCartRoute.php](../../../../src/StoreApi/Routes/V1/AbstractCartRoute.php) --- ## woocommerce_store_api_checkout_order_processed + Fires before an order is processed by the Checkout Block/Store API. ```php @@ -603,9 +641,9 @@ do_action( 'woocommerce_store_api_checkout_order_processed', \WC_Order $order ) ### Parameters -| Argument | Type | Description | -| -------- | --------- | ------------- | -| $order | \WC_Order | Order object. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $order | \WC_Order | Order object. | ### Example @@ -621,18 +659,23 @@ function my_function_callback( $order ) { add_action( 'woocommerce_blocks_checkout_order_processed', 'my_function_callback', 10 ); ``` + ### See -- https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3238 + + - https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3238 ### Source -- [StoreApi/Routes/V1/Checkout.php](../../../../src/StoreApi/Routes/V1/Checkout.php) + + - [StoreApi/Routes/V1/CheckoutOrder.php](../../../../src/StoreApi/Routes/V1/CheckoutOrder.php) + - [StoreApi/Routes/V1/Checkout.php](../../../../src/StoreApi/Routes/V1/Checkout.php) --- ## woocommerce_store_api_checkout_update_customer_from_request + Fires when the Checkout Block/Store API updates a customer from the API request data. ```php @@ -641,44 +684,22 @@ do_action( 'woocommerce_store_api_checkout_update_customer_from_request', \WC_Cu ### Parameters -| Argument | Type | Description | -| --------- | ---------------- | ------------------------------- | -| $customer | \WC_Customer | Customer object. | -| $request | \WP_REST_Request | Full details about the request. | - -### Source - -- [StoreApi/Routes/V1/Checkout.php](../../../../src/StoreApi/Routes/V1/Checkout.php) - ---- - -## woocommerce_store_api_checkout_update_order_from_request - -Fires when the Checkout Block/Store API updates an order's from the API request data. - -```php -do_action( 'woocommerce_store_api_checkout_update_order_from_request', \WC_Order $order, \WP_REST_Request $request ) -``` - -### Description - -

This hook gives extensions the chance to update orders based on the data in the request. This can be used in conjunction with the ExtendSchema class to post custom data and then process it.

- -### Parameters - -| Argument | Type | Description | -| -------- | ---------------- | ------------------------------- | -| $order | \WC_Order | Order object. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $customer | \WC_Customer | Customer object. | | $request | \WP_REST_Request | Full details about the request. | ### Source -- [StoreApi/Routes/V1/Checkout.php](../../../../src/StoreApi/Routes/V1/Checkout.php) + + - [StoreApi/Routes/V1/CheckoutOrder.php](../../../../src/StoreApi/Routes/V1/CheckoutOrder.php) + - [StoreApi/Routes/V1/Checkout.php](../../../../src/StoreApi/Routes/V1/Checkout.php) --- ## woocommerce_store_api_checkout_update_order_meta + Fires when the Checkout Block/Store API updates an order's meta data. ```php @@ -691,22 +712,25 @@ do_action( 'woocommerce_store_api_checkout_update_order_meta', \WC_Order $order ### Parameters -| Argument | Type | Description | -| -------- | --------- | ------------- | -| $order | \WC_Order | Order object. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $order | \WC_Order | Order object. | ### See -- https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3686 + + - https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/3686 ### Source -- [StoreApi/Routes/V1/Checkout.php](../../../../src/StoreApi/Routes/V1/Checkout.php) + + - [StoreApi/Routes/V1/Checkout.php](../../../../src/StoreApi/Routes/V1/Checkout.php) --- ## woocommerce_store_api_rate_limit_exceeded + Fires when the rate limit is exceeded. ```php @@ -715,18 +739,20 @@ do_action( 'woocommerce_store_api_rate_limit_exceeded', string $ip_address ) ### Parameters -| Argument | Type | Description | -| ----------- | ------ | ------------------------------ | +| Argument | Type | Description | +| -------- | ---- | ----------- | | $ip_address | string | The IP address of the request. | ### Source -- [StoreApi/Authentication.php](../../../../src/StoreApi/Authentication.php) + + - [StoreApi/Authentication.php](../../../../src/StoreApi/Authentication.php) --- ## woocommerce_store_api_validate_add_to_cart + Fires during validation when adding an item to the cart via the Store API. ```php @@ -739,19 +765,21 @@ do_action( 'woocommerce_store_api_validate_add_to_cart', \WC_Product $product, a ### Parameters -| Argument | Type | Description | -| -------- | ----------- | ---------------------------------------------------------------------------- | -| $product | \WC_Product | Product object being added to the cart. | -| $request | array | Add to cart request params including id, quantity, and variation attributes. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $product | \WC_Product | Product object being added to the cart. | +| $request | array | Add to cart request params including id, quantity, and variation attributes. | ### Source -- [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) + + - [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) --- ## woocommerce_store_api_validate_cart_item + Fire action to validate add to cart. Functions hooking into this should throw an \Exception to prevent add to cart from occurring. ```php @@ -760,18 +788,20 @@ do_action( 'woocommerce_store_api_validate_cart_item', \WC_Product $product, arr ### Parameters -| Argument | Type | Description | -| ---------- | ----------- | --------------------------------------- | -| $product | \WC_Product | Product object being added to the cart. | -| $cart_item | array | Cart item array. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $product | \WC_Product | Product object being added to the cart. | +| $cart_item | array | Cart item array. | ### Source -- [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) + + - [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) --- -## woocommerce\_{$product->get_type()}\_add_to_cart +## woocommerce_{$product->get_type()}_add_to_cart + Trigger the single product add to cart action for each product type. @@ -781,12 +811,14 @@ do_action( 'woocommerce_{$product->get_type()}_add_to_cart' ) ### Source -- [BlockTypes/AddToCartForm.php](../../../../src/BlockTypes/AddToCartForm.php) + + - [BlockTypes/AddToCartForm.php](../../../../src/BlockTypes/AddToCartForm.php) --- ## {$hook} + Action to render the content of a hook. ```php @@ -795,10 +827,10 @@ do_action( '{$hook}' ) ### Source -- [Templates/AbstractTemplateCompatibility.php](../../../../src/Templates/AbstractTemplateCompatibility.php) ---- + - [Templates/AbstractTemplateCompatibility.php](../../../../src/Templates/AbstractTemplateCompatibility.php) +--- --- @@ -808,3 +840,4 @@ do_action( '{$hook}' ) 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/hooks/actions.md) + diff --git a/docs/third-party-developers/extensibility/hooks/filters.md b/docs/third-party-developers/extensibility/hooks/filters.md index b446dff5f9d..2ac864847ab 100644 --- a/docs/third-party-developers/extensibility/hooks/filters.md +++ b/docs/third-party-developers/extensibility/hooks/filters.md @@ -6,45 +6,52 @@ ## Table of Contents -- [\_\_experimental_woocommerce_blocks_add_data_attributes_to_block](#__experimental_woocommerce_blocks_add_data_attributes_to_block) -- [\_\_experimental_woocommerce_blocks_add_data_attributes_to_namespace](#__experimental_woocommerce_blocks_add_data_attributes_to_namespace) -- [\_\_experimental_woocommerce_blocks_payment_gateway_features_list](#__experimental_woocommerce_blocks_payment_gateway_features_list) -- [deprecated_function_trigger_error](#deprecated_function_trigger_error) -- [wc_session_expiration](#wc_session_expiration) -- [woocommerce_add_cart_item](#woocommerce_add_cart_item) -- [woocommerce_add_cart_item_data](#woocommerce_add_cart_item_data) -- [woocommerce_add_to_cart_sold_individually_quantity](#woocommerce_add_to_cart_sold_individually_quantity) -- [woocommerce_add_to_cart_validation](#-woocommerce_add_to_cart_validation) -- [woocommerce_adjust_non_base_location_prices](#woocommerce_adjust_non_base_location_prices) -- [woocommerce_apply_base_tax_for_local_pickup](#woocommerce_apply_base_tax_for_local_pickup) -- [woocommerce_apply_individual_use_coupon](#woocommerce_apply_individual_use_coupon) -- [woocommerce_apply_with_individual_use_coupon](#woocommerce_apply_with_individual_use_coupon) -- [woocommerce_blocks_hook_compatibility_additional_data](#woocommerce_blocks_hook_compatibility_additional_data) -- [woocommerce_blocks_product_grid_is_cacheable](#woocommerce_blocks_product_grid_is_cacheable) -- [woocommerce_blocks_product_grid_item_html](#woocommerce_blocks_product_grid_item_html) -- [woocommerce_blocks_register_script_dependencies](#woocommerce_blocks_register_script_dependencies) -- [woocommerce_cart_contents_changed](#woocommerce_cart_contents_changed) -- [woocommerce_disable_compatibility_layer](#woocommerce_disable_compatibility_layer) -- [woocommerce_ga_disable_tracking](#woocommerce_ga_disable_tracking) -- [woocommerce_get_item_data](#woocommerce_get_item_data) -- [woocommerce_loop_add_to_cart_args](#woocommerce_loop_add_to_cart_args) -- [woocommerce_loop_add_to_cart_link](#woocommerce_loop_add_to_cart_link) -- [woocommerce_new_customer_data](#woocommerce_new_customer_data) -- [woocommerce_registration_errors](#woocommerce_registration_errors) -- [woocommerce_shared_settings](#-woocommerce_shared_settings) -- [woocommerce_shipping_package_name](#woocommerce_shipping_package_name) -- [woocommerce*shipping*{$this->id}\_is_available](#woocommerce_shipping_-this--id-_is_available) -- [woocommerce_show_page_title](#woocommerce_show_page_title) -- [woocommerce_store_api_add_to_cart_data](#woocommerce_store_api_add_to_cart_data) -- [woocommerce_store_api_disable_nonce_check](#woocommerce_store_api_disable_nonce_check) -- [woocommerce_store_api_product_quantity_limit](#woocommerce_store_api_product_quantity_limit) -- [woocommerce*store_api_product_quantity*{$value_type}](#woocommerce_store_api_product_quantity_-value_type) -- [woocommerce_store_api_rate_limit_options](#woocommerce_store_api_rate_limit_options) -- [woocommerce_variation_option_name](#woocommerce_variation_option_name) - ---- - -## \_\_experimental_woocommerce_blocks_add_data_attributes_to_block + + - [__experimental_woocommerce_blocks_add_data_attributes_to_block](#__experimental_woocommerce_blocks_add_data_attributes_to_block) + - [__experimental_woocommerce_blocks_add_data_attributes_to_namespace](#__experimental_woocommerce_blocks_add_data_attributes_to_namespace) + - [__experimental_woocommerce_blocks_payment_gateway_features_list](#__experimental_woocommerce_blocks_payment_gateway_features_list) + - [deprecated_function_trigger_error](#deprecated_function_trigger_error) + - [loop_shop_per_page](#loop_shop_per_page) + - [wc_session_expiration](#wc_session_expiration) + - [woocommerce_add_cart_item](#woocommerce_add_cart_item) + - [woocommerce_add_cart_item_data](#woocommerce_add_cart_item_data) + - [woocommerce_add_to_cart_quantity](#woocommerce_add_to_cart_quantity) + - [woocommerce_add_to_cart_sold_individually_quantity](#woocommerce_add_to_cart_sold_individually_quantity) + - [woocommerce_add_to_cart_validation](#woocommerce_add_to_cart_validation) + - [woocommerce_adjust_non_base_location_prices](#woocommerce_adjust_non_base_location_prices) + - [woocommerce_apply_base_tax_for_local_pickup](#woocommerce_apply_base_tax_for_local_pickup) + - [woocommerce_apply_individual_use_coupon](#woocommerce_apply_individual_use_coupon) + - [woocommerce_apply_with_individual_use_coupon](#woocommerce_apply_with_individual_use_coupon) + - [woocommerce_blocks_hook_compatibility_additional_data](#woocommerce_blocks_hook_compatibility_additional_data) + - [woocommerce_blocks_product_grid_is_cacheable](#woocommerce_blocks_product_grid_is_cacheable) + - [woocommerce_blocks_product_grid_item_html](#woocommerce_blocks_product_grid_item_html) + - [woocommerce_blocks_register_script_dependencies](#woocommerce_blocks_register_script_dependencies) + - [woocommerce_cart_contents_changed](#woocommerce_cart_contents_changed) + - [woocommerce_cart_item_permalink](#woocommerce_cart_item_permalink) + - [woocommerce_disable_compatibility_layer](#woocommerce_disable_compatibility_layer) + - [woocommerce_ga_disable_tracking](#woocommerce_ga_disable_tracking) + - [woocommerce_get_item_data](#woocommerce_get_item_data) + - [woocommerce_loop_add_to_cart_args](#woocommerce_loop_add_to_cart_args) + - [woocommerce_loop_add_to_cart_link](#woocommerce_loop_add_to_cart_link) + - [woocommerce_new_customer_data](#woocommerce_new_customer_data) + - [woocommerce_pay_order_product_has_enough_stock](#woocommerce_pay_order_product_has_enough_stock) + - [woocommerce_pay_order_product_in_stock](#woocommerce_pay_order_product_in_stock) + - [woocommerce_registration_errors](#woocommerce_registration_errors) + - [woocommerce_shared_settings](#woocommerce_shared_settings) + - [woocommerce_shipping_package_name](#woocommerce_shipping_package_name) + - [woocommerce_shipping_{$this->id}_is_available](#woocommerce_shipping_this-id_is_available) + - [woocommerce_show_page_title](#woocommerce_show_page_title) + - [woocommerce_single_product_image_thumbnail_html](#woocommerce_single_product_image_thumbnail_html) + - [woocommerce_store_api_add_to_cart_data](#woocommerce_store_api_add_to_cart_data) + - [woocommerce_store_api_disable_nonce_check](#woocommerce_store_api_disable_nonce_check) + - [woocommerce_store_api_product_quantity_limit](#woocommerce_store_api_product_quantity_limit) + - [woocommerce_store_api_product_quantity_{$value_type}](#woocommerce_store_api_product_quantity_value_type) + - [woocommerce_store_api_rate_limit_options](#woocommerce_store_api_rate_limit_options) + +--- + +## __experimental_woocommerce_blocks_add_data_attributes_to_block + Filters the list of allowed Block Names @@ -58,17 +65,19 @@ apply_filters( '__experimental_woocommerce_blocks_add_data_attributes_to_block', ### Parameters -| Argument | Type | Description | -| ------------------- | ----- | ------------------- | +| Argument | Type | Description | +| -------- | ---- | ----------- | | $allowed_namespaces | array | List of namespaces. | ### Source -- [BlockTypesController.php](../../../../src/BlockTypesController.php) + + - [BlockTypesController.php](../../../../src/BlockTypesController.php) --- -## \_\_experimental_woocommerce_blocks_add_data_attributes_to_namespace +## __experimental_woocommerce_blocks_add_data_attributes_to_namespace + Filters the list of allowed block namespaces. @@ -82,17 +91,19 @@ apply_filters( '__experimental_woocommerce_blocks_add_data_attributes_to_namespa ### Parameters -| Argument | Type | Description | -| ------------------- | ----- | ------------------- | +| Argument | Type | Description | +| -------- | ---- | ----------- | | $allowed_namespaces | array | List of namespaces. | ### Source -- [BlockTypesController.php](../../../../src/BlockTypesController.php) + + - [BlockTypesController.php](../../../../src/BlockTypesController.php) --- -## \_\_experimental_woocommerce_blocks_payment_gateway_features_list +## __experimental_woocommerce_blocks_payment_gateway_features_list + Filter to control what features are available for each payment gateway. @@ -102,13 +113,14 @@ apply_filters( '__experimental_woocommerce_blocks_payment_gateway_features_list' ### Parameters -| Argument | Type | Description | -| --------- | ------ | --------------------------- | -| $features | array | List of supported features. | -| $name | string | Gateway name. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $features | array | List of supported features. | +| $name | string | Gateway name. | ### Returns + `array` Updated list of supported features. ### Example @@ -128,14 +140,17 @@ function my_function_callback( $features, $gateway ) { add_filter( '__experimental_woocommerce_blocks_payment_gateway_features_list', 'my_function_callback', 10, 2 ); ``` + ### Source -- [Payments/Integrations/PayPal.php](../../../../src/Payments/Integrations/PayPal.php) + + - [Payments/Integrations/PayPal.php](../../../../src/Payments/Integrations/PayPal.php) --- ## deprecated_function_trigger_error + Filters whether to trigger an error for deprecated functions. (Same as WP core) ```php @@ -144,18 +159,37 @@ apply_filters( 'deprecated_function_trigger_error', bool $trigger ) ### Parameters -| Argument | Type | Description | -| -------- | ---- | -------------------------------------------------------------------- | +| Argument | Type | Description | +| -------- | ---- | ----------- | | $trigger | bool | Whether to trigger the error for deprecated functions. Default true. | ### Source -- [Domain/Bootstrap.php](../../../../src/Domain/Bootstrap.php) + + - [Domain/Bootstrap.php](../../../../src/Domain/Bootstrap.php) + +--- + +## loop_shop_per_page + + + + +```php +apply_filters( 'loop_shop_per_page' ) +``` + +### Source + + + - [BlockTypes/ProductQuery.php](../../../../src/BlockTypes/ProductQuery.php) + - [BlockTypes/ProductCollection.php](../../../../src/BlockTypes/ProductCollection.php) --- ## wc_session_expiration + Filters the session expiration. ```php @@ -164,110 +198,148 @@ apply_filters( 'wc_session_expiration', int $expiration ) ### Parameters -| Argument | Type | Description | -| ----------- | ---- | ---------------------- | -| $expiration | int | Expiration in seconds. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $expiration | int | Expiration in seconds. | ### Source -- [StoreApi/Routes/V1/AbstractCartRoute.php](../../../../src/StoreApi/Routes/V1/AbstractCartRoute.php) + + - [StoreApi/Routes/V1/AbstractCartRoute.php](../../../../src/StoreApi/Routes/V1/AbstractCartRoute.php) --- ## woocommerce_add_cart_item + Filters the item being added to the cart. ```php apply_filters( 'woocommerce_add_cart_item', array $cart_item_data, string $cart_id ) ``` + **Note: Matches filter name in WooCommerce core.** ### Parameters -| Argument | Type | Description | -| --------------- | ------ | ------------------------------------------------ | -| $cart_item_data | array | Array of cart item data being added to the cart. | -| $cart_id | string | Id of the item in the cart. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $cart_item_data | array | Array of cart item data being added to the cart. | +| $cart_id | string | Id of the item in the cart. | ### Returns + `array` Updated cart item data. ### Source -- [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) + + - [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) --- ## woocommerce_add_cart_item_data + Filter cart item data for add to cart requests. ```php apply_filters( 'woocommerce_add_cart_item_data', array $cart_item_data, integer $product_id, integer $variation_id, integer $quantity ) ``` + **Note: Matches filter name in WooCommerce core.** ### Parameters -| Argument | Type | Description | -| --------------- | ------- | ---------------------------------------------- | -| $cart_item_data | array | Array of other cart item data. | -| $product_id | integer | ID of the product added to the cart. | -| $variation_id | integer | Variation ID of the product added to the cart. | -| $quantity | integer | Quantity of the item added to the cart. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $cart_item_data | array | Array of other cart item data. | +| $product_id | integer | ID of the product added to the cart. | +| $variation_id | integer | Variation ID of the product added to the cart. | +| $quantity | integer | Quantity of the item added to the cart. | ### Returns -`array` + +`array` + +### Source + + + - [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) + +--- + +## woocommerce_add_to_cart_quantity + + +Filters the change the quantity to add to cart. + +```php +apply_filters( 'woocommerce_add_to_cart_quantity', \Automattic\WooCommerce\Blocks\BlockTypes\number $default_quantity, \Automattic\WooCommerce\Blocks\BlockTypes\number $product_id ) +``` + +### Parameters + +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $default_quantity | \Automattic\WooCommerce\Blocks\BlockTypes\number | The default quantity. | +| $product_id | \Automattic\WooCommerce\Blocks\BlockTypes\number | The product id. | ### Source -- [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) + + - [BlockTypes/ProductButton.php](../../../../src/BlockTypes/ProductButton.php) --- ## woocommerce_add_to_cart_sold_individually_quantity + Filter sold individually quantity for add to cart requests. ```php apply_filters( 'woocommerce_add_to_cart_sold_individually_quantity', integer $sold_individually_quantity, integer $quantity, integer $product_id, integer $variation_id, array $cart_item_data ) ``` + **Note: Matches filter name in WooCommerce core.** ### Parameters -| Argument | Type | Description | -| --------------------------- | ------- | ---------------------------------------------- | -| $sold_individually_quantity | integer | Defaults to 1. | -| $quantity | integer | Quantity of the item added to the cart. | -| $product_id | integer | ID of the product added to the cart. | -| $variation_id | integer | Variation ID of the product added to the cart. | -| $cart_item_data | array | Array of other cart item data. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $sold_individually_quantity | integer | Defaults to 1. | +| $quantity | integer | Quantity of the item added to the cart. | +| $product_id | integer | ID of the product added to the cart. | +| $variation_id | integer | Variation ID of the product added to the cart. | +| $cart_item_data | array | Array of other cart item data. | ### Returns -`integer` + +`integer` ### Source -- [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) + + - [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) --- ## ~~woocommerce_add_to_cart_validation~~ + Filters if an item being added to the cart passed validation checks. ```php apply_filters( 'woocommerce_add_to_cart_validation', boolean $passed_validation, integer $product_id, integer $quantity, integer $variation_id, array $variation ) ``` + **Deprecated: This hook is deprecated and will be removed** ### Description @@ -276,32 +348,36 @@ apply_filters( 'woocommerce_add_to_cart_validation', boolean $passed_validation, ### Parameters -| Argument | Type | Description | -| ------------------ | ------- | ------------------------------------- | -| $passed_validation | boolean | True if the item passed validation. | -| $product_id | integer | Product ID being validated. | -| $quantity | integer | Quantity added to the cart. | -| $variation_id | integer | Variation ID being added to the cart. | -| $variation | array | Variation data. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $passed_validation | boolean | True if the item passed validation. | +| $product_id | integer | Product ID being validated. | +| $quantity | integer | Quantity added to the cart. | +| $variation_id | integer | Variation ID being added to the cart. | +| $variation | array | Variation data. | ### Returns -`boolean` + +`boolean` ### Source -- [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) + + - [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) --- ## woocommerce_adjust_non_base_location_prices + Filters if taxes should be removed from locations outside the store base location. ```php apply_filters( 'woocommerce_adjust_non_base_location_prices', boolean $adjust_non_base_location_prices ) ``` + **Note: Matches filter name in WooCommerce core.** ### Description @@ -310,91 +386,106 @@ apply_filters( 'woocommerce_adjust_non_base_location_prices', boolean $adjust_no ### Parameters -| Argument | Type | Description | -| -------------------------------- | ------- | ---------------- | +| Argument | Type | Description | +| -------- | ---- | ----------- | | $adjust_non_base_location_prices | boolean | True by default. | ### Returns -`boolean` + +`boolean` ### Source -- [StoreApi/Utilities/ProductQuery.php](../../../../src/StoreApi/Utilities/ProductQuery.php) + + - [StoreApi/Utilities/ProductQuery.php](../../../../src/StoreApi/Utilities/ProductQuery.php) --- ## woocommerce_apply_base_tax_for_local_pickup + + + ```php apply_filters( 'woocommerce_apply_base_tax_for_local_pickup' ) ``` ### Source -- [Shipping/ShippingController.php](../../../../src/Shipping/ShippingController.php) + + - [Shipping/ShippingController.php](../../../../src/Shipping/ShippingController.php) --- ## woocommerce_apply_individual_use_coupon + Filter coupons to remove when applying an individual use coupon. ```php apply_filters( 'woocommerce_apply_individual_use_coupon', array $coupons, \WC_Coupon $coupon, array $applied_coupons ) ``` + **Note: Matches filter name in WooCommerce core.** ### Parameters -| Argument | Type | Description | -| ---------------- | ---------- | ----------------------------------------------------- | -| $coupons | array | Array of coupons to remove from the cart. | -| $coupon | \WC_Coupon | Coupon object applied to the cart. | -| $applied_coupons | array | Array of applied coupons already applied to the cart. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $coupons | array | Array of coupons to remove from the cart. | +| $coupon | \WC_Coupon | Coupon object applied to the cart. | +| $applied_coupons | array | Array of applied coupons already applied to the cart. | ### Returns -`array` + +`array` ### Source -- [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) + + - [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) --- ## woocommerce_apply_with_individual_use_coupon + Filters if a coupon can be applied alongside other individual use coupons. ```php apply_filters( 'woocommerce_apply_with_individual_use_coupon', boolean $apply_with_individual_use_coupon, \WC_Coupon $coupon, \WC_Coupon $individual_use_coupon, array $applied_coupons ) ``` + **Note: Matches filter name in WooCommerce core.** ### Parameters -| Argument | Type | Description | -| --------------------------------- | ---------- | ----------------------------------------------------- | -| $apply_with_individual_use_coupon | boolean | Defaults to false. | -| $coupon | \WC_Coupon | Coupon object applied to the cart. | -| $individual_use_coupon | \WC_Coupon | Individual use coupon already applied to the cart. | -| $applied_coupons | array | Array of applied coupons already applied to the cart. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $apply_with_individual_use_coupon | boolean | Defaults to false. | +| $coupon | \WC_Coupon | Coupon object applied to the cart. | +| $individual_use_coupon | \WC_Coupon | Individual use coupon already applied to the cart. | +| $applied_coupons | array | Array of applied coupons already applied to the cart. | ### Returns -`boolean` + +`boolean` ### Source -- [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) + + - [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) --- ## woocommerce_blocks_hook_compatibility_additional_data + When extensions implement their equivalent blocks of the template hook functions, they can use this filter to register their old hooked data here, so in the blockified template, the old hooked functions can be removed in favor of the new blocks while keeping the old hooked functions working in classic templates. ```php @@ -407,18 +498,20 @@ apply_filters( 'woocommerce_blocks_hook_compatibility_additional_data', array $d ### Parameters -| Argument | Type | Description | -| -------- | ----- | ---------------------------------------- | -| $data | array | Additional hooked data. Default to empty | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $data | array | Additional hooked data. Default to empty | ### Source -- [Templates/AbstractTemplateCompatibility.php](../../../../src/Templates/AbstractTemplateCompatibility.php) + + - [Templates/AbstractTemplateCompatibility.php](../../../../src/Templates/AbstractTemplateCompatibility.php) --- ## woocommerce_blocks_product_grid_is_cacheable + Filters whether or not the product grid is cacheable. ```php @@ -427,23 +520,26 @@ apply_filters( 'woocommerce_blocks_product_grid_is_cacheable', boolean $is_cache ### Parameters -| Argument | Type | Description | -| ------------- | ------- | ---------------------------------------------------------- | -| $is_cacheable | boolean | The list of script dependencies. | -| $query_args | array | Query args for the products query passed to BlocksWpQuery. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $is_cacheable | boolean | The list of script dependencies. | +| $query_args | array | Query args for the products query passed to BlocksWpQuery. | ### Returns + `array` True to enable cache, false to disable cache. ### Source -- [BlockTypes/AbstractProductGrid.php](../../../../src/BlockTypes/AbstractProductGrid.php) + + - [BlockTypes/AbstractProductGrid.php](../../../../src/BlockTypes/AbstractProductGrid.php) --- ## woocommerce_blocks_product_grid_item_html + Filters the HTML for products in the grid. ```php @@ -452,24 +548,27 @@ apply_filters( 'woocommerce_blocks_product_grid_item_html', string $html, array ### Parameters -| Argument | Type | Description | -| -------- | ----------- | ------------------------------------ | -| $html | string | Product grid item HTML. | -| $data | array | Product data passed to the template. | -| $product | \WC_Product | Product object. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $html | string | Product grid item HTML. | +| $data | array | Product data passed to the template. | +| $product | \WC_Product | Product object. | ### Returns + `string` Updated product grid item HTML. ### Source -- [BlockTypes/AbstractProductGrid.php](../../../../src/BlockTypes/AbstractProductGrid.php) + + - [BlockTypes/AbstractProductGrid.php](../../../../src/BlockTypes/AbstractProductGrid.php) --- ## woocommerce_blocks_register_script_dependencies + Filters the list of script dependencies. ```php @@ -478,49 +577,84 @@ apply_filters( 'woocommerce_blocks_register_script_dependencies', array $depende ### Parameters -| Argument | Type | Description | -| ------------- | ------ | -------------------------------- | -| $dependencies | array | The list of script dependencies. | -| $handle | string | The script's handle. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $dependencies | array | The list of script dependencies. | +| $handle | string | The script's handle. | ### Returns -`array` + +`array` ### Source -- [Assets/Api.php](../../../../src/Assets/Api.php) + + - [Assets/Api.php](../../../../src/Assets/Api.php) --- ## woocommerce_cart_contents_changed + Filters the entire cart contents when the cart changes. ```php apply_filters( 'woocommerce_cart_contents_changed', array $cart_contents ) ``` + **Note: Matches filter name in WooCommerce core.** ### Parameters -| Argument | Type | Description | -| -------------- | ----- | ------------------------ | +| Argument | Type | Description | +| -------- | ---- | ----------- | | $cart_contents | array | Array of all cart items. | ### Returns + `array` Updated array of all cart items. ### Source -- [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) + + - [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) + +--- + +## woocommerce_cart_item_permalink + + +Filter the product permalink. + +```php +apply_filters( 'woocommerce_cart_item_permalink', string $product_permalink, array $cart_item, string $cart_item_key ) +``` + +### Description + +

This is a hook taken from the legacy cart/mini-cart templates that allows the permalink to be changed for a product. This is specific to the cart endpoint.

+ +### Parameters + +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $product_permalink | string | Product permalink. | +| $cart_item | array | Cart item array. | +| $cart_item_key | string | Cart item key. | + +### Source + + + - [StoreApi/Schemas/V1/CartItemSchema.php](../../../../src/StoreApi/Schemas/V1/CartItemSchema.php) --- ## woocommerce_disable_compatibility_layer + Filter to disable the compatibility layer for the blockified templates. ```php @@ -533,47 +667,53 @@ apply_filters( 'woocommerce_disable_compatibility_layer', \Automattic\WooCommerc ### Parameters -| Argument | Type | Description | -| -------- | ------------------------------------------------- | ----------- | -| 1 | \Automattic\WooCommerce\Blocks\Templates\boolean. | | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| 1 | \Automattic\WooCommerce\Blocks\Templates\boolean. | | ### Source -- [Templates/AbstractTemplateCompatibility.php](../../../../src/Templates/AbstractTemplateCompatibility.php) -- [Templates/AbstractTemplateCompatibility.php](../../../../src/Templates/AbstractTemplateCompatibility.php) + + - [Templates/AbstractTemplateCompatibility.php](../../../../src/Templates/AbstractTemplateCompatibility.php) + - [Templates/AbstractTemplateCompatibility.php](../../../../src/Templates/AbstractTemplateCompatibility.php) --- ## woocommerce_ga_disable_tracking + Filter to disable Google Analytics tracking. ```php apply_filters( 'woocommerce_ga_disable_tracking', boolean $disable_tracking ) ``` + **Note: Matches filter name in GA extension.** ### Parameters -| Argument | Type | Description | -| ----------------- | ------- | ----------------------------------- | +| Argument | Type | Description | +| -------- | ---- | ----------- | | $disable_tracking | boolean | If true, tracking will be disabled. | ### Source -- [Domain/Services/GoogleAnalytics.php](../../../../src/Domain/Services/GoogleAnalytics.php) + + - [Domain/Services/GoogleAnalytics.php](../../../../src/Domain/Services/GoogleAnalytics.php) --- ## woocommerce_get_item_data + Filters cart item data. ```php apply_filters( 'woocommerce_get_item_data', array $item_data, array $cart_item ) ``` + **Note: Matches filter name in WooCommerce core.** ### Description @@ -582,23 +722,26 @@ apply_filters( 'woocommerce_get_item_data', array $item_data, array $cart_item ) ### Parameters -| Argument | Type | Description | -| ---------- | ----- | --------------------------------- | +| Argument | Type | Description | +| -------- | ---- | ----------- | | $item_data | array | Cart item data. Empty by default. | -| $cart_item | array | Cart item array. | +| $cart_item | array | Cart item array. | ### Returns -`array` + +`array` ### Source -- [StoreApi/Schemas/V1/CartItemSchema.php](../../../../src/StoreApi/Schemas/V1/CartItemSchema.php) + + - [StoreApi/Schemas/V1/CartItemSchema.php](../../../../src/StoreApi/Schemas/V1/CartItemSchema.php) --- ## woocommerce_loop_add_to_cart_args + Allow filtering of the add to cart button arguments. ```php @@ -607,12 +750,14 @@ apply_filters( 'woocommerce_loop_add_to_cart_args' ) ### Source -- [BlockTypes/ProductButton.php](../../../../src/BlockTypes/ProductButton.php) + + - [BlockTypes/ProductButton.php](../../../../src/BlockTypes/ProductButton.php) --- ## woocommerce_loop_add_to_cart_link + Filters the add to cart button class. ```php @@ -621,18 +766,20 @@ apply_filters( 'woocommerce_loop_add_to_cart_link', string $class ) ### Parameters -| Argument | Type | Description | -| -------- | ------ | ----------- | -| $class | string | The class. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $class | string | The class. | ### Source -- [BlockTypes/ProductButton.php](../../../../src/BlockTypes/ProductButton.php) + + - [BlockTypes/ProductButton.php](../../../../src/BlockTypes/ProductButton.php) --- ## woocommerce_new_customer_data + Filters customer data before a customer account is registered. ```php @@ -645,28 +792,80 @@ apply_filters( 'woocommerce_new_customer_data', array $customer_data ) ### Parameters -| Argument | Type | Description | -| -------------- | ----- | --------------------------------- | +| Argument | Type | Description | +| -------- | ---- | ----------- | | $customer_data | array | An array of customer (user) data. | ### Returns -`array` + +`array` + +### Source + + + - [StoreApi/Routes/V1/Checkout.php](../../../../src/StoreApi/Routes/V1/Checkout.php) + +--- + +## woocommerce_pay_order_product_has_enough_stock + + +Filters whether or not the product has enough stock. + +```php +apply_filters( 'woocommerce_pay_order_product_has_enough_stock', boolean $argument0, \WC_Product $product, \WC_Order $order ) +``` + +### Parameters + +| Argument | Type | Description | +| -------- | ---- | ----------- | +| 1 | boolean | True if has enough stock. | +| $product | \WC_Product | Product. | +| $order | \WC_Order | Order. | + +### Source + + + - [StoreApi/Utilities/OrderController.php](../../../../src/StoreApi/Utilities/OrderController.php) + +--- + +## woocommerce_pay_order_product_in_stock + + +Filters whether or not the product is in stock for this pay for order. + +```php +apply_filters( 'woocommerce_pay_order_product_in_stock', boolean $argument0, \WC_Product $product, \WC_Order $order ) +``` + +### Parameters + +| Argument | Type | Description | +| -------- | ---- | ----------- | +| 1 | boolean | True if in stock. | +| $product | \WC_Product | Product. | +| $order | \WC_Order | Order. | ### Source -- [StoreApi/Routes/V1/Checkout.php](../../../../src/StoreApi/Routes/V1/Checkout.php) + + - [StoreApi/Utilities/OrderController.php](../../../../src/StoreApi/Utilities/OrderController.php) --- ## woocommerce_registration_errors + Filters registration errors before a customer account is registered. ```php apply_filters( 'woocommerce_registration_errors', \WP_Error $errors, string $username, string $user_email ) ``` + **Note: Matches filter name in WooCommerce core.** ### Description @@ -675,30 +874,34 @@ apply_filters( 'woocommerce_registration_errors', \WP_Error $errors, string $use ### Parameters -| Argument | Type | Description | -| ----------- | --------- | ----------------------- | -| $errors | \WP_Error | Error object. | -| $username | string | Customer username. | -| $user_email | string | Customer email address. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $errors | \WP_Error | Error object. | +| $username | string | Customer username. | +| $user_email | string | Customer email address. | ### Returns -`\WP_Error` + +`\WP_Error` ### Source -- [StoreApi/Routes/V1/Checkout.php](../../../../src/StoreApi/Routes/V1/Checkout.php) + + - [StoreApi/Routes/V1/Checkout.php](../../../../src/StoreApi/Routes/V1/Checkout.php) --- ## ~~woocommerce_shared_settings~~ + Filters the array of shared settings. ```php apply_filters( 'woocommerce_shared_settings', array $data ) ``` + **Deprecated: This hook is deprecated and will be removed** ### Description @@ -707,49 +910,58 @@ apply_filters( 'woocommerce_shared_settings', array $data ) ### Parameters -| Argument | Type | Description | -| -------- | ----- | -------------- | -| $data | array | Settings data. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $data | array | Settings data. | ### Returns -`array` + +`array` ### Source -- [Assets/AssetDataRegistry.php](../../../../src/Assets/AssetDataRegistry.php) + + - [Assets/AssetDataRegistry.php](../../../../src/Assets/AssetDataRegistry.php) --- ## woocommerce_shipping_package_name + Filters the shipping package name. ```php apply_filters( 'woocommerce_shipping_package_name', string $shipping_package_name, string $package_id, array $package ) ``` + **Note: Matches filter name in WooCommerce core.** ### Parameters -| Argument | Type | Description | -| ---------------------- | ------ | ---------------------------------- | -| $shipping_package_name | string | Shipping package name. | -| $package_id | string | Shipping package ID. | -| $package | array | Shipping package from WooCommerce. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $shipping_package_name | string | Shipping package name. | +| $package_id | string | Shipping package ID. | +| $package | array | Shipping package from WooCommerce. | ### Returns + `string` Shipping package name. ### Source -- [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) + + - [StoreApi/Utilities/CartController.php](../../../../src/StoreApi/Utilities/CartController.php) --- -## woocommerce*shipping*{$this->id}\_is_available +## woocommerce_shipping_{$this->id}_is_available + + + ```php apply_filters( 'woocommerce_shipping_{$this->id}_is_available' ) @@ -757,12 +969,14 @@ apply_filters( 'woocommerce_shipping_{$this->id}_is_available' ) ### Source -- [Shipping/PickupLocation.php](../../../../src/Shipping/PickupLocation.php) + + - [Shipping/PickupLocation.php](../../../../src/Shipping/PickupLocation.php) --- ## woocommerce_show_page_title + Hook: woocommerce_show_page_title ```php @@ -775,12 +989,37 @@ apply_filters( 'woocommerce_show_page_title' ) ### Source -- [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) + + - [BlockTypes/ClassicTemplate.php](../../../../src/BlockTypes/ClassicTemplate.php) + +--- + +## woocommerce_single_product_image_thumbnail_html + + +Filter the HTML markup for a single product image thumbnail in the gallery. + +```php +apply_filters( 'woocommerce_single_product_image_thumbnail_html', string $thumbnail_html, int $attachment_id ) +``` + +### Parameters + +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $thumbnail_html | string | The HTML markup for the thumbnail. | +| $attachment_id | int | The attachment ID of the thumbnail. | + +### Source + + + - [BlockTypes/ProductGalleryThumbnails.php](../../../../src/BlockTypes/ProductGalleryThumbnails.php) --- ## woocommerce_store_api_add_to_cart_data + Filters cart item data sent via the API before it is passed to the cart controller. ```php @@ -793,22 +1032,25 @@ apply_filters( 'woocommerce_store_api_add_to_cart_data', array $customer_data ) ### Parameters -| Argument | Type | Description | -| -------------- | ----- | --------------------------------- | +| Argument | Type | Description | +| -------- | ---- | ----------- | | $customer_data | array | An array of customer (user) data. | ### Returns -`array` + +`array` ### Source -- [StoreApi/Routes/V1/CartAddItem.php](../../../../src/StoreApi/Routes/V1/CartAddItem.php) + + - [StoreApi/Routes/V1/CartAddItem.php](../../../../src/StoreApi/Routes/V1/CartAddItem.php) --- ## woocommerce_store_api_disable_nonce_check + Filters the Store API nonce check. ```php @@ -821,22 +1063,25 @@ apply_filters( 'woocommerce_store_api_disable_nonce_check', boolean $disable_non ### Parameters -| Argument | Type | Description | -| -------------------- | ------- | --------------------------------------- | +| Argument | Type | Description | +| -------- | ---- | ----------- | | $disable_nonce_check | boolean | If true, nonce checks will be disabled. | ### Returns -`boolean` + +`boolean` ### Source -- [StoreApi/Routes/V1/AbstractCartRoute.php](../../../../src/StoreApi/Routes/V1/AbstractCartRoute.php) + + - [StoreApi/Routes/V1/AbstractCartRoute.php](../../../../src/StoreApi/Routes/V1/AbstractCartRoute.php) --- ## woocommerce_store_api_product_quantity_limit + Filters the quantity limit for a product being added to the cart via the Store API. ```php @@ -849,22 +1094,25 @@ apply_filters( 'woocommerce_store_api_product_quantity_limit', integer $quantity ### Parameters -| Argument | Type | Description | -| --------------- | ----------- | --------------------------------------------------------------- | -| $quantity_limit | integer | Quantity limit which defaults to 9999 unless sold individually. | -| $product | \WC_Product | Product instance. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $quantity_limit | integer | Quantity limit which defaults to 9999 unless sold individually. | +| $product | \WC_Product | Product instance. | ### Returns -`integer` + +`integer` ### Source -- [StoreApi/Utilities/QuantityLimits.php](../../../../src/StoreApi/Utilities/QuantityLimits.php) + + - [StoreApi/Utilities/QuantityLimits.php](../../../../src/StoreApi/Utilities/QuantityLimits.php) --- -## woocommerce*store_api_product_quantity*{$value_type} +## woocommerce_store_api_product_quantity_{$value_type} + Filters the quantity minimum for a cart item in Store API. This allows extensions to control the minimum qty of items already within the cart. @@ -878,24 +1126,27 @@ apply_filters( 'woocommerce_store_api_product_quantity_{$value_type}', mixed $va ### Parameters -| Argument | Type | Description | -| ---------- | ----------- | --------------------------------------------------------- | -| $value | mixed | The value being filtered. | -| $product | \WC_Product | The product object. | +| Argument | Type | Description | +| -------- | ---- | ----------- | +| $value | mixed | The value being filtered. | +| $product | \WC_Product | The product object. | | $cart_item | array, null | The cart item if the product exists in the cart, or null. | ### Returns -`mixed` + +`mixed` ### Source -- [StoreApi/Utilities/QuantityLimits.php](../../../../src/StoreApi/Utilities/QuantityLimits.php) + + - [StoreApi/Utilities/QuantityLimits.php](../../../../src/StoreApi/Utilities/QuantityLimits.php) --- ## woocommerce_store_api_rate_limit_options + Filters options for Rate Limits. ```php @@ -904,53 +1155,21 @@ apply_filters( 'woocommerce_store_api_rate_limit_options', array $rate_limit_opt ### Parameters -| Argument | Type | Description | -| ------------------- | ----- | ----------------------- | +| Argument | Type | Description | +| -------- | ---- | ----------- | | $rate_limit_options | array | Array of option values. | ### Returns -`array` - -### Source - -- [StoreApi/Utilities/RateLimits.php](../../../../src/StoreApi/Utilities/RateLimits.php) - ---- - -## woocommerce_variation_option_name - -Filters the variation option name. - -```php -apply_filters( 'woocommerce_variation_option_name', string $value, null $unused, string $taxonomy, \WC_Product $product ) -``` - -**Note: Matches filter name in WooCommerce core.** - -### Description - -

Filters the variation option name for custom option slugs.

- -### Parameters - -| Argument | Type | Description | -| --------- | ----------- | ------------------------------------------------ | -| $value | string | The name to display. | -| $unused | null | Unused because this is not a variation taxonomy. | -| $taxonomy | string | Taxonomy or product attribute name. | -| $product | \WC_Product | Product data. | - -### Returns -`string` +`array` ### Source -- [StoreApi/Schemas/V1/CartItemSchema.php](../../../../src/StoreApi/Schemas/V1/CartItemSchema.php) ---- + - [StoreApi/Utilities/RateLimits.php](../../../../src/StoreApi/Utilities/RateLimits.php) +--- --- @@ -960,3 +1179,4 @@ apply_filters( 'woocommerce_variation_option_name', string $value, null $unused, 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/hooks/filters.md) + diff --git a/docs/third-party-developers/extensibility/rest-api/available-endpoints-to-extend.md b/docs/third-party-developers/extensibility/rest-api/available-endpoints-to-extend.md index a4cc473f14f..c41ed73fb1d 100644 --- a/docs/third-party-developers/extensibility/rest-api/available-endpoints-to-extend.md +++ b/docs/third-party-developers/extensibility/rest-api/available-endpoints-to-extend.md @@ -80,3 +80,4 @@ The main products endpoint is extensible via ExtendSchema. The data is available 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/rest-api/available-endpoints-to-extend.md) + diff --git a/docs/third-party-developers/extensibility/rest-api/extend-rest-api-add-data.md b/docs/third-party-developers/extensibility/rest-api/extend-rest-api-add-data.md index 69ce0b5ea65..ef9abeb3577 100644 --- a/docs/third-party-developers/extensibility/rest-api/extend-rest-api-add-data.md +++ b/docs/third-party-developers/extensibility/rest-api/extend-rest-api-add-data.md @@ -337,3 +337,4 @@ You may wish to use our pre-existing Formatters to ensure your data is passed th 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/rest-api/extend-rest-api-add-data.md) + diff --git a/docs/third-party-developers/extensibility/rest-api/extend-rest-api-formatters.md b/docs/third-party-developers/extensibility/rest-api/extend-rest-api-formatters.md index ab6c9075382..4f95abb85b8 100644 --- a/docs/third-party-developers/extensibility/rest-api/extend-rest-api-formatters.md +++ b/docs/third-party-developers/extensibility/rest-api/extend-rest-api-formatters.md @@ -142,3 +142,4 @@ alert('bad script!') This “coffee” is very strong. 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/rest-api/extend-rest-api-formatters.md) + diff --git a/docs/third-party-developers/extensibility/rest-api/extend-rest-api-new-endpoint.md b/docs/third-party-developers/extensibility/rest-api/extend-rest-api-new-endpoint.md index 16ed49f5818..b715a1dda9f 100644 --- a/docs/third-party-developers/extensibility/rest-api/extend-rest-api-new-endpoint.md +++ b/docs/third-party-developers/extensibility/rest-api/extend-rest-api-new-endpoint.md @@ -49,3 +49,4 @@ Extending a new endpoint is usually half the work, you will need to receive this 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/rest-api/extend-rest-api-new-endpoint.md) + diff --git a/docs/third-party-developers/extensibility/rest-api/extend-rest-api-update-cart.md b/docs/third-party-developers/extensibility/rest-api/extend-rest-api-update-cart.md index b62d59cb13b..b2944d6e012 100644 --- a/docs/third-party-developers/extensibility/rest-api/extend-rest-api-update-cart.md +++ b/docs/third-party-developers/extensibility/rest-api/extend-rest-api-update-cart.md @@ -192,3 +192,4 @@ Now that this is registered, when the button is pressed, the `cart/extensions` e 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./docs/third-party-developers/extensibility/rest-api/extend-rest-api-update-cart.md) + diff --git a/images/pattern-placeholders/crafting-pots.png b/images/pattern-placeholders/crafting-pots.png new file mode 100644 index 00000000000..2846b25919f Binary files /dev/null and b/images/pattern-placeholders/crafting-pots.png differ diff --git a/images/pattern-placeholders/hand-made-pots.png b/images/pattern-placeholders/hand-made-pots.png new file mode 100644 index 00000000000..e380d933618 Binary files /dev/null and b/images/pattern-placeholders/hand-made-pots.png differ diff --git a/package-lock.json b/package-lock.json index 351f91268d4..5088a4b4787 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@woocommerce/block-library", - "version": "10.9.0-dev", + "version": "11.0.0-dev", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@woocommerce/block-library", - "version": "10.9.0-dev", + "version": "11.0.0-dev", "hasInstallScript": true, "license": "GPL-3.0+", "dependencies": { @@ -115,7 +115,7 @@ "@wordpress/dependency-extraction-webpack-plugin": "3.2.1", "@wordpress/dom": "3.27.0", "@wordpress/e2e-test-utils": "10.1.0", - "@wordpress/e2e-test-utils-playwright": "https://github.com/woocommerce/woocommerce-blocks/files/11286971/wordpress-e2e-test-utils-playwright-0.0.0.tgz", + "@wordpress/e2e-test-utils-playwright": "0.6.0", "@wordpress/e2e-tests": "^4.6.0", "@wordpress/element": "4.20.0", "@wordpress/env": "7.0.0", @@ -126,6 +126,7 @@ "@wordpress/scripts": "24.6.0", "autoprefixer": "10.4.14", "axios": "0.27.2", + "babel-jest": "^29.6.2", "babel-plugin-explicit-exports-references": "^1.0.2", "babel-plugin-react-docgen": "4.2.1", "babel-plugin-transform-async-generator-functions": "6.24.1", @@ -15391,9 +15392,9 @@ } }, "node_modules/@wordpress/e2e-test-utils-playwright": { - "version": "0.0.0", - "resolved": "https://github.com/woocommerce/woocommerce-blocks/files/11286971/wordpress-e2e-test-utils-playwright-0.0.0.tgz", - "integrity": "sha512-BLtq8Vcsyxbac1d8I+klE2Zrhbso3DJ2YTRl3ZmZ6KMiIiYWCvPLLIbtYAWiIDy6NU2jiT1wLlJ4G4jyV3DhIQ==", + "version": "0.6.0", + "resolved": "https://github.com/woocommerce/woocommerce-blocks/files/12309320/wordpress-e2e-test-utils-playwright-0.6.0.tgz", + "integrity": "sha512-5lo8iRuRfUOAPMRsQteSkKyMoP1IHHu6GKye8Df+YEPz1LWXcS6YRFGI3HrONBpcaHLrJC7LVav4UdB/sBPqUw==", "dev": true, "license": "GPL-2.0-or-later", "dependencies": { @@ -16127,6 +16128,68 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@wordpress/e2e-tests/node_modules/babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "dev": true, + "dependencies": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/@wordpress/e2e-tests/node_modules/babel-jest/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/e2e-tests/node_modules/babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@wordpress/e2e-tests/node_modules/babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@wordpress/e2e-tests/node_modules/ci-info": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", @@ -17389,6 +17452,68 @@ "react-dom": "^17.0.0" } }, + "node_modules/@wordpress/jest-preset-default/node_modules/babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "dev": true, + "dependencies": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/@wordpress/jest-preset-default/node_modules/babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@wordpress/jest-preset-default/node_modules/babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@wordpress/jest-preset-default/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/@wordpress/jest-puppeteer-axe": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@wordpress/jest-puppeteer-axe/-/jest-puppeteer-axe-4.0.2.tgz", @@ -18297,6 +18422,68 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@wordpress/scripts/node_modules/babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "dev": true, + "dependencies": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/@wordpress/scripts/node_modules/babel-jest/node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@wordpress/scripts/node_modules/babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@wordpress/scripts/node_modules/babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/@wordpress/scripts/node_modules/ci-info": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", @@ -21004,27 +21191,150 @@ } }, "node_modules/babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.2.tgz", + "integrity": "sha512-BYCzImLos6J3BH/+HvUCHG1dTf2MzmAB4jaVxHV+29RZLjR29XuYTmsf2sdDwkrb+FczkGo3kOhE7ga6sI0P4A==", "dev": true, "dependencies": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", + "@jest/transform": "^29.6.2", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", + "babel-preset-jest": "^29.5.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "@babel/core": "^7.8.0" } }, + "node_modules/babel-jest/node_modules/@jest/transform": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.6.2.tgz", + "integrity": "sha512-ZqCqEISr58Ce3U+buNFJYUktLJZOggfyvR+bZMaiV1e8B1SIvJbwZMrYz3gx/KAPn9EXmOmN+uB08yLCjWkQQg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.1", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.2", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.6.2", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-jest/node_modules/@jest/types": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.1.tgz", + "integrity": "sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.6.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-jest/node_modules/@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/babel-jest/node_modules/ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/babel-jest/node_modules/jest-haste-map": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.6.2.tgz", + "integrity": "sha512-+51XleTDAAysvU8rT6AnS1ZJ+WHVNqhj1k6nTvN2PYP+HjU3kqlaKQ1Lnw3NYW3bm2r8vq82X0Z1nDDHZMzHVA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.1", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.6.2", + "jest-worker": "^29.6.2", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/babel-jest/node_modules/jest-regex-util": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-jest/node_modules/jest-util": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.2.tgz", + "integrity": "sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w==", + "dev": true, + "dependencies": { + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/babel-jest/node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -21034,6 +21344,19 @@ "node": ">=8" } }, + "node_modules/babel-jest/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/babel-loader": { "version": "8.2.5", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.5.tgz", @@ -21265,18 +21588,18 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", + "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", "dev": true, "dependencies": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", + "@types/babel__core": "^7.1.14", "@types/babel__traverse": "^7.0.6" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/babel-plugin-macros": { @@ -21498,16 +21821,16 @@ } }, "node_modules/babel-preset-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", + "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^27.5.1", + "babel-plugin-jest-hoist": "^29.5.0", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -33616,6 +33939,59 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/jest-cli/node_modules/babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "dev": true, + "dependencies": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/jest-cli/node_modules/babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-cli/node_modules/babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, "node_modules/jest-cli/node_modules/ci-info": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.1.tgz", @@ -34225,58 +34601,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-config/node_modules/babel-jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", - "integrity": "sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==", - "dev": true, - "dependencies": { - "@jest/transform": "^29.5.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.5.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/jest-config/node_modules/babel-plugin-jest-hoist": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", - "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", - "dev": true, - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-config/node_modules/babel-preset-jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", - "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", - "dev": true, - "dependencies": { - "babel-plugin-jest-hoist": "^29.5.0", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, "node_modules/jest-config/node_modules/ci-info": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", @@ -36677,13 +37001,13 @@ } }, "node_modules/jest-worker": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", - "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.6.2.tgz", + "integrity": "sha512-l3ccBOabTdkng8I/ORCkADz4eSMKejTYv1vB/Z83UiubqhC1oQ5Li6dWCyqOIvSifGjUBxuvxvlm6KGK2DtuAQ==", "dev": true, "dependencies": { "@types/node": "*", - "jest-util": "^29.5.0", + "jest-util": "^29.6.2", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -36692,12 +37016,12 @@ } }, "node_modules/jest-worker/node_modules/@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.1.tgz", + "integrity": "sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.0", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -36733,12 +37057,12 @@ } }, "node_modules/jest-worker/node_modules/jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.2.tgz", + "integrity": "sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.1", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -65605,8 +65929,9 @@ } }, "@wordpress/e2e-test-utils-playwright": { - "version": "https://github.com/woocommerce/woocommerce-blocks/files/11286971/wordpress-e2e-test-utils-playwright-0.0.0.tgz", - "integrity": "sha512-BLtq8Vcsyxbac1d8I+klE2Zrhbso3DJ2YTRl3ZmZ6KMiIiYWCvPLLIbtYAWiIDy6NU2jiT1wLlJ4G4jyV3DhIQ==", + "version": "0.6.0", + "resolved": "https://github.com/woocommerce/woocommerce-blocks/files/12309320/wordpress-e2e-test-utils-playwright-0.6.0.tgz", + "integrity": "sha512-5lo8iRuRfUOAPMRsQteSkKyMoP1IHHu6GKye8Df+YEPz1LWXcS6YRFGI3HrONBpcaHLrJC7LVav4UdB/sBPqUw==", "dev": true, "requires": { "@wordpress/api-fetch": "file:../api-fetch", @@ -66177,6 +66502,52 @@ "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==", "dev": true }, + "babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "dev": true, + "requires": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "dependencies": { + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + } + } + }, + "babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, "ci-info": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", @@ -67058,6 +67429,52 @@ "babel-jest": "^27.4.5", "enzyme": "^3.11.0", "enzyme-to-json": "^3.4.4" + }, + "dependencies": { + "babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "dev": true, + "requires": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + } } }, "@wordpress/jest-puppeteer-axe": { @@ -67760,6 +68177,52 @@ "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==", "dev": true }, + "babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "dev": true, + "requires": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "dependencies": { + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + } + } + }, + "babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, "ci-info": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", @@ -69790,26 +70253,133 @@ } }, "babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.6.2.tgz", + "integrity": "sha512-BYCzImLos6J3BH/+HvUCHG1dTf2MzmAB4jaVxHV+29RZLjR29XuYTmsf2sdDwkrb+FczkGo3kOhE7ga6sI0P4A==", "dev": true, "requires": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", + "@jest/transform": "^29.6.2", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", + "babel-preset-jest": "^29.5.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" }, "dependencies": { + "@jest/transform": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.6.2.tgz", + "integrity": "sha512-ZqCqEISr58Ce3U+buNFJYUktLJZOggfyvR+bZMaiV1e8B1SIvJbwZMrYz3gx/KAPn9EXmOmN+uB08yLCjWkQQg==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.1", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.6.2", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.6.2", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + } + }, + "@jest/types": { + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.1.tgz", + "integrity": "sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.6.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true + }, + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "jest-haste-map": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.6.2.tgz", + "integrity": "sha512-+51XleTDAAysvU8rT6AnS1ZJ+WHVNqhj1k6nTvN2PYP+HjU3kqlaKQ1Lnw3NYW3bm2r8vq82X0Z1nDDHZMzHVA==", + "dev": true, + "requires": { + "@jest/types": "^29.6.1", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.6.2", + "jest-worker": "^29.6.2", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + } + }, + "jest-regex-util": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", + "dev": true + }, + "jest-util": { + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.2.tgz", + "integrity": "sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w==", + "dev": true, + "requires": { + "@jest/types": "^29.6.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true + }, + "write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } } } }, @@ -69989,14 +70559,14 @@ } }, "babel-plugin-jest-hoist": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", + "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", "dev": true, "requires": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", + "@types/babel__core": "^7.1.14", "@types/babel__traverse": "^7.0.6" } }, @@ -70199,12 +70769,12 @@ } }, "babel-preset-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", + "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^27.5.1", + "babel-plugin-jest-hoist": "^29.5.0", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -79547,6 +80117,44 @@ "jest-runtime": "^27.5.1" } }, + "babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "dev": true, + "requires": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, "ci-info": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.1.tgz", @@ -80017,43 +80625,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true }, - "babel-jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", - "integrity": "sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==", - "dev": true, - "requires": { - "@jest/transform": "^29.5.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.5.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", - "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", - "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^29.5.0", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, "ci-info": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", @@ -81974,24 +82545,24 @@ } }, "jest-worker": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", - "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.6.2.tgz", + "integrity": "sha512-l3ccBOabTdkng8I/ORCkADz4eSMKejTYv1vB/Z83UiubqhC1oQ5Li6dWCyqOIvSifGjUBxuvxvlm6KGK2DtuAQ==", "dev": true, "requires": { "@types/node": "*", - "jest-util": "^29.5.0", + "jest-util": "^29.6.2", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, "dependencies": { "@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", + "version": "29.6.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.1.tgz", + "integrity": "sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw==", "dev": true, "requires": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.0", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -82015,12 +82586,12 @@ "dev": true }, "jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", + "version": "29.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.2.tgz", + "integrity": "sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w==", "dev": true, "requires": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.1", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", diff --git a/package.json b/package.json index f4da41e4d29..3b3547fafb7 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@woocommerce/block-library", "title": "WooCommerce Blocks", "author": "Automattic", - "version": "10.9.0-dev", + "version": "11.0.0-dev", "description": "WooCommerce blocks for the Gutenberg editor.", "homepage": "https://github.com/woocommerce/woocommerce-gutenberg-products-block/", "keywords": [ @@ -81,6 +81,8 @@ "test:debug": "ndb .", "test:e2e": "sh ./bin/check-env.sh && npx playwright test --config=tests/e2e/playwright.config.ts", "test:e2e:report": "sh ./bin/check-env.sh && npx playwright test --config=tests/e2e/playwright.config.ts --reporter=html", + "test:e2e:side-effects": "npm run test:e2e -- --config=tests/e2e/playwright.side-effects.config.ts", + "test:e2e:side-effects:report": "npm run test:e2e:report -- --config=tests/e2e/playwright.side-effects.config.ts", "test:e2e:jest": "npm run wp-env:config && cross-env JEST_PUPPETEER_CONFIG=tests/e2e-jest/config/jest-puppeteer.config.js NODE_CONFIG_DIR=tests/e2e-jest/config wp-scripts test-e2e --config tests/e2e-jest/config/jest.config.js", "test:e2e:jest:dev": "npm run wp-env:config && cross-env JEST_PUPPETEER_CONFIG=tests/e2e-jest/config/jest-puppeteer.config-dev.js NODE_CONFIG_DIR=tests/e2e-jest/config wp-scripts test-e2e --config tests/e2e-jest/config/jest.config.js", "test:e2e:jest:dev-watch": "npm run wp-env:config && cross-env JEST_PUPPETEER_CONFIG=tests/e2e-jest/config/jest-puppeteer.config-dev.js NODE_CONFIG_DIR=tests/e2e-jest/config wp-scripts test-e2e --config tests/e2e-jest/config/jest.config.js --watch", @@ -164,7 +166,7 @@ "@wordpress/dependency-extraction-webpack-plugin": "3.2.1", "@wordpress/dom": "3.27.0", "@wordpress/e2e-test-utils": "10.1.0", - "@wordpress/e2e-test-utils-playwright": "https://github.com/woocommerce/woocommerce-blocks/files/11286971/wordpress-e2e-test-utils-playwright-0.0.0.tgz", + "@wordpress/e2e-test-utils-playwright": "0.6.0", "@wordpress/e2e-tests": "^4.6.0", "@wordpress/element": "4.20.0", "@wordpress/env": "7.0.0", @@ -175,6 +177,7 @@ "@wordpress/scripts": "24.6.0", "autoprefixer": "10.4.14", "axios": "0.27.2", + "babel-jest": "^29.6.2", "babel-plugin-explicit-exports-references": "^1.0.2", "babel-plugin-react-docgen": "4.2.1", "babel-plugin-transform-async-generator-functions": "6.24.1", diff --git a/packages/checkout/README.md b/packages/checkout/README.md index 499529bfb46..e2ccb2596af 100644 --- a/packages/checkout/README.md +++ b/packages/checkout/README.md @@ -62,3 +62,4 @@ This package contains the following directories. Navigate to a directory for mor 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./packages/checkout/README.md) + diff --git a/packages/checkout/blocks-registry/README.md b/packages/checkout/blocks-registry/README.md index 81c6f92da84..e93911ba639 100644 --- a/packages/checkout/blocks-registry/README.md +++ b/packages/checkout/blocks-registry/README.md @@ -212,3 +212,4 @@ const isValid = hasInnerBlocks( 'woocommerce/checkout-totals-block' ); // true 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./packages/checkout/blocks-registry/README.md) + diff --git a/packages/checkout/components/README.md b/packages/checkout/components/README.md index f66beaf0a03..305ebeb1946 100644 --- a/packages/checkout/components/README.md +++ b/packages/checkout/components/README.md @@ -29,3 +29,4 @@ These components are here so they can be consumed by extensions. 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./packages/checkout/components/README.md) + diff --git a/packages/checkout/filter-registry/README.md b/packages/checkout/filter-registry/README.md index 7359e271769..1045d9d025f 100644 --- a/packages/checkout/filter-registry/README.md +++ b/packages/checkout/filter-registry/README.md @@ -132,3 +132,4 @@ Filters are implemented throughout the Mini-Cart, Cart and Checkout Blocks, as w 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./packages/checkout/filter-registry/README.md) + diff --git a/packages/checkout/slot/README.md b/packages/checkout/slot/README.md index df513cb2e39..eeb677b95e0 100644 --- a/packages/checkout/slot/README.md +++ b/packages/checkout/slot/README.md @@ -192,3 +192,4 @@ Slot Fills are implemented throughout the Cart and Checkout Blocks, as well as s 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./packages/checkout/slot/README.md) + diff --git a/packages/checkout/utils/README.md b/packages/checkout/utils/README.md index d2693b8843b..e4735267082 100644 --- a/packages/checkout/utils/README.md +++ b/packages/checkout/utils/README.md @@ -81,3 +81,4 @@ What value must contain. If this is not found within `value`, and error will be 🐞 Found a mistake, or have a suggestion? [Leave feedback about this document here.](https://github.com/woocommerce/woocommerce-blocks/issues/new?assignees=&labels=type%3A+documentation&template=--doc-feedback.md&title=Feedback%20on%20./packages/checkout/utils/README.md) + diff --git a/patterns/featured-products-5-cols.php b/patterns/featured-products-5-cols.php index e793722a0f9..ae9556245bf 100644 --- a/patterns/featured-products-5-cols.php +++ b/patterns/featured-products-5-cols.php @@ -12,7 +12,7 @@ - +
diff --git a/patterns/footer-large-dark.php b/patterns/footer-large-dark.php index 78243738bbc..27780e60f98 100644 --- a/patterns/footer-large-dark.php +++ b/patterns/footer-large-dark.php @@ -7,10 +7,8 @@ */ ?> - -