Merge branch 'trunk' into feature/marketplace-subscriptions

This commit is contained in:
Bero 2023-09-28 20:50:42 +02:00
commit 2f3d4b163e
246 changed files with 5472 additions and 1851 deletions

View File

@ -26,11 +26,10 @@ jobs:
- name: Get Changed Files
id: changed-files
uses: tj-actions/changed-files@v32
uses: tj-actions/changed-files@v39
with:
path: plugins/woocommerce
files: |
**/*.php
files: "**/*.php"
- name: Setup WooCommerce Monorepo
if: steps.changed-files.outputs.any_changed == 'true'
@ -49,7 +48,4 @@ jobs:
- name: Run PHPCS
if: steps.changed-files.outputs.any_changed == 'true'
working-directory: plugins/woocommerce
run: |
HEAD_REF=$(git rev-parse HEAD)
git checkout $HEAD_REF
phpcs-changed -s --git --git-base ${{ github.base_ref }} ${{ steps.changed-files.outputs.all_changed_files }}
run: phpcs-changed -s --git --git-base ${{ github.event.pull_request.base.sha }} ${{ steps.changed-files.outputs.all_changed_files }}

View File

@ -7,8 +7,6 @@ permissions: {}
jobs:
stale:
if: |
! contains(github.event.issue.labels.*.name, 'type: enhancement')
runs-on: ubuntu-20.04
permissions:
contents: read
@ -25,6 +23,7 @@ jobs:
days-before-pr-close: -1
stale-issue-label: 'status: stale'
stale-pr-label: 'status: stale'
exempt-issue-labels: 'type: enhancement'
only-issue-labels: 'needs: author feedback'
close-issue-label: "status: can't reproduce"
ascending: true

View File

@ -3,6 +3,7 @@
"MD003": { "style": "atx" },
"MD007": { "indent": 4 },
"MD013": { "line_length": 9999 },
"MD024": { "allow_different_nesting": true },
"no-hard-tabs": false,
"whitespace": false
}

View File

@ -118,6 +118,7 @@
"@wordpress/edit-site"
],
"packages": [
"@woocommerce/block-templates",
"@woocommerce/product-editor",
"woocommerce/client/admin",
"@woocommerce/components"

View File

@ -0,0 +1,35 @@
# How to decide if a Pull Request is High-Impact
Deciding if a Pull Request should be declared High-Impact is a complex task. To achieve it, we need to assess and estimate the impact that the changes introduced in the Pull Request have in WooCommerce, which is usually a subjective task and sometimes inaccurate, due to the huge knowledge it demands of the WooCommerce product details, technical details and even customers issues history.
On this page, we will share some guidelines to help you assess the impact degree of a Pull Request.
## You should mark a Pull Request as High-Impact if
- It adds a **new feature** to WooCommerce, except if it's behind a feature flag.
- Modifies **critical functionality** (see the [critical flows list](https://github.com/woocommerce/woocommerce/wiki/Critical-Flows)).
- It fixes a **high-priority bug** (this includes Blocks fix releases core version bumps).
- It contains a **security fix**.
- Updates **SQL queries**.
- Touches any of the **$_REQUEST** family of variables.
- Any kind of **data migration/update**.
- Changes to **emails** sent from WooCommerce.
- Changes to WooCommerce **hooks/actions/filters**.
- Changes to **REST API endpoints**.
- It's a **big PR** (i.e. adds several changes in many files).
- It has **i18n changes** (for example, any file from `woocommerce/i18n` is modified).
## You should not mark a Pull Request as High-Impact if
- It only updates automated tests, things related to infrastructure not included in the WooCommerce release package, or other projects in the monorepo not included in the release package.
- It only contains readme or changelog changes.
- Fixes a low-priority bug such as a typo etc.
- Doesnt need to be verified in multiple environment types.
- Regular scheduled (not a fix release) core version bumps for the Blocks package (as testing will already be scheduled).
- It's part of a feature that hasn't been released as a whole yet (i.e. it's behind a feature flag currently in progress).
## My PR is High-Impact. What's next?
If your PR is High-Impact, be sure to label it with `needs: analysis` so that it can get reviewed. If you don't have permission to add labels, please make sure that the **PR reviewers do it**.
Once the PR labelled as `needs: analysis` is reviewed, it will get added the `impact: high` label if it qualifies for High-Impact and the WooCommerce Core team will keep special considerations for testing it.

View File

@ -0,0 +1,18 @@
# Developing extensions for the product editor
> ⚠️ **Notice:** This documentation is currently a **work in progress**. Please be aware that some sections might be incomplete or subject to change. We appreciate your patience and welcome any contributions!
This handbook is a guide for extension developers looking to add support for the new product editor in their extensions. The product editor uses [Gutenberg's Block Editor](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-editor), which is going to help WooCommerce evolve alongside the WordPress ecosystem.
The product editor's UI consists of Groups (currently rendered as tabs), Sections, and Fields, which are all blocks.
![Product editor structure](https://woocommerce.files.wordpress.com/2023/09/groups-sections-fields.jpg)
The form's structure is defined in PHP using a Template. The template can be modified by using the Block Template API to add new Groups, Sections, and Fields as well as remove existing ones.
Many extensibility implementations can be done using only the PHP-based Block Template API. More complex interactivity can be implemented using JavaScript and React (the same library used to implement the core blocks used in the product editor). [@woocommerce/create-product-editor-block](../../packages/js/create-product-editor-block/README.md) can help scaffold a development environment with JavaScript and React.
## Index
- [Common tasks](common-tasks.md)

View File

@ -0,0 +1,34 @@
# Common tasks
> ⚠️ **Notice:** This documentation is currently a **work in progress**. Please be aware that some sections might be incomplete or subject to change. We appreciate your patience and welcome any contributions!
## Adding a group/section/field next to an existing one
Here's a snippet that adds a new block to the catalog section, between the first and second fields (order 15):
```php
use Automattic\WooCommerce\Admin\BlockTemplates\BlockInterface;
if ( ! function_exists( 'YOUR_PREFIX_add_block_after_categories' ) ) {
/**
* Add a new block to the template.
*/
function YOUR_PREFIX_add_block_after_categories( BlockInterface $product_categories_field ) {
$product_categories_field->get_parent()->add_block(
[
'id' => 'your-prefix-id',
'blockName' => 'woocommerce/product-checkbox-field',
'order' => $product_categories_field->get_order() + 5,
'attributes' => [
'label' => 'Your Checkbox',
'property' => 'your_checkbox_bool_property',
],
]
);
}
}
add_action( 'woocommerce_block_template_area_product-form_after_add_block_product-categories', 'YOUR_PREFIX_add_block_after_categories' );
```
Result:
![Adding field next to other field](https://woocommerce.files.wordpress.com/2023/09/adding-field-next-to-other-field.png)

View File

@ -0,0 +1,12 @@
module.exports = {
extends: [ 'plugin:@woocommerce/eslint-plugin/recommended' ],
root: true,
overrides: [
{
files: [ '**/*.js', '**/*.jsx', '**/*.tsx' ],
rules: {
'react/react-in-jsx-scope': 'off',
},
},
],
};

View File

@ -0,0 +1 @@
package-lock=false

View File

@ -0,0 +1,70 @@
# @woocommerce/block-templates
A collection of utility functions for use with WooCommerce admin block templates.
## API
### registerWooBlockType
Registers a WooCommerce block type.
#### Usage
```js
import { registerWooBlockType } from '@woocommerce/block-templates';
import metadata from './block.json';
import { Edit } from './edit';
registerWooBlockType( {
name: metadata.name,
metadata: metadata,
settings: {
edit: Edit,
}
} );
```
#### Parameters
- _blockMetadata_ `Object`: Block metadata.
#### Returns
- `WPBlockType | undefined`: The block type if it was registered successfully, otherwise `undefined`.
### useWooBlockProps
This hook is used to lightly mark an element as a WooCommerce block template block. The block's attributes must be passed to this hook and the return result passed to the outermost element of the block in order for the block to properly function in WooCommerce block template contexts.
If you define a ref for the element, it is important to pass the ref to this hook, which the hook in turn will pass to the component through the props it returns. Optionally, you can also pass any other props through this hook, and they will be merged and returned.
#### Usage
```js
import { useWooBlockProps } from '@woocommerce/block-templates';
export function Edit( { attributes } ) {
const { blockProps } = useWooBlockProps(
attributes,
{
className: 'my-block',
}
);
return (
<div { ...blockProps }>
Block content
</div>
);
}
```
#### Parameters
- _attributes_: `Object`: Block attributes.
- _props_: `Object`: Optional. Props to pass to the element.
#### Returns
- `Object`: Props to pass to the element to mark as a WooCommerce block.

View File

@ -0,0 +1,3 @@
module.exports = {
extends: '../internal-js-tests/babel.config.js',
};

View File

@ -0,0 +1,3 @@
# Changelog
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Initial version of @woocommerce/block-templates package. Adds registerWooBlockType and useWooBlockProps.

View File

@ -0,0 +1,32 @@
{
"name": "woocommerce/block-templates",
"description": "WooCommerce Admin block templates component library",
"type": "library",
"license": "GPL-3.0-or-later",
"minimum-stability": "dev",
"require-dev": {
"automattic/jetpack-changelogger": "3.3.0"
},
"config": {
"platform": {
"php": "7.2"
}
},
"extra": {
"changelogger": {
"formatter": {
"filename": "../../../tools/changelogger/class-package-formatter.php"
},
"types": {
"fix": "Fixes an existing bug",
"add": "Adds functionality",
"update": "Update existing functionality",
"dev": "Development related task",
"tweak": "A minor adjustment to the codebase",
"performance": "Address performance issues",
"enhancement": "Improve existing functionality"
},
"changelog": "CHANGELOG.md"
}
}
}

483
packages/js/block-templates/composer.lock generated Normal file
View File

@ -0,0 +1,483 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "2d316cec186ab12385e8dda54f6df0f6",
"packages": [],
"packages-dev": [
{
"name": "automattic/jetpack-changelogger",
"version": "v3.3.0",
"source": {
"type": "git",
"url": "https://github.com/Automattic/jetpack-changelogger.git",
"reference": "8f63c829b8d1b0d7b1d5de93510d78523ed18959"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Automattic/jetpack-changelogger/zipball/8f63c829b8d1b0d7b1d5de93510d78523ed18959",
"reference": "8f63c829b8d1b0d7b1d5de93510d78523ed18959",
"shasum": ""
},
"require": {
"php": ">=5.6",
"symfony/console": "^3.4 || ^5.2 || ^6.0",
"symfony/process": "^3.4 || ^5.2 || ^6.0",
"wikimedia/at-ease": "^1.2 || ^2.0"
},
"require-dev": {
"wikimedia/testing-access-wrapper": "^1.0 || ^2.0",
"yoast/phpunit-polyfills": "1.0.4"
},
"bin": [
"bin/changelogger"
],
"type": "project",
"extra": {
"autotagger": true,
"branch-alias": {
"dev-trunk": "3.3.x-dev"
},
"mirror-repo": "Automattic/jetpack-changelogger",
"version-constants": {
"::VERSION": "src/Application.php"
},
"changelogger": {
"link-template": "https://github.com/Automattic/jetpack-changelogger/compare/${old}...${new}"
}
},
"autoload": {
"psr-4": {
"Automattic\\Jetpack\\Changelog\\": "lib",
"Automattic\\Jetpack\\Changelogger\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-2.0-or-later"
],
"description": "Jetpack Changelogger tool. Allows for managing changelogs by dropping change files into a changelog directory with each PR.",
"support": {
"source": "https://github.com/Automattic/jetpack-changelogger/tree/v3.3.0"
},
"time": "2022-12-26T13:49:01+00:00"
},
{
"name": "psr/log",
"version": "1.1.4",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "d49695b909c3b7628b6289db5479a1c204601f11"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
"reference": "d49695b909c3b7628b6289db5479a1c204601f11",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "Psr/Log/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"homepage": "https://github.com/php-fig/log",
"keywords": [
"log",
"psr",
"psr-3"
],
"support": {
"source": "https://github.com/php-fig/log/tree/1.1.4"
},
"time": "2021-05-03T11:20:27+00:00"
},
{
"name": "symfony/console",
"version": "3.4.x-dev",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "a10b1da6fc93080c180bba7219b5ff5b7518fe81"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/a10b1da6fc93080c180bba7219b5ff5b7518fe81",
"reference": "a10b1da6fc93080c180bba7219b5ff5b7518fe81",
"shasum": ""
},
"require": {
"php": "^5.5.9|>=7.0.8",
"symfony/debug": "~2.8|~3.0|~4.0",
"symfony/polyfill-mbstring": "~1.0"
},
"conflict": {
"symfony/dependency-injection": "<3.4",
"symfony/process": "<3.3"
},
"provide": {
"psr/log-implementation": "1.0"
},
"require-dev": {
"psr/log": "~1.0",
"symfony/config": "~3.3|~4.0",
"symfony/dependency-injection": "~3.4|~4.0",
"symfony/event-dispatcher": "~2.8|~3.0|~4.0",
"symfony/lock": "~3.4|~4.0",
"symfony/process": "~3.3|~4.0"
},
"suggest": {
"psr/log": "For using the console logger",
"symfony/event-dispatcher": "",
"symfony/lock": "",
"symfony/process": ""
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Console\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/console/tree/3.4"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-10-24T10:57:07+00:00"
},
{
"name": "symfony/debug",
"version": "4.4.x-dev",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
"reference": "1a692492190773c5310bc7877cb590c04c2f05be"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/debug/zipball/1a692492190773c5310bc7877cb590c04c2f05be",
"reference": "1a692492190773c5310bc7877cb590c04c2f05be",
"shasum": ""
},
"require": {
"php": ">=7.1.3",
"psr/log": "^1|^2|^3"
},
"conflict": {
"symfony/http-kernel": "<3.4"
},
"require-dev": {
"symfony/http-kernel": "^3.4|^4.0|^5.0"
},
"default-branch": true,
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Debug\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Provides tools to ease debugging PHP code",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/debug/tree/v4.4.44"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"abandoned": "symfony/error-handler",
"time": "2022-07-28T16:29:46+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "1.x-dev",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "42292d99c55abe617799667f454222c54c60e229"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229",
"reference": "42292d99c55abe617799667f454222c54c60e229",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"provide": {
"ext-mbstring": "*"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"default-branch": true,
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Mbstring extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"mbstring",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2023-07-28T09:04:16+00:00"
},
{
"name": "symfony/process",
"version": "3.4.x-dev",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "b8648cf1d5af12a44a51d07ef9bf980921f15fca"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/b8648cf1d5af12a44a51d07ef9bf980921f15fca",
"reference": "b8648cf1d5af12a44a51d07ef9bf980921f15fca",
"shasum": ""
},
"require": {
"php": "^5.5.9|>=7.0.8"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Process\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/process/tree/3.4"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-10-24T10:57:07+00:00"
},
{
"name": "wikimedia/at-ease",
"version": "v2.0.0",
"source": {
"type": "git",
"url": "https://github.com/wikimedia/at-ease.git",
"reference": "013ac61929797839c80a111a3f1a4710d8248e7a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/wikimedia/at-ease/zipball/013ac61929797839c80a111a3f1a4710d8248e7a",
"reference": "013ac61929797839c80a111a3f1a4710d8248e7a",
"shasum": ""
},
"require": {
"php": ">=5.6.99"
},
"require-dev": {
"jakub-onderka/php-console-highlighter": "0.3.2",
"jakub-onderka/php-parallel-lint": "1.0.0",
"mediawiki/mediawiki-codesniffer": "22.0.0",
"mediawiki/minus-x": "0.3.1",
"ockcyp/covers-validator": "0.5.1 || 0.6.1",
"phpunit/phpunit": "4.8.36 || ^6.5"
},
"type": "library",
"autoload": {
"files": [
"src/Wikimedia/Functions.php"
],
"psr-4": {
"Wikimedia\\AtEase\\": "src/Wikimedia/AtEase/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-2.0-or-later"
],
"authors": [
{
"name": "Tim Starling",
"email": "tstarling@wikimedia.org"
},
{
"name": "MediaWiki developers",
"email": "wikitech-l@lists.wikimedia.org"
}
],
"description": "Safe replacement to @ for suppressing warnings.",
"homepage": "https://www.mediawiki.org/wiki/at-ease",
"support": {
"source": "https://github.com/wikimedia/at-ease/tree/master"
},
"time": "2018-10-10T15:39:06+00:00"
}
],
"aliases": [],
"minimum-stability": "dev",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"platform-overrides": {
"php": "7.2"
},
"plugin-api-version": "2.6.0"
}

View File

@ -0,0 +1,4 @@
{
"rootDir": "./src",
"preset": "../node_modules/@woocommerce/internal-js-tests/jest-preset.js"
}

View File

@ -0,0 +1,76 @@
{
"name": "@woocommerce/block-templates",
"version": "1.0.0-beta.0",
"description": "Utilities for working with block templates in WooCommerce admin.",
"author": "Automattic",
"license": "GPL-2.0-or-later",
"keywords": [
"wordpress",
"woocommerce"
],
"homepage": "https://github.com/woocommerce/woocommerce/tree/trunk/packages/js/block-templates/README.md",
"repository": {
"type": "git",
"url": "https://github.com/woocommerce/woocommerce.git"
},
"bugs": {
"url": "https://github.com/woocommerce/woocommerce/issues"
},
"main": "build/index.js",
"module": "build-module/index.js",
"types": "build-types",
"react-native": "src/index",
"sideEffects": [
"build-style/**",
"src/**/*.scss"
],
"publishConfig": {
"access": "public"
},
"dependencies": {
"@wordpress/block-editor": "^9.8.0",
"@wordpress/blocks": "^12.3.0"
},
"devDependencies": {
"@babel/core": "^7.21.3",
"@babel/runtime": "^7.17.2",
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react-hooks": "^8.0.1",
"@types/jest": "^27.4.1",
"@types/testing-library__jest-dom": "^5.14.3",
"@types/wordpress__block-editor": "^7.0.0",
"@types/wordpress__blocks": "^11.0.7",
"@woocommerce/eslint-plugin": "workspace:*",
"@woocommerce/internal-js-tests": "workspace:*",
"@woocommerce/internal-style-build": "workspace:*",
"@wordpress/browserslist-config": "wp-6.0",
"copy-webpack-plugin": "^9.1.0",
"css-loader": "^3.6.0",
"eslint": "^8.32.0",
"jest": "^27.5.1",
"jest-cli": "^27.5.1",
"postcss": "^8.4.7",
"postcss-loader": "^4.3.0",
"rimraf": "^3.0.2",
"sass-loader": "^10.2.1",
"ts-jest": "^27.1.3",
"typescript": "^5.1.6",
"webpack": "^5.70.0",
"webpack-cli": "^3.3.12"
},
"scripts": {
"turbo:build": "pnpm run build:js && pnpm run build:css",
"turbo:test": "jest --config ./jest.config.json",
"prepare": "composer install",
"changelog": "composer exec -- changelogger",
"clean": "pnpm exec rimraf tsconfig.tsbuildinfo build build-*",
"build": "pnpm -w exec turbo run turbo:build --filter=$npm_package_name",
"test": "pnpm -w exec turbo run turbo:test --filter=$npm_package_name",
"lint": "eslint --output-file eslint_report.json --format json src",
"build:js": "tsc --project tsconfig.json && tsc --project tsconfig-cjs.json",
"build:css": "webpack",
"start": "concurrently \"tsc --project tsconfig.json --watch\" \"tsc --project tsconfig-cjs.json --watch\" \"webpack --watch\"",
"prepack": "pnpm run clean && pnpm run build",
"lint:fix": "eslint src --fix"
}
}

View File

@ -0,0 +1 @@
export * from './use-woo-block-props';

View File

@ -0,0 +1 @@
export * from './use-woo-block-props';

View File

@ -0,0 +1,37 @@
/**
* External dependencies
*/
import { renderHook } from '@testing-library/react-hooks';
import { useBlockProps } from '@wordpress/block-editor';
/**
* Internal dependencies
*/
import { useWooBlockProps } from '../use-woo-block-props';
jest.mock( '@wordpress/block-editor', () => ( {
useBlockProps: jest.fn(),
} ) );
describe( 'useWooBlockProps', () => {
it( 'should return the block props with the block id and block order attributes', () => {
renderHook( () =>
useWooBlockProps(
{
foo: 'bar',
_templateBlockId: 'test/block',
_templateBlockOrder: 30,
},
{
className: 'test',
}
)
);
expect( useBlockProps ).toHaveBeenCalledWith( {
'data-template-block-id': 'test/block',
'data-template-block-order': 30,
className: 'test',
} );
} );
} );

View File

@ -0,0 +1,24 @@
/**
* External dependencies
*/
import { useBlockProps } from '@wordpress/block-editor';
interface TemplateBlockAttributes {
_templateBlockId?: string;
_templateBlockOrder?: number;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[ key: string ]: any;
}
export const useWooBlockProps = (
attributes: TemplateBlockAttributes,
props: Record< string, unknown > = {}
) => {
const additionalProps = {
'data-template-block-id': attributes._templateBlockId,
'data-template-block-order': attributes._templateBlockOrder,
...props,
};
return useBlockProps( additionalProps );
};

View File

@ -0,0 +1,2 @@
export * from './hooks';
export * from './utils';

View File

@ -0,0 +1 @@
export * from './register-woo-block-type';

View File

@ -0,0 +1,51 @@
/**
* External dependencies
*/
import {
Block,
BlockConfiguration,
registerBlockType,
} from '@wordpress/blocks';
interface BlockRepresentation< T extends Record< string, object > > {
name?: string;
metadata: BlockConfiguration< T >;
settings: Partial< BlockConfiguration< T > >;
}
/**
* Function to register an individual block.
*
* @param block The block to be registered.
* @return The block, if it has been successfully registered; otherwise `undefined`.
*/
export function registerWooBlockType<
// eslint-disable-next-line @typescript-eslint/no-explicit-any
T extends Record< string, any > = Record< string, any >
>( block: BlockRepresentation< T > ): Block< T > | undefined {
if ( ! block ) {
return;
}
const { metadata, settings, name } = block;
const templateBlockAttributes = {
_templateBlockId: {
type: 'string',
__experimentalRole: 'content',
},
_templateBlockOrder: {
type: 'integer',
__experimentalRole: 'content',
},
};
const augmentedMetadata = {
...metadata,
attributes: {
...metadata.attributes,
...templateBlockAttributes,
},
};
return registerBlockType< T >( { name, ...augmentedMetadata }, settings );
}

View File

@ -0,0 +1,59 @@
/**
* External dependencies
*/
import { registerBlockType } from '@wordpress/blocks';
/**
* Internal dependencies
*/
import { registerWooBlockType } from '../register-woo-block-type';
jest.mock( '@wordpress/blocks', () => ( {
registerBlockType: jest.fn(),
} ) );
describe( 'registerWooBlockType', () => {
it( 'should register a block type with the block id and block order attributes', () => {
const block = {
name: 'test/block',
metadata: {
attributes: {
foo: {
type: 'boolean',
default: false,
},
},
},
settings: {
foo: 'bar',
},
};
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore ts2345 Complaining about the type of the foo attribute; it's fine.
registerWooBlockType( block );
expect( registerBlockType ).toHaveBeenCalledWith(
{
name: 'test/block',
attributes: {
foo: {
type: 'boolean',
default: false,
},
_templateBlockId: {
type: 'string',
__experimentalRole: 'content',
},
_templateBlockOrder: {
type: 'integer',
__experimentalRole: 'content',
},
},
},
{
foo: 'bar',
}
);
} );
} );

View File

@ -0,0 +1,16 @@
{
"extends": "../tsconfig-cjs",
"include": [
"**/*.d.ts",
"src/**/*",
"src/**/*.json"
],
"compilerOptions": {
"outDir": "build",
"resolveJsonModule": true,
"typeRoots": [
"./typings",
"./node_modules/@types"
]
}
}

View File

@ -0,0 +1,20 @@
{
"extends": "../tsconfig",
"compilerOptions": {
"rootDir": "src",
"outDir": "build-module",
"declaration": true,
"declarationMap": true,
"declarationDir": "./build-types",
"resolveJsonModule": true,
"typeRoots": [
"./typings",
"./node_modules/@types"
]
},
"include": [
"**/*.d.ts",
"src/**/*",
"src/**/*.json"
]
}

View File

@ -0,0 +1,19 @@
/**
* Internal dependencies
*/
const { webpackConfig } = require( '@woocommerce/internal-style-build' );
module.exports = {
mode: process.env.NODE_ENV || 'development',
entry: {
'build-style': __dirname + '/src/style.scss',
},
output: {
path: __dirname,
},
module: {
parser: webpackConfig.parser,
rules: webpackConfig.rules,
},
plugins: webpackConfig.plugins,
};

View File

@ -0,0 +1,4 @@
Significance: patch
Type: fix
TreeSelectControl Component - Make sure individuallySelectParent prop is respected

View File

@ -0,0 +1,5 @@
Significance: patch
Type: fix
Comment: Fixes and earlier unreleaed change, not changelog required

View File

@ -234,7 +234,10 @@ const TreeSelectControl = ( {
* @return {boolean} True if checked, false otherwise.
*/
get() {
if ( includeParent && this.value !== ROOT_VALUE ) {
if (
( includeParent && this.value !== ROOT_VALUE ) ||
individuallySelectParent
) {
return cache.selectedValues.includes( this.value );
}
if ( this.hasChildren ) {
@ -427,11 +430,20 @@ const TreeSelectControl = ( {
const handleParentChange = ( checked, option ) => {
let newValue;
const changedValues = individuallySelectParent
? []
? [ option.value ]
: option.leaves
.filter( ( opt ) => opt.checked !== checked )
.map( ( opt ) => opt.value );
if ( includeParent && option.value !== ROOT_VALUE ) {
/**
* If includeParent is true, we need to add the parent value to the array of
* changed values. However, if for some reason includeParent AND individuallySelectParent
* are both set to true, we want to avoid duplicating the parent value in the array.
*/
if (
includeParent &&
! individuallySelectParent &&
option.value !== ROOT_VALUE
) {
changedValues.push( option.value );
}
if ( checked ) {

View File

@ -96,6 +96,7 @@ Base.args = {
selectAllLabel: 'All countries',
includeParent: false,
alwaysShowPlaceholder: false,
individuallySelectParent: false,
};
Base.argTypes = {

View File

@ -0,0 +1,4 @@
Significance: minor
Type: performance
Update totalCount in crud store to avoid unnecessary requests.

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Add support for default_values param in productVariations store

View File

@ -57,6 +57,13 @@ export const createResolvers = ( {
const urlParameters = getUrlParameters( namespace, query || {} );
const resourceQuery = cleanQuery( query || {}, namespace );
yield controls.dispatch(
storeName,
'startResolution',
`get${ pluralResourceName }TotalCount`,
[ query ]
);
// Require ID when requesting specific fields to later update the resource data.
if (
resourceQuery &&
@ -98,6 +105,16 @@ export const createResolvers = ( {
};
const getItemsTotalCount = function* ( query?: Partial< ItemQuery > ) {
const startedTotalCountUsingGetItems: boolean = yield controls.select(
storeName,
'hasStartedResolution',
`get${ pluralResourceName }`,
[ query ]
);
// Skip resolver as we get the total count from the getItems query as well with same query parameters.
if ( startedTotalCountUsingGetItems ) {
return;
}
const totalsQuery = {
...( query || {} ),
page: 1,

View File

@ -96,6 +96,7 @@ export type ActionDispatchers = DispatchFromMap< ProductVariationActions >;
export type GenerateRequest = {
delete?: boolean;
default_values?: Partial< ProductVariation >;
};
export type BatchUpdateRequest = {

View File

@ -1,6 +1,7 @@
module.exports = [
// wc-admin packages
'@woocommerce/admin-layout',
'@woocommerce/block-templates',
'@woocommerce/components',
'@woocommerce/csv-export',
'@woocommerce/currency',

View File

@ -0,0 +1,4 @@
Significance: minor
Type: update
Add @woocommerce/block-templates.

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Add regular price as default value if available when generating new product variations.

View File

@ -0,0 +1,4 @@
Significance: patch
Type: fix
The Select all and Clear selection buttons are only displayed when at least 1 item is selected

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Add a visibility toggle to the Quick actions list

View File

@ -0,0 +1,4 @@
Significance: minor
Type: update
Update blocks to use registerWooBlockType and useWooBlockProps from @woocommerce/block-templates. Deprecates initBlock.

View File

@ -0,0 +1,4 @@
Significance: minor
Type: dev
Fix field label styling in the edit attribute modal #40449

View File

@ -0,0 +1,4 @@
Significance: minor
Type: dev
Improve copy in variation management notifications #40467

View File

@ -0,0 +1,5 @@
Significance: patch
Type: enhancement
Comment: Add documentation for woocommerce/product-checkbox-field

View File

@ -0,0 +1,4 @@
Significance: minor
Type: fix
Fix styles for attribute list

View File

@ -0,0 +1,4 @@
Significance: minor
Type: fix
Open variation preview in a new tab #40414

View File

@ -0,0 +1,4 @@
Significance: patch
Type: fix
Fix visibility and filterable icons

View File

@ -0,0 +1,4 @@
Significance: patch
Type: fix
Add cursor: not-allowed; to the disabled Quick updates button

View File

@ -32,6 +32,7 @@
"@types/prop-types": "^15.7.4",
"@types/wordpress__blocks": "^11.0.7",
"@woocommerce/admin-layout": "workspace:*",
"@woocommerce/block-templates": "workspace:*",
"@woocommerce/components": "workspace:*",
"@woocommerce/currency": "workspace:*",
"@woocommerce/customer-effort-score": "workspace:*",
@ -49,6 +50,7 @@
"@wordpress/core-data": "wp-6.0",
"@wordpress/data": "wp-6.0",
"@wordpress/date": "wp-6.0",
"@wordpress/deprecated": "wp-6.0",
"@wordpress/editor": "wp-6.0",
"@wordpress/element": "wp-6.0",
"@wordpress/html-entities": "wp-6.0",

View File

@ -1,9 +1,10 @@
/**
* External dependencies
*/
import { BlockEditProps, BlockAttributes } from '@wordpress/blocks';
import { createElement } from '@wordpress/element';
import { useWooBlockProps } from '@woocommerce/block-templates';
import { ProductAttribute } from '@woocommerce/data';
import { useBlockProps } from '@wordpress/block-editor';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore No types for this exist yet.
// eslint-disable-next-line @woocommerce/dependency-group
@ -14,14 +15,14 @@ import { useEntityProp, useEntityId } from '@wordpress/core-data';
*/
import { Attributes as AttributesContainer } from '../../components/attributes/attributes';
export function Edit() {
export function Edit( { attributes }: BlockEditProps< BlockAttributes > ) {
const [ entityAttributes, setEntityAttributes ] = useEntityProp<
ProductAttribute[]
>( 'postType', 'product', 'attributes' );
const productId = useEntityId( 'postType', 'product' );
const blockProps = useBlockProps();
const blockProps = useWooBlockProps( attributes );
return (
<div { ...blockProps }>

View File

@ -7,7 +7,7 @@
background: none;
border: none;
border-bottom: 1px solid $gray-200;
padding-left: 0;
padding: 0;
grid-template-columns: 26% auto 90px;
}
@ -15,4 +15,9 @@
display: none;
}
.components-button.has-icon {
svg {
fill: $gray-700;
}
}
}

View File

@ -1,7 +1,11 @@
/**
* External dependencies
*/
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils';
import metadata from './block.json';
import { Edit } from './edit';
@ -15,7 +19,7 @@ export const settings = {
};
export const init = () =>
initBlock( {
registerWooBlockType( {
name,
metadata: metadata as never,
settings,

View File

@ -1,10 +1,10 @@
/**
* External dependencies
*/
import { useBlockProps } from '@wordpress/block-editor';
import { CheckboxControl } from '@wordpress/components';
import { useEntityProp } from '@wordpress/core-data';
import { createElement } from '@wordpress/element';
import { useWooBlockProps } from '@woocommerce/block-templates';
import { Product } from '@woocommerce/data';
/**
@ -19,7 +19,7 @@ export function Edit( {
} ) {
const { label, visibility } = attributes;
const blockProps = useBlockProps();
const blockProps = useWooBlockProps( attributes );
const [ catalogVisibility, setCatalogVisibility ] = useEntityProp<
Product[ 'catalog_visibility' ]

View File

@ -2,11 +2,11 @@
* External dependencies
*/
import { BlockConfiguration } from '@wordpress/blocks';
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils/init-block';
import blockConfiguration from './block.json';
import { Edit } from './edit';
import { CatalogVisibilityBlockAttributes } from './types';
@ -24,5 +24,5 @@ export const settings: Partial<
};
export function init() {
return initBlock( { name, metadata, settings } );
return registerWooBlockType( { name, metadata, settings } );
}

View File

@ -0,0 +1,67 @@
# woocommerce/product-checkbox-field
A reusable checkbox for the product editor.
![Product checkbox field screenshot](https://woocommerce.files.wordpress.com/2023/09/checkbox.png)
_Please note that to persist a custom field in the product it also needs to be added to the WooCommerce REST API._
## Attributes
### title
- **Type:** `String`
- **Required:** `No`
Header that appears above the checkbox.
### label
- **Type:** `String`
- **Required:** `No`
Label that appears at the side of the checkbox.
### property
- **Type:** `String`
- **Required:** `Yes`
Property in which the checkbox value is stored.
### tooltip
- **Type:** `String`
- **Required:** `No`
Tooltip text that is shown when hovering the icon at the side of the label.
## Example
Here's an example on the code that is used for the 'sold_individually' field in the Inventory section:
```php
$parent_container->add_block(
[
'id' => 'product-limit-purchase',
'blockName' => 'woocommerce/product-checkbox-field',
'order' => 20,
'attributes' => [
'title' => __(
'Restrictions',
'woocommerce'
),
'label' => __(
'Limit purchases to 1 item per order',
'woocommerce'
),
'property' => 'sold_individually',
'tooltip' => __(
'When checked, customers will be able to purchase only 1 item in a single order. This is particularly useful for items that have limited quantity, like art or handmade goods.',
'woocommerce'
),
],
]
);
```

View File

@ -4,7 +4,7 @@
"name": "woocommerce/product-checkbox-field",
"title": "Product checkbox control",
"category": "woocommerce",
"description": "The product checkbox.",
"description": "A reusable checkbox for the product editor.",
"keywords": [ "products", "checkbox", "input" ],
"textdomain": "default",
"attributes": {

View File

@ -4,17 +4,18 @@
import { createElement } from '@wordpress/element';
import type { BlockAttributes } from '@wordpress/blocks';
import { CheckboxControl, Tooltip } from '@wordpress/components';
import { useBlockProps } from '@wordpress/block-editor';
import { useEntityProp } from '@wordpress/core-data';
import { Icon, help } from '@wordpress/icons';
import { useWooBlockProps } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
export function Edit( { attributes }: { attributes: BlockAttributes } ) {
const blockProps = useBlockProps( {
const blockProps = useWooBlockProps( {
className: 'woocommerce-product-form__checkbox',
...attributes,
} );
const { property, title, label, tooltip } = attributes;
const [ value, setValue ] = useEntityProp< boolean >(

View File

@ -2,11 +2,11 @@
* External dependencies
*/
import { BlockConfiguration } from '@wordpress/blocks';
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils/init-block';
import blockConfiguration from './block.json';
import { Edit } from './edit';
@ -19,4 +19,4 @@ export const settings = {
edit: Edit,
};
export const init = () => initBlock( { name, metadata, settings } );
export const init = () => registerWooBlockType( { name, metadata, settings } );

View File

@ -1,13 +1,14 @@
/**
* External dependencies
*/
import { useWooBlockProps } from '@woocommerce/block-templates';
import { CollapsibleContent } from '@woocommerce/components';
import type { BlockAttributes } from '@wordpress/blocks';
import { createElement } from '@wordpress/element';
import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
import { InnerBlocks } from '@wordpress/block-editor';
export function Edit( { attributes }: { attributes: BlockAttributes } ) {
const blockProps = useBlockProps();
const blockProps = useWooBlockProps( attributes );
const { toggleText, initialCollapsed, persistRender = true } = attributes;
return (

View File

@ -1,7 +1,11 @@
/**
* External dependencies
*/
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils';
import metadata from './block.json';
import { Edit } from './edit';
@ -15,4 +19,4 @@ export const settings = {
};
export const init = () =>
initBlock( { name, metadata: metadata as never, settings } );
registerWooBlockType( { name, metadata: metadata as never, settings } );

View File

@ -3,8 +3,9 @@
*/
import type { BlockAttributes } from '@wordpress/blocks';
import { createElement, useMemo } from '@wordpress/element';
import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
import { InnerBlocks } from '@wordpress/block-editor';
import { useSelect } from '@wordpress/data';
import { useWooBlockProps } from '@woocommerce/block-templates';
import { DisplayState } from '@woocommerce/components';
import { Product } from '@woocommerce/data';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
@ -19,7 +20,7 @@ export function Edit( {
mustMatch: Record< string, Array< string > >;
};
} ) {
const blockProps = useBlockProps();
const blockProps = useWooBlockProps( attributes );
const { mustMatch } = attributes;
const productId = useEntityId( 'postType', 'product' );

View File

@ -1,7 +1,11 @@
/**
* External dependencies
*/
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils';
import metadata from './block.json';
import { Edit } from './edit';
@ -15,4 +19,4 @@ export const settings = {
};
export const init = () =>
initBlock( { name, metadata: metadata as never, settings } );
registerWooBlockType( { name, metadata: metadata as never, settings } );

View File

@ -3,10 +3,16 @@
*/
import { __ } from '@wordpress/i18n';
import { createElement, useState } from '@wordpress/element';
import { BlockInstance, parse, serialize } from '@wordpress/blocks';
import {
BlockEditProps,
BlockAttributes,
BlockInstance,
parse,
serialize,
} from '@wordpress/blocks';
import { Button } from '@wordpress/components';
import { useWooBlockProps } from '@woocommerce/block-templates';
import { recordEvent } from '@woocommerce/tracks';
import { useBlockProps } from '@wordpress/block-editor';
import { useEntityProp } from '@wordpress/core-data';
/**
@ -21,7 +27,7 @@ import { ModalEditor } from '../../components/modal-editor';
/**
* By default the blocks variable always contains one paragraph
* block with empty content, that causes the desciption to never
* block with empty content, that causes the description to never
* be empty. This function removes the default block to keep
* the description empty.
*
@ -39,8 +45,8 @@ function clearDescriptionIfEmpty( blocks: BlockInstance[] ) {
return blocks;
}
export function Edit() {
const blockProps = useBlockProps();
export function Edit( { attributes }: BlockEditProps< BlockAttributes > ) {
const blockProps = useWooBlockProps( attributes );
const [ isModalOpen, setIsModalOpen ] = useState( false );
const [ description, setDescription ] = useEntityProp< string >(
'postType',

View File

@ -2,11 +2,11 @@
* External dependencies
*/
import { BlockConfiguration } from '@wordpress/blocks';
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils/init-block';
import blockConfiguration from './block.json';
import { Edit } from './edit';
@ -19,4 +19,4 @@ export const settings = {
edit: Edit,
};
export const init = () => initBlock( { name, metadata, settings } );
export const init = () => registerWooBlockType( { name, metadata, settings } );

View File

@ -2,18 +2,19 @@
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { BlockEditProps, BlockAttributes } from '@wordpress/blocks';
import { DropZone } from '@wordpress/components';
import classnames from 'classnames';
import { createElement, useState } from '@wordpress/element';
import { Icon, trash } from '@wordpress/icons';
import { MediaItem } from '@wordpress/media-utils';
import { useWooBlockProps } from '@woocommerce/block-templates';
import {
MediaUploader,
ImageGallery,
ImageGalleryItem,
} from '@woocommerce/components';
import { recordEvent } from '@woocommerce/tracks';
import { useBlockProps } from '@wordpress/block-editor';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore No types for this exist yet.
// eslint-disable-next-line @woocommerce/dependency-group
@ -23,7 +24,7 @@ type Image = MediaItem & {
src: string;
};
export function Edit() {
export function Edit( { attributes }: BlockEditProps< BlockAttributes > ) {
const [ images, setImages ] = useEntityProp< MediaItem[] >(
'postType',
'product',
@ -36,7 +37,7 @@ export function Edit() {
null
);
const blockProps = useBlockProps( {
const blockProps = useWooBlockProps( attributes, {
className: classnames( {
'has-images': images.length > 0,
} ),

View File

@ -1,7 +1,11 @@
/**
* External dependencies
*/
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils';
import metadata from './block.json';
import { Edit } from './edit';
@ -15,7 +19,7 @@ export const settings = {
};
export const init = () =>
initBlock( {
registerWooBlockType( {
name,
metadata: metadata as never,
settings,

View File

@ -2,6 +2,7 @@
* External dependencies
*/
import { __, sprintf } from '@wordpress/i18n';
import { useWooBlockProps } from '@woocommerce/block-templates';
import { Link } from '@woocommerce/components';
import { Product } from '@woocommerce/data';
import {
@ -11,7 +12,6 @@ import {
} from '@wordpress/element';
import { getSetting } from '@woocommerce/settings';
import { BlockEditProps } from '@wordpress/blocks';
import { useBlockProps } from '@wordpress/block-editor';
import { useInstanceId } from '@wordpress/compose';
import {
BaseControl,
@ -30,9 +30,10 @@ import { useValidation } from '../../contexts/validation-context';
import { InventoryEmailBlockAttributes } from './types';
export function Edit( {
attributes,
clientId,
}: BlockEditProps< InventoryEmailBlockAttributes > ) {
const blockProps = useBlockProps();
const blockProps = useWooBlockProps( attributes );
const notifyLowStockAmount = getSetting( 'notifyLowStockAmount', 2 );
const [ lowStockAmount, setLowStockAmount ] = useEntityProp< number >(

View File

@ -1,13 +1,12 @@
/**
* External dependencies
*/
import { createElement } from '@wordpress/element';
import { BlockConfiguration } from '@wordpress/blocks';
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils/init-block';
import blockConfiguration from './block.json';
import { Edit } from './edit';
import { InventoryEmailBlockAttributes } from './types';
@ -25,5 +24,5 @@ export const settings: Partial<
};
export function init() {
return initBlock( { name, metadata, settings } );
return registerWooBlockType( { name, metadata, settings } );
}

View File

@ -1,9 +1,9 @@
/**
* External dependencies
*/
import { useWooBlockProps } from '@woocommerce/block-templates';
import { Product } from '@woocommerce/data';
import { BlockEditProps } from '@wordpress/blocks';
import { useBlockProps } from '@wordpress/block-editor';
import { useInstanceId } from '@wordpress/compose';
import { useEntityProp } from '@wordpress/core-data';
import { createElement, useEffect } from '@wordpress/element';
@ -21,9 +21,10 @@ import { TrackInventoryBlockAttributes } from './types';
import { useValidation } from '../../contexts/validation-context';
export function Edit( {
attributes,
clientId,
}: BlockEditProps< TrackInventoryBlockAttributes > ) {
const blockProps = useBlockProps();
const blockProps = useWooBlockProps( attributes );
const [ manageStock ] = useEntityProp< boolean >(
'postType',

View File

@ -1,13 +1,12 @@
/**
* External dependencies
*/
import { createElement } from '@wordpress/element';
import { BlockConfiguration } from '@wordpress/blocks';
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils/init-block';
import blockConfiguration from './block.json';
import { Edit } from './edit';
import { TrackInventoryBlockAttributes } from './types';
@ -25,5 +24,5 @@ export const settings: Partial<
};
export function init() {
return initBlock( { name, metadata, settings } );
return registerWooBlockType( { name, metadata, settings } );
}

View File

@ -2,8 +2,9 @@
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { BlockEditProps, BlockAttributes } from '@wordpress/blocks';
import { createElement, createInterpolateElement } from '@wordpress/element';
import { useBlockProps } from '@wordpress/block-editor';
import { useWooBlockProps } from '@woocommerce/block-templates';
import {
BaseControl,
@ -19,8 +20,8 @@ import { useEntityProp } from '@wordpress/core-data';
* Internal dependencies
*/
export function Edit() {
const blockProps = useBlockProps();
export function Edit( { attributes }: BlockEditProps< BlockAttributes > ) {
const blockProps = useWooBlockProps( attributes );
const [ sku, setSku ] = useEntityProp( 'postType', 'product', 'sku' );

View File

@ -2,11 +2,11 @@
* External dependencies
*/
import { BlockConfiguration } from '@wordpress/blocks';
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils/init-block';
import blockConfiguration from './block.json';
import { Edit } from './edit';
@ -19,4 +19,4 @@ export const settings = {
edit: Edit,
};
export const init = () => initBlock( { name, metadata, settings } );
export const init = () => registerWooBlockType( { name, metadata, settings } );

View File

@ -9,11 +9,11 @@ import {
useState,
} from '@wordpress/element';
import { useBlockProps } from '@wordpress/block-editor';
import { BlockEditProps } from '@wordpress/blocks';
import { useInstanceId } from '@wordpress/compose';
import { cleanForSlug } from '@wordpress/url';
import { useSelect, useDispatch } from '@wordpress/data';
import { useWooBlockProps } from '@woocommerce/block-templates';
import {
PRODUCTS_STORE_NAME,
WCDataSelector,
@ -41,7 +41,7 @@ import { NameBlockAttributes } from './types';
import { useProductEdits } from '../../hooks/use-product-edits';
export function Edit( { attributes }: BlockEditProps< NameBlockAttributes > ) {
const blockProps = useBlockProps();
const blockProps = useWooBlockProps( attributes );
const { editEntityRecord, saveEntityRecord } = useDispatch( 'core' );

View File

@ -1,7 +1,11 @@
/**
* External dependencies
*/
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils';
import metadata from './block.json';
import { Edit } from './edit';
@ -15,7 +19,7 @@ export const settings = {
};
export const init = () =>
initBlock( {
registerWooBlockType( {
name,
metadata: metadata as never,
settings,

View File

@ -1,10 +1,10 @@
/**
* External dependencies
*/
import { useBlockProps } from '@wordpress/block-editor';
import { createElement } from '@wordpress/element';
import type { BlockAttributes, BlockEditProps } from '@wordpress/blocks';
import { Button } from '@wordpress/components';
import { useWooBlockProps } from '@woocommerce/block-templates';
import { getNewPath, navigateTo } from '@woocommerce/navigation';
import { Product } from '@woocommerce/data';
import { useEntityProp } from '@wordpress/core-data';
@ -25,7 +25,7 @@ export interface NoticeBlockAttributes extends BlockAttributes {
export function Edit( {
attributes,
}: BlockEditProps< NoticeBlockAttributes > ) {
const blockProps = useBlockProps();
const blockProps = useWooBlockProps( attributes );
const { buttonText, content, title, type = 'info' } = attributes;
const [ productAttributes ] = useEntityProp< Product[ 'attributes' ] >(

View File

@ -2,11 +2,11 @@
* External dependencies
*/
import { BlockConfiguration } from '@wordpress/blocks';
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils/init-block';
import blockConfiguration from './block.json';
import { Edit, NoticeBlockAttributes } from './edit';
@ -22,5 +22,5 @@ export const settings: Partial< BlockConfiguration< NoticeBlockAttributes > > =
};
export function init() {
initBlock( { name, metadata, settings } );
registerWooBlockType( { name, metadata, settings } );
}

View File

@ -1,12 +1,12 @@
/**
* External dependencies
*/
import { useBlockProps } from '@wordpress/block-editor';
import { BlockEditProps } from '@wordpress/blocks';
import { useInstanceId } from '@wordpress/compose';
import { useEntityProp } from '@wordpress/core-data';
import { createElement, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { useWooBlockProps } from '@woocommerce/block-templates';
import {
BaseControl,
CheckboxControl,
@ -23,7 +23,7 @@ import { RequirePasswordBlockAttributes } from './types';
export function Edit( {
attributes,
}: BlockEditProps< RequirePasswordBlockAttributes > ) {
const blockProps = useBlockProps();
const blockProps = useWooBlockProps( attributes );
const { label } = attributes;
const [ postPassword, setPostPassword ] = useEntityProp< string >(

View File

@ -2,11 +2,11 @@
* External dependencies
*/
import { BlockConfiguration } from '@wordpress/blocks';
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils/init-block';
import blockConfiguration from './block.json';
import { Edit } from './edit';
import { RequirePasswordBlockAttributes } from './types';
@ -23,5 +23,5 @@ export const settings: Partial<
};
export function init() {
return initBlock( { name, metadata, settings } );
return registerWooBlockType( { name, metadata, settings } );
}

View File

@ -1,10 +1,10 @@
/**
* External dependencies
*/
import { useWooBlockProps } from '@woocommerce/block-templates';
import { Link } from '@woocommerce/components';
import { getNewPath } from '@woocommerce/navigation';
import { recordEvent } from '@woocommerce/tracks';
import { useBlockProps } from '@wordpress/block-editor';
import { BlockEditProps } from '@wordpress/blocks';
import { useInstanceId } from '@wordpress/compose';
import { useEntityProp } from '@wordpress/core-data';
@ -25,7 +25,7 @@ import { PricingBlockAttributes } from './types';
export function Edit( {
attributes,
}: BlockEditProps< PricingBlockAttributes > ) {
const blockProps = useBlockProps();
const blockProps = useWooBlockProps( attributes );
const { name, label, help } = attributes;
const [ price, setPrice ] = useEntityProp< string >(
'postType',

View File

@ -2,11 +2,11 @@
* External dependencies
*/
import { BlockConfiguration } from '@wordpress/blocks';
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils/init-block';
import blockConfiguration from './block.json';
import { Edit } from './edit';
import { PricingBlockAttributes } from './types';
@ -23,5 +23,5 @@ export const settings: Partial< BlockConfiguration< PricingBlockAttributes > > =
};
export function init() {
return initBlock( { name, metadata, settings } );
return registerWooBlockType( { name, metadata, settings } );
}

View File

@ -3,8 +3,8 @@
*/
import { createElement } from '@wordpress/element';
import { BlockEditProps } from '@wordpress/blocks';
import { useBlockProps } from '@wordpress/block-editor';
import { useEntityProp } from '@wordpress/core-data';
import { useWooBlockProps } from '@woocommerce/block-templates';
/**
* Internal dependencies
@ -13,7 +13,7 @@ import { RadioField } from '../../components/radio-field';
import { RadioBlockAttributes } from './types';
export function Edit( { attributes }: BlockEditProps< RadioBlockAttributes > ) {
const blockProps = useBlockProps();
const blockProps = useWooBlockProps( attributes );
const { description, options, property, title } = attributes;
const [ value, setValue ] = useEntityProp< string >(
'postType',

View File

@ -2,11 +2,11 @@
* External dependencies
*/
import { BlockConfiguration } from '@wordpress/blocks';
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils/init-block';
import blockConfiguration from './block.json';
import { Edit } from './edit';
import { RadioBlockAttributes } from './types';
@ -22,5 +22,5 @@ export const settings: Partial< BlockConfiguration< RadioBlockAttributes > > = {
};
export function init() {
return initBlock( { name, metadata, settings } );
return registerWooBlockType( { name, metadata, settings } );
}

View File

@ -2,11 +2,11 @@
* External dependencies
*/
import classNames from 'classnames';
import { useWooBlockProps } from '@woocommerce/block-templates';
import { Link } from '@woocommerce/components';
import { Product } from '@woocommerce/data';
import { getNewPath } from '@woocommerce/navigation';
import { recordEvent } from '@woocommerce/tracks';
import { useBlockProps } from '@wordpress/block-editor';
import { BlockEditProps } from '@wordpress/blocks';
import { useInstanceId } from '@wordpress/compose';
import { useEntityProp } from '@wordpress/core-data';
@ -29,7 +29,7 @@ export function Edit( {
attributes,
clientId,
}: BlockEditProps< SalePriceBlockAttributes > ) {
const blockProps = useBlockProps();
const blockProps = useWooBlockProps( attributes );
const { label, help } = attributes;
const [ regularPrice, setRegularPrice ] = useEntityProp< string >(
'postType',

View File

@ -2,11 +2,11 @@
* External dependencies
*/
import { BlockConfiguration } from '@wordpress/blocks';
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils/init-block';
import blockConfiguration from './block.json';
import { Edit } from './edit';
import { SalePriceBlockAttributes } from './types';
@ -24,5 +24,5 @@ export const settings: Partial<
};
export function init() {
return initBlock( { name, metadata, settings } );
return registerWooBlockType( { name, metadata, settings } );
}

View File

@ -2,8 +2,8 @@
* External dependencies
*/
import classNames from 'classnames';
import { useWooBlockProps } from '@woocommerce/block-templates';
import { Product } from '@woocommerce/data';
import { useBlockProps } from '@wordpress/block-editor';
import { BlockEditProps } from '@wordpress/blocks';
import { useInstanceId } from '@wordpress/compose';
import { useEntityProp } from '@wordpress/core-data';
@ -26,7 +26,7 @@ export function Edit( {
attributes,
clientId,
}: BlockEditProps< SalePriceBlockAttributes > ) {
const blockProps = useBlockProps();
const blockProps = useWooBlockProps( attributes );
const { label, help } = attributes;
const [ regularPrice ] = useEntityProp< string >(
'postType',

View File

@ -2,11 +2,11 @@
* External dependencies
*/
import { BlockConfiguration } from '@wordpress/blocks';
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils/init-block';
import blockConfiguration from './block.json';
import { Edit } from './edit';
import { SalePriceBlockAttributes } from './types';
@ -24,5 +24,5 @@ export const settings: Partial<
};
export function init() {
return initBlock( { name, metadata, settings } );
return registerWooBlockType( { name, metadata, settings } );
}

View File

@ -1,10 +1,10 @@
/**
* External dependencies
*/
import { useWooBlockProps } from '@woocommerce/block-templates';
import { DateTimePickerControl } from '@woocommerce/components';
import { Product } from '@woocommerce/data';
import { recordEvent } from '@woocommerce/tracks';
import { useBlockProps } from '@wordpress/block-editor';
import { BlockEditProps } from '@wordpress/blocks';
import { ToggleControl } from '@wordpress/components';
import { useEntityProp } from '@wordpress/core-data';
@ -24,9 +24,10 @@ import { useProductEdits } from '../../hooks/use-product-edits';
import { useValidation } from '../../contexts/validation-context';
export function Edit( {
attributes,
clientId,
}: BlockEditProps< ScheduleSalePricingBlockAttributes > ) {
const blockProps = useBlockProps();
const blockProps = useWooBlockProps( attributes );
const { hasEdit } = useProductEdits();
const dateTimeFormat = getSettings().formats.datetime;

View File

@ -1,13 +1,12 @@
/**
* External dependencies
*/
import { createElement } from '@wordpress/element';
import { BlockConfiguration } from '@wordpress/blocks';
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils/init-block';
import blockConfiguration from './block.json';
import { Edit } from './edit';
import { ScheduleSalePricingBlockAttributes } from './types';
@ -25,5 +24,5 @@ export const settings: Partial<
};
export function init() {
return initBlock( { name, metadata, settings } );
return registerWooBlockType( { name, metadata, settings } );
}

View File

@ -4,8 +4,8 @@
import classNames from 'classnames';
import { createElement } from '@wordpress/element';
import type { BlockEditProps } from '@wordpress/blocks';
import { useWooBlockProps } from '@woocommerce/block-templates';
import {
useBlockProps,
// @ts-expect-error no exported member.
useInnerBlocksProps,
} from '@wordpress/block-editor';
@ -20,7 +20,7 @@ export function Edit( {
attributes,
}: BlockEditProps< SectionBlockAttributes > ) {
const { description, title, blockGap } = attributes;
const blockProps = useBlockProps();
const blockProps = useWooBlockProps( attributes );
const innerBlockProps = useInnerBlocksProps(
{
className: classNames(

View File

@ -1,13 +1,12 @@
/**
* External dependencies
*/
import { createElement } from '@wordpress/element';
import { BlockConfiguration } from '@wordpress/blocks';
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils/init-block';
import blockConfiguration from './block.json';
import { Edit } from './edit';
import { SectionBlockAttributes } from './types';
@ -24,5 +23,5 @@ export const settings: Partial< BlockConfiguration< SectionBlockAttributes > > =
};
export function init() {
return initBlock( { name, metadata, settings } );
return registerWooBlockType( { name, metadata, settings } );
}

View File

@ -2,6 +2,7 @@
* External dependencies
*/
import { BlockEditProps } from '@wordpress/blocks';
import { useWooBlockProps } from '@woocommerce/block-templates';
import { Link } from '@woocommerce/components';
import {
EXPERIMENTAL_PRODUCT_SHIPPING_CLASSES_STORE_NAME,
@ -10,7 +11,6 @@ import {
} from '@woocommerce/data';
import { getNewPath } from '@woocommerce/navigation';
import { recordEvent } from '@woocommerce/tracks';
import { useBlockProps } from '@wordpress/block-editor';
import { BaseControl, SelectControl } from '@wordpress/components';
import { useInstanceId } from '@wordpress/compose';
import { useSelect, useDispatch } from '@wordpress/data';
@ -69,11 +69,13 @@ function extractDefaultShippingClassFromProduct(
}
}
export function Edit( {}: BlockEditProps< ShippingClassBlockAttributes > ) {
export function Edit( {
attributes,
}: BlockEditProps< ShippingClassBlockAttributes > ) {
const [ showShippingClassModal, setShowShippingClassModal ] =
useState( false );
const blockProps = useBlockProps();
const blockProps = useWooBlockProps( attributes );
const { createProductShippingClass, invalidateResolution } = useDispatch(
EXPERIMENTAL_PRODUCT_SHIPPING_CLASSES_STORE_NAME

View File

@ -1,13 +1,12 @@
/**
* External dependencies
*/
import { createElement } from '@wordpress/element';
import { BlockConfiguration } from '@wordpress/blocks';
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils/init-block';
import blockConfiguration from './block.json';
import { Edit } from './edit';
import { ShippingClassBlockAttributes } from './types';
@ -25,5 +24,5 @@ export const settings: Partial<
};
export function init() {
return initBlock( { name, metadata, settings } );
return registerWooBlockType( { name, metadata, settings } );
}

View File

@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { useBlockProps } from '@wordpress/block-editor';
import { useWooBlockProps } from '@woocommerce/block-templates';
import { BlockEditProps } from '@wordpress/blocks';
import {
OPTIONS_STORE_NAME,
@ -36,9 +36,10 @@ import {
import { useValidation } from '../../contexts/validation-context';
export function Edit( {
attributes,
clientId,
}: BlockEditProps< ShippingDimensionsBlockAttributes > ) {
const blockProps = useBlockProps();
const blockProps = useWooBlockProps( attributes );
const [ dimensions, setDimensions ] =
useEntityProp< Partial< ProductDimensions > | null >(

View File

@ -1,13 +1,12 @@
/**
* External dependencies
*/
import { createElement } from '@wordpress/element';
import { BlockConfiguration } from '@wordpress/blocks';
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils/init-block';
import blockConfiguration from './block.json';
import { Edit } from './edit';
import { ShippingDimensionsBlockAttributes } from './types';
@ -25,5 +24,5 @@ export const settings: Partial<
};
export function init() {
return initBlock( { name, metadata, settings } );
return registerWooBlockType( { name, metadata, settings } );
}

View File

@ -2,6 +2,7 @@
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { useWooBlockProps } from '@woocommerce/block-templates';
import { createElement } from '@wordpress/element';
import { BlockEditProps } from '@wordpress/blocks';
import { BaseControl } from '@wordpress/components';
@ -16,7 +17,6 @@ import {
BlockControls,
RichText,
store as blockEditorStore,
useBlockProps,
} from '@wordpress/block-editor';
/**
@ -31,7 +31,7 @@ export function Edit( {
setAttributes,
}: BlockEditProps< SummaryAttributes > ) {
const { align, allowedFormats, direction, label } = attributes;
const blockProps = useBlockProps( {
const blockProps = useWooBlockProps( attributes, {
style: { direction },
} );
const contentId = useInstanceId(

View File

@ -2,11 +2,11 @@
* External dependencies
*/
import { BlockConfiguration } from '@wordpress/blocks';
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils';
import blockConfiguration from './block.json';
import { Edit } from './edit';
import { SummaryAttributes } from './types';
@ -22,7 +22,7 @@ export const settings = {
};
export function init() {
return initBlock< SummaryAttributes >( {
return registerWooBlockType< SummaryAttributes >( {
name,
metadata,
settings,

View File

@ -1,10 +1,11 @@
/**
* External dependencies
*/
import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
import { InnerBlocks } from '@wordpress/block-editor';
import classnames from 'classnames';
import { createElement } from '@wordpress/element';
import type { BlockAttributes, BlockEditProps } from '@wordpress/blocks';
import { useWooBlockProps } from '@woocommerce/block-templates';
/**
* Internal dependencies
@ -27,7 +28,7 @@ export function Edit( {
selectedTab?: string | null;
};
} ) {
const blockProps = useBlockProps();
const blockProps = useWooBlockProps( attributes );
const { id, title, order, isSelected: contextIsSelected } = attributes;
const isSelected = context?.selectedTab === id;
if ( isSelected !== contextIsSelected ) {

View File

@ -2,11 +2,11 @@
* External dependencies
*/
import { BlockConfiguration } from '@wordpress/blocks';
import { registerWooBlockType } from '@woocommerce/block-templates';
/**
* Internal dependencies
*/
import { initBlock } from '../../utils/init-block';
import blockConfiguration from './block.json';
import { Edit, TabBlockAttributes } from './edit';
@ -21,5 +21,5 @@ export const settings: Partial< BlockConfiguration< TabBlockAttributes > > = {
};
export function init() {
initBlock( { name, metadata, settings } );
registerWooBlockType( { name, metadata, settings } );
}

Some files were not shown because too many files have changed in this diff Show More