Update product editor package (#36830)
* Add missing dev packages to product-editor package * Create components folder for organization * Move product field, section and tab slots over to product-editor package * Move use of product slot fills to product-editor package * Sync dependencies * Add changelogs * Update README's and add constant for default values * Update README's in product-editor package
This commit is contained in:
parent
2ef4f8a9da
commit
aec4dfd3bd
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: update
|
||||||
|
|
||||||
|
Add deprecated message to product slot fill components
|
|
@ -26,17 +26,17 @@ A Slotfill component that will allow you to add a new field to a specific sectio
|
||||||
|
|
||||||
This is the fill component. You must provide the `id` prop to identify your product field fill with a unique string. This component will accept a series of props:
|
This is the fill component. You must provide the `id` prop to identify your product field fill with a unique string. This component will accept a series of props:
|
||||||
|
|
||||||
| Prop | Type | Description |
|
| Prop | Type | Description |
|
||||||
| -------------| -------- | ------------------------------------------------------------------------------------------------------------------------ |
|
| ---------- | ------ | ------------------------------------------------------------------------------------------------ |
|
||||||
| `id` | String | A unique string to identify your fill. Used for configuiration management. |
|
| `id` | String | A unique string to identify your fill. Used for configuration management. |
|
||||||
| `section ` | String | The string used to identify the particular section where you want to render your field. |
|
| `sections` | Array | Contains an array of name and order values for which slots it should be rendered in. |
|
||||||
| `pluginId` | String | A unique plugin ID to identify the plugin/extension that this fill is associated with. |
|
| `pluginId` | String | A unique plugin ID to identify the plugin/extension that this fill is associated with. |
|
||||||
| `order` | Number | (optional) This number will dictate the order that the fields rendered by a Slot will be appear. |
|
| `order` | Number | (optional) This number will dictate the order that the fields rendered by a Slot will be appear. |
|
||||||
|
|
||||||
### WooProductFieldItem.Slot (slot)
|
### WooProductFieldItem.Slot (slot)
|
||||||
|
|
||||||
This is the slot component, and will not be used as frequently. It must also receive the required `location` prop that will be identical to the fill `location`.
|
This is the slot component. This will render all the registered fills that match the `section` prop.
|
||||||
|
|
||||||
| Name | Type | Description |
|
| Name | Type | Description |
|
||||||
| ----------- | ------ | ---------------------------------------------------------------------------------------------------- |
|
| --------- | ------ | --------------------------------------------------------------------------------------------------- |
|
||||||
| `section` | String | Unique to the section that the Slot appears, and must be the same as the one provided to any fills. |
|
| `section` | String | Unique to the section that the Slot appears, and must be the same as the one provided to any fills. |
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { Slot, Fill } from '@wordpress/components';
|
import { Slot, Fill } from '@wordpress/components';
|
||||||
import { createElement, Children, Fragment } from '@wordpress/element';
|
import { createElement, Children, Fragment } from '@wordpress/element';
|
||||||
|
import deprecated from '@wordpress/deprecated';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -29,6 +30,8 @@ type WooProductFieldFillProps = {
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const DEFAULT_FIELD_ORDER = 20;
|
||||||
|
|
||||||
const WooProductFieldFill: React.FC< WooProductFieldFillProps > = ( {
|
const WooProductFieldFill: React.FC< WooProductFieldFillProps > = ( {
|
||||||
fieldName,
|
fieldName,
|
||||||
sectionName,
|
sectionName,
|
||||||
|
@ -39,6 +42,12 @@ const WooProductFieldFill: React.FC< WooProductFieldFillProps > = ( {
|
||||||
|
|
||||||
const fieldId = `product_field/${ sectionName }/${ fieldName }`;
|
const fieldId = `product_field/${ sectionName }/${ fieldName }`;
|
||||||
|
|
||||||
|
deprecated( `__experimentalWooProductFieldItem`, {
|
||||||
|
version: '13.0.0',
|
||||||
|
plugin: '@woocommerce/components',
|
||||||
|
hint: 'Moved to @woocommerce/product-editor package: import { __experimentalWooProductFieldItem } from @woocommerce/product-editor',
|
||||||
|
} );
|
||||||
|
|
||||||
useEffect( () => {
|
useEffect( () => {
|
||||||
registerFill( fieldId );
|
registerFill( fieldId );
|
||||||
}, [] );
|
}, [] );
|
||||||
|
@ -75,16 +84,18 @@ export const WooProductFieldItem: React.FC< WooProductFieldItemProps > & {
|
||||||
} = ( { children, sections, id } ) => {
|
} = ( { children, sections, id } ) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{ sections.map( ( { name: sectionName, order = 20 } ) => (
|
{ sections.map(
|
||||||
<WooProductFieldFill
|
( { name: sectionName, order = DEFAULT_FIELD_ORDER } ) => (
|
||||||
fieldName={ id }
|
<WooProductFieldFill
|
||||||
sectionName={ sectionName }
|
fieldName={ id }
|
||||||
order={ order }
|
sectionName={ sectionName }
|
||||||
key={ sectionName }
|
order={ order }
|
||||||
>
|
key={ sectionName }
|
||||||
{ children }
|
>
|
||||||
</WooProductFieldFill>
|
{ children }
|
||||||
) ) }
|
</WooProductFieldFill>
|
||||||
|
)
|
||||||
|
) }
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,17 +30,17 @@ A Slotfill component that will allow you to add a new section to the product edi
|
||||||
|
|
||||||
This is the fill component. You must provide the `id` prop to identify your section fill with a unique string. This component will accept a series of props:
|
This is the fill component. You must provide the `id` prop to identify your section fill with a unique string. This component will accept a series of props:
|
||||||
|
|
||||||
| Prop | Type | Description |
|
| Prop | Type | Description |
|
||||||
| -------------| -------- | ------------------------------------------------------------------------------------------------------------------------ |
|
| ---------- | ------ | -------------------------------------------------------------------------------------------------- |
|
||||||
| `id` | String | A unique string to identify your fill. Used for configuiration management. |
|
| `id` | String | A unique string to identify your fill. Used for configuiration management. |
|
||||||
| `location` | String | The string used to identify the particular location that you want to render your section. |
|
| `tabs` | Array | Contains an array of name and order of which slots it should be rendered in. |
|
||||||
| `pluginId` | String | A unique plugin ID to identify the plugin/extension that this fill is associated with. |
|
| `pluginId` | String | A unique plugin ID to identify the plugin/extension that this fill is associated with. |
|
||||||
| `order` | Number | (optional) This number will dictate the order that the sections rendered by a Slot will be appear. |
|
| `order` | Number | (optional) This number will dictate the order that the sections rendered by a Slot will be appear. |
|
||||||
|
|
||||||
### WooProductSectionItem.Slot (slot)
|
### WooProductSectionItem.Slot (slot)
|
||||||
|
|
||||||
This is the slot component, and will not be used as frequently. It must also receive the required `location` prop that will be identical to the fill `location`.
|
This is the slot component. This will render all the registered fills that match the `tab` prop.
|
||||||
|
|
||||||
| Name | Type | Description |
|
| Name | Type | Description |
|
||||||
| ----------- | ------ | ---------------------------------------------------------------------------------------------------- |
|
| ----- | ------ | ---------------------------------------------------------------------------------------------------- |
|
||||||
| `location` | String | Unique to the location that the Slot appears, and must be the same as the one provided to any fills. |
|
| `tab` | String | Unique to the location that the Slot appears, and must be the same as the one provided to any fills. |
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Slot, Fill } from '@wordpress/components';
|
import { Slot, Fill } from '@wordpress/components';
|
||||||
import { createElement, Fragment } from '@wordpress/element';
|
import { createElement, Fragment } from '@wordpress/element';
|
||||||
|
import deprecated from '@wordpress/deprecated';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -21,12 +22,20 @@ type WooProductSectionSlotProps = {
|
||||||
tab: string;
|
tab: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const DEFAULT_SECTION_ORDER = 20;
|
||||||
|
|
||||||
export const WooProductSectionItem: React.FC< WooProductSectionItemProps > & {
|
export const WooProductSectionItem: React.FC< WooProductSectionItemProps > & {
|
||||||
Slot: React.FC< Slot.Props & WooProductSectionSlotProps >;
|
Slot: React.FC< Slot.Props & WooProductSectionSlotProps >;
|
||||||
} = ( { children, tabs } ) => {
|
} = ( { children, tabs } ) => {
|
||||||
|
deprecated( `__experimentalWooProductSectionItem`, {
|
||||||
|
version: '13.0.0',
|
||||||
|
plugin: '@woocommerce/components',
|
||||||
|
hint: 'Moved to @woocommerce/product-editor package: import { __experimentalWooProductSectionItem } from @woocommerce/product-editor',
|
||||||
|
} );
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{ tabs.map( ( { name: tabName, order: tabOrder } ) => (
|
{ tabs.map( ( { name: tabName, order: sectionOrder } ) => (
|
||||||
<Fill
|
<Fill
|
||||||
name={ `woocommerce_product_section_${ tabName }` }
|
name={ `woocommerce_product_section_${ tabName }` }
|
||||||
key={ tabName }
|
key={ tabName }
|
||||||
|
@ -34,7 +43,7 @@ export const WooProductSectionItem: React.FC< WooProductSectionItemProps > & {
|
||||||
{ ( fillProps: Fill.Props ) => {
|
{ ( fillProps: Fill.Props ) => {
|
||||||
return createOrderedChildren<
|
return createOrderedChildren<
|
||||||
Fill.Props & { tabName: string }
|
Fill.Props & { tabName: string }
|
||||||
>( children, tabOrder || 20, {
|
>( children, sectionOrder || DEFAULT_SECTION_ORDER, {
|
||||||
tabName,
|
tabName,
|
||||||
...fillProps,
|
...fillProps,
|
||||||
} );
|
} );
|
||||||
|
|
|
@ -18,18 +18,18 @@ A Slotfill component that will allow you to add a new tab to the product editor.
|
||||||
|
|
||||||
This is the fill component. You must provide the `id` prop to identify your section fill with a unique string. This component will accept a series of props:
|
This is the fill component. You must provide the `id` prop to identify your section fill with a unique string. This component will accept a series of props:
|
||||||
|
|
||||||
| Prop | Type | Description |
|
| Prop | Type | Description |
|
||||||
| ---------- | ------ | -------------------------------------------------------------------------------------------------------------- |
|
| ----------- | ------ | -------------------------------------------------------------------------------------------------------------- |
|
||||||
| `id` | String | A unique string to identify your fill. Used for configuiration management. |
|
| `id` | String | A unique string to identify your fill. Used for configuiration management. |
|
||||||
| `location` | String | The string used to identify the particular location that you want to render your section. |
|
| `templates` | Array | Array of name and order of which template slots it should be rendered in |
|
||||||
| `pluginId` | String | A unique plugin ID to identify the plugin/extension that this fill is associated with. |
|
| `pluginId` | String | A unique plugin ID to identify the plugin/extension that this fill is associated with. |
|
||||||
| `tabProps` | Object | An object containing tab props: name, title, className, disabled (see TabPanel.Tab from @wordpress/components) |
|
| `tabProps` | Object | An object containing tab props: name, title, className, disabled (see TabPanel.Tab from @wordpress/components) |
|
||||||
| `order` | Number | (optional) This number will dictate the order that the sections rendered by a Slot will be appear. |
|
| `order` | Number | (optional) This number will dictate the order that the sections rendered by a Slot will be appear. |
|
||||||
|
|
||||||
### WooProductTabItem.Slot (slot)
|
### WooProductTabItem.Slot (slot)
|
||||||
|
|
||||||
This is the slot component, and will not be used as frequently. It must also receive the required `location` prop that will be identical to the fill `location`.
|
This is the slot component. This will render all the registered fills that match the `template` prop.
|
||||||
|
|
||||||
| Name | Type | Description |
|
| Name | Type | Description |
|
||||||
| ---------- | ------ | ---------------------------------------------------------------------------------------------------- |
|
| ---------- | ------ | ---------------------------------------------------------------------------------------------------- |
|
||||||
| `location` | String | Unique to the location that the Slot appears, and must be the same as the one provided to any fills. |
|
| `template` | String | Unique to the location that the Slot appears, and must be the same as the one provided to any fills. |
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
import React, { ReactElement, ReactNode } from 'react';
|
import React, { ReactElement, ReactNode } from 'react';
|
||||||
import { Slot, Fill, TabPanel } from '@wordpress/components';
|
import { Slot, Fill, TabPanel } from '@wordpress/components';
|
||||||
import { createElement, Fragment } from '@wordpress/element';
|
import { createElement, Fragment } from '@wordpress/element';
|
||||||
|
import deprecated from '@wordpress/deprecated';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -30,11 +31,19 @@ type WooProductFieldSlotProps = {
|
||||||
) => ReactElement | null;
|
) => ReactElement | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const DEFAULT_TAB_ORDER = 20;
|
||||||
|
|
||||||
export const WooProductTabItem: React.FC< WooProductTabItemProps > & {
|
export const WooProductTabItem: React.FC< WooProductTabItemProps > & {
|
||||||
Slot: React.VFC<
|
Slot: React.VFC<
|
||||||
Omit< Slot.Props, 'children' > & WooProductFieldSlotProps
|
Omit< Slot.Props, 'children' > & WooProductFieldSlotProps
|
||||||
>;
|
>;
|
||||||
} = ( { children, tabProps, templates } ) => {
|
} = ( { children, tabProps, templates } ) => {
|
||||||
|
deprecated( `__experimentalWooProductTabItem`, {
|
||||||
|
version: '13.0.0',
|
||||||
|
plugin: '@woocommerce/components',
|
||||||
|
hint: 'Moved to @woocommerce/product-editor package: import { __experimentalWooProductTabItem } from @woocommerce/product-editor',
|
||||||
|
} );
|
||||||
|
|
||||||
if ( ! templates ) {
|
if ( ! templates ) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.warn( 'WooProductTabItem fill is missing templates property.' );
|
console.warn( 'WooProductTabItem fill is missing templates property.' );
|
||||||
|
@ -50,12 +59,12 @@ export const WooProductTabItem: React.FC< WooProductTabItemProps > & {
|
||||||
{ ( fillProps: Fill.Props ) => {
|
{ ( fillProps: Fill.Props ) => {
|
||||||
return createOrderedChildren< Fill.Props >(
|
return createOrderedChildren< Fill.Props >(
|
||||||
children,
|
children,
|
||||||
templateData.order || 20,
|
templateData.order || DEFAULT_TAB_ORDER,
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
tabProps,
|
tabProps,
|
||||||
templateName: templateData.name,
|
templateName: templateData.name,
|
||||||
order: templateData.order || 20,
|
order: templateData.order || DEFAULT_TAB_ORDER,
|
||||||
...fillProps,
|
...fillProps,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -84,7 +93,7 @@ WooProductTabItem.Slot = ( { fillProps, template, children } ) => (
|
||||||
: props.tabProps;
|
: props.tabProps;
|
||||||
tabs.push( {
|
tabs.push( {
|
||||||
...tabProps,
|
...tabProps,
|
||||||
order: props.order ?? 20,
|
order: props.order ?? DEFAULT_TAB_ORDER,
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: add
|
||||||
|
|
||||||
|
Copy over the product slot fill components from @woocommerce/components
|
|
@ -42,12 +42,15 @@
|
||||||
"@woocommerce/eslint-plugin": "workspace:*",
|
"@woocommerce/eslint-plugin": "workspace:*",
|
||||||
"@woocommerce/internal-style-build": "workspace:*",
|
"@woocommerce/internal-style-build": "workspace:*",
|
||||||
"@wordpress/browserslist-config": "^4.1.1",
|
"@wordpress/browserslist-config": "^4.1.1",
|
||||||
|
"concurrently": "^7.0.0",
|
||||||
"css-loader": "^3.6.0",
|
"css-loader": "^3.6.0",
|
||||||
"eslint": "^8.32.0",
|
"eslint": "^8.32.0",
|
||||||
"jest": "^27.5.1",
|
"jest": "^27.5.1",
|
||||||
"jest-cli": "^27.5.1",
|
"jest-cli": "^27.5.1",
|
||||||
"postcss-loader": "^3.0.0",
|
"postcss-loader": "^3.0.0",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
|
"react-dom": "^17.0.2",
|
||||||
|
"rimraf": "^3.0.2",
|
||||||
"sass-loader": "^10.2.1",
|
"sass-loader": "^10.2.1",
|
||||||
"ts-jest": "^27.1.3",
|
"ts-jest": "^27.1.3",
|
||||||
"typescript": "^4.8.3",
|
"typescript": "^4.8.3",
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
export {
|
||||||
|
ProductSectionLayout as __experimentalProductSectionLayout,
|
||||||
|
ProductFieldSection as __experimentalProductFieldSection,
|
||||||
|
} from './product-section-layout';
|
||||||
|
export { WooProductFieldItem as __experimentalWooProductFieldItem } from './woo-product-field-item';
|
||||||
|
export { WooProductSectionItem as __experimentalWooProductSectionItem } from './woo-product-section-item';
|
||||||
|
export { WooProductTabItem as __experimentalWooProductTabItem } from './woo-product-tab-item';
|
|
@ -0,0 +1,42 @@
|
||||||
|
# WooProductFieldItem Slot & Fill
|
||||||
|
|
||||||
|
A Slotfill component that will allow you to add a new field to a specific section in the product editor.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
<WooProductFieldItem id={ key } section="details" order={ 2 } pluginId="test-plugin" >
|
||||||
|
{ () => {
|
||||||
|
return (
|
||||||
|
<TextControl
|
||||||
|
label="Name"
|
||||||
|
name={ `product-mvp-name` }
|
||||||
|
placeholder="e.g. 12 oz Coffee Mug"
|
||||||
|
value="Test Name"
|
||||||
|
onChange={ () => console.debug( 'Changed!' ) }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} }
|
||||||
|
</WooProductFieldItem>
|
||||||
|
|
||||||
|
<WooProductFieldItem.Slot section="details" />
|
||||||
|
```
|
||||||
|
|
||||||
|
### WooProductFieldItem (fill)
|
||||||
|
|
||||||
|
This is the fill component. You must provide the `id` prop to identify your product field fill with a unique string. This component will accept a series of props:
|
||||||
|
|
||||||
|
| Prop | Type | Description |
|
||||||
|
| ---------- | ------ | ------------------------------------------------------------------------------------------------ |
|
||||||
|
| `id` | String | A unique string to identify your fill. Used for configuration management. |
|
||||||
|
| `sections` | Array | Contains an array of name and order values for which slots it should be rendered in. |
|
||||||
|
| `pluginId` | String | A unique plugin ID to identify the plugin/extension that this fill is associated with. |
|
||||||
|
| `order` | Number | (optional) This number will dictate the order that the fields rendered by a Slot will be appear. |
|
||||||
|
|
||||||
|
### WooProductFieldItem.Slot (slot)
|
||||||
|
|
||||||
|
This is the slot component. This will render all the registered fills that match the `section` prop.
|
||||||
|
|
||||||
|
| Name | Type | Description |
|
||||||
|
| --------- | ------ | --------------------------------------------------------------------------------------------------- |
|
||||||
|
| `section` | String | Unique to the section that the Slot appears, and must be the same as the one provided to any fills. |
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './woo-product-field-item';
|
|
@ -0,0 +1,130 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { ReactNode } from 'react';
|
||||||
|
import { Slot, Fill } from '@wordpress/components';
|
||||||
|
import {
|
||||||
|
createElement,
|
||||||
|
Children,
|
||||||
|
Fragment,
|
||||||
|
useEffect,
|
||||||
|
} from '@wordpress/element';
|
||||||
|
import {
|
||||||
|
useSlotContext,
|
||||||
|
SlotContextHelpersType,
|
||||||
|
} from '@woocommerce/components';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { createOrderedChildren, sortFillsByOrder } from '../../utils';
|
||||||
|
import { ProductFillLocationType } from '../woo-product-tab-item';
|
||||||
|
|
||||||
|
type WooProductFieldItemProps = {
|
||||||
|
id: string;
|
||||||
|
sections: ProductFillLocationType[];
|
||||||
|
pluginId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type WooProductFieldSlotProps = {
|
||||||
|
section: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type WooProductFieldFillProps = {
|
||||||
|
fieldName: string;
|
||||||
|
sectionName: string;
|
||||||
|
order: number;
|
||||||
|
children?: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
const DEFAULT_FIELD_ORDER = 20;
|
||||||
|
|
||||||
|
const WooProductFieldFill: React.FC< WooProductFieldFillProps > = ( {
|
||||||
|
fieldName,
|
||||||
|
sectionName,
|
||||||
|
order,
|
||||||
|
children,
|
||||||
|
} ) => {
|
||||||
|
const { registerFill, getFillHelpers } = useSlotContext();
|
||||||
|
|
||||||
|
const fieldId = `product_field/${ sectionName }/${ fieldName }`;
|
||||||
|
|
||||||
|
useEffect( () => {
|
||||||
|
registerFill( fieldId );
|
||||||
|
}, [] );
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Fill
|
||||||
|
name={ `woocommerce_product_field_${ sectionName }` }
|
||||||
|
key={ fieldId }
|
||||||
|
>
|
||||||
|
{ ( fillProps: Fill.Props ) =>
|
||||||
|
createOrderedChildren<
|
||||||
|
Fill.Props &
|
||||||
|
SlotContextHelpersType & {
|
||||||
|
sectionName: string;
|
||||||
|
},
|
||||||
|
{ _id: string }
|
||||||
|
>(
|
||||||
|
children,
|
||||||
|
order,
|
||||||
|
{
|
||||||
|
sectionName,
|
||||||
|
...fillProps,
|
||||||
|
...getFillHelpers(),
|
||||||
|
},
|
||||||
|
{ _id: fieldId }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</Fill>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const WooProductFieldItem: React.FC< WooProductFieldItemProps > & {
|
||||||
|
Slot: React.FC< Slot.Props & WooProductFieldSlotProps >;
|
||||||
|
} = ( { children, sections, id } ) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{ sections.map(
|
||||||
|
( { name: sectionName, order = DEFAULT_FIELD_ORDER } ) => (
|
||||||
|
<WooProductFieldFill
|
||||||
|
fieldName={ id }
|
||||||
|
sectionName={ sectionName }
|
||||||
|
order={ order }
|
||||||
|
key={ sectionName }
|
||||||
|
>
|
||||||
|
{ children }
|
||||||
|
</WooProductFieldFill>
|
||||||
|
)
|
||||||
|
) }
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
WooProductFieldItem.Slot = ( { fillProps, section } ) => {
|
||||||
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||||
|
const { filterRegisteredFills } = useSlotContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Slot
|
||||||
|
name={ `woocommerce_product_field_${ section }` }
|
||||||
|
fillProps={ fillProps }
|
||||||
|
>
|
||||||
|
{ ( fills ) => {
|
||||||
|
if ( ! sortFillsByOrder ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Children.map(
|
||||||
|
sortFillsByOrder( filterRegisteredFills( fills ) )?.props
|
||||||
|
.children,
|
||||||
|
( child ) => (
|
||||||
|
<div className="woocommerce-product-form__field">
|
||||||
|
{ child }
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} }
|
||||||
|
</Slot>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,46 @@
|
||||||
|
# WooProductSectionItem Slot & Fill
|
||||||
|
|
||||||
|
A Slotfill component that will allow you to add a new section to the product editor.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
<WooProductSectionItem id={ key } location="tab/general" order={ 2 } pluginId="test-plugin" >
|
||||||
|
{ () => {
|
||||||
|
return (
|
||||||
|
<ProductSectionLayout
|
||||||
|
title={ __( 'Product test section', 'woocommerce' ) }
|
||||||
|
description={ __(
|
||||||
|
'In this area you can describe the section.',
|
||||||
|
'woocommerce'
|
||||||
|
) }
|
||||||
|
>
|
||||||
|
<Card>
|
||||||
|
<CardBody>{ /* Section content */ }</CardBody>
|
||||||
|
</Card>
|
||||||
|
</ProductSectionLayout>
|
||||||
|
);
|
||||||
|
} }
|
||||||
|
</WooProductSectionItem>
|
||||||
|
|
||||||
|
<WooProductSectionItem.Slot location="tab/general" />
|
||||||
|
```
|
||||||
|
|
||||||
|
### WooProductSectionItem (fill)
|
||||||
|
|
||||||
|
This is the fill component. You must provide the `id` prop to identify your section fill with a unique string. This component will accept a series of props:
|
||||||
|
|
||||||
|
| Prop | Type | Description |
|
||||||
|
| ---------- | ------ | -------------------------------------------------------------------------------------------------- |
|
||||||
|
| `id` | String | A unique string to identify your fill. Used for configuration management. |
|
||||||
|
| `tabs` | Array | Contains an array of name and order of which slots it should be rendered in. |
|
||||||
|
| `pluginId` | String | A unique plugin ID to identify the plugin/extension that this fill is associated with. |
|
||||||
|
| `order` | Number | (optional) This number will dictate the order that the sections rendered by a Slot will be appear. |
|
||||||
|
|
||||||
|
### WooProductSectionItem.Slot (slot)
|
||||||
|
|
||||||
|
This is the slot component. This will render all the registered fills that match the `tab` prop.
|
||||||
|
|
||||||
|
| Name | Type | Description |
|
||||||
|
| ----- | ------ | ---------------------------------------------------------------------------------------------------- |
|
||||||
|
| `tab` | String | Unique to the location that the Slot appears, and must be the same as the one provided to any fills. |
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './woo-product-section-item';
|
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import React from 'react';
|
||||||
|
import { Slot, Fill } from '@wordpress/components';
|
||||||
|
import { createElement, Fragment } from '@wordpress/element';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { createOrderedChildren, sortFillsByOrder } from '../../utils';
|
||||||
|
import { ProductFillLocationType } from '../woo-product-tab-item';
|
||||||
|
|
||||||
|
type WooProductSectionItemProps = {
|
||||||
|
id: string;
|
||||||
|
tabs: ProductFillLocationType[];
|
||||||
|
pluginId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type WooProductSectionSlotProps = {
|
||||||
|
tab: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const DEFAULT_SECTION_ORDER = 20;
|
||||||
|
|
||||||
|
export const WooProductSectionItem: React.FC< WooProductSectionItemProps > & {
|
||||||
|
Slot: React.FC< Slot.Props & WooProductSectionSlotProps >;
|
||||||
|
} = ( { children, tabs } ) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{ tabs.map( ( { name: tabName, order: sectionOrder } ) => (
|
||||||
|
<Fill
|
||||||
|
name={ `woocommerce_product_section_${ tabName }` }
|
||||||
|
key={ tabName }
|
||||||
|
>
|
||||||
|
{ ( fillProps: Fill.Props ) => {
|
||||||
|
return createOrderedChildren<
|
||||||
|
Fill.Props & { tabName: string }
|
||||||
|
>( children, sectionOrder || DEFAULT_SECTION_ORDER, {
|
||||||
|
tabName,
|
||||||
|
...fillProps,
|
||||||
|
} );
|
||||||
|
} }
|
||||||
|
</Fill>
|
||||||
|
) ) }
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
WooProductSectionItem.Slot = ( { fillProps, tab } ) => (
|
||||||
|
<Slot
|
||||||
|
name={ `woocommerce_product_section_${ tab }` }
|
||||||
|
fillProps={ fillProps }
|
||||||
|
>
|
||||||
|
{ ( fills ) => {
|
||||||
|
if ( ! sortFillsByOrder ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sortFillsByOrder( fills );
|
||||||
|
} }
|
||||||
|
</Slot>
|
||||||
|
);
|
|
@ -0,0 +1,35 @@
|
||||||
|
# WooProductTabItem Slot & Fill
|
||||||
|
|
||||||
|
A Slotfill component that will allow you to add a new tab to the product editor.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
<WooProductTabItem id={ key } location="tab/general" order={ 2 } pluginId="test-plugin" tabProps={ { title: 'New tab', name: 'new-tab' } } >
|
||||||
|
<Card>
|
||||||
|
<CardBody>{ /* Tab content */ }</CardBody>
|
||||||
|
</Card>
|
||||||
|
</WooProductTabItem>
|
||||||
|
|
||||||
|
<WooProductTabItem.Slot location="tab/general" />
|
||||||
|
```
|
||||||
|
|
||||||
|
### WooProductTabItem (fill)
|
||||||
|
|
||||||
|
This is the fill component. You must provide the `id` prop to identify your section fill with a unique string. This component will accept a series of props:
|
||||||
|
|
||||||
|
| Prop | Type | Description |
|
||||||
|
| ----------- | ------ | -------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| `id` | String | A unique string to identify your fill. Used for configuration management. |
|
||||||
|
| `templates` | Array | Array of name and order of which template slots it should be rendered in |
|
||||||
|
| `pluginId` | String | A unique plugin ID to identify the plugin/extension that this fill is associated with. |
|
||||||
|
| `tabProps` | Object | An object containing tab props: name, title, className, disabled (see TabPanel.Tab from @wordpress/components) |
|
||||||
|
| `order` | Number | (optional) This number will dictate the order that the sections rendered by a Slot will be appear. |
|
||||||
|
|
||||||
|
### WooProductTabItem.Slot (slot)
|
||||||
|
|
||||||
|
This is the slot component. This will render all the registered fills that match the `template` prop.
|
||||||
|
|
||||||
|
| Name | Type | Description |
|
||||||
|
| ---------- | ------ | ---------------------------------------------------------------------------------------------------- |
|
||||||
|
| `template` | String | Unique to the location that the Slot appears, and must be the same as the one provided to any fills. |
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './woo-product-tab-item';
|
|
@ -0,0 +1,109 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import React, { ReactElement, ReactNode } from 'react';
|
||||||
|
import { Slot, Fill, TabPanel } from '@wordpress/components';
|
||||||
|
import { createElement, Fragment } from '@wordpress/element';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal dependencies
|
||||||
|
*/
|
||||||
|
import { createOrderedChildren } from '../../utils';
|
||||||
|
|
||||||
|
export type ProductFillLocationType = { name: string; order?: number };
|
||||||
|
|
||||||
|
type WooProductTabItemProps = {
|
||||||
|
id: string;
|
||||||
|
pluginId: string;
|
||||||
|
tabProps:
|
||||||
|
| TabPanel.Tab
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
| ( ( fillProps: Record< string, any > | undefined ) => TabPanel.Tab );
|
||||||
|
templates?: Array< ProductFillLocationType >;
|
||||||
|
};
|
||||||
|
|
||||||
|
type WooProductFieldSlotProps = {
|
||||||
|
template: string;
|
||||||
|
children: (
|
||||||
|
tabs: TabPanel.Tab[],
|
||||||
|
tabChildren: Record< string, ReactNode >
|
||||||
|
) => ReactElement | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const DEFAULT_TAB_ORDER = 20;
|
||||||
|
|
||||||
|
export const WooProductTabItem: React.FC< WooProductTabItemProps > & {
|
||||||
|
Slot: React.VFC<
|
||||||
|
Omit< Slot.Props, 'children' > & WooProductFieldSlotProps
|
||||||
|
>;
|
||||||
|
} = ( { children, tabProps, templates } ) => {
|
||||||
|
if ( ! templates ) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.warn( 'WooProductTabItem fill is missing templates property.' );
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{ templates.map( ( templateData ) => (
|
||||||
|
<Fill
|
||||||
|
name={ `woocommerce_product_tab_${ templateData.name }` }
|
||||||
|
key={ templateData.name }
|
||||||
|
>
|
||||||
|
{ ( fillProps: Fill.Props ) => {
|
||||||
|
return createOrderedChildren< Fill.Props >(
|
||||||
|
children,
|
||||||
|
templateData.order || DEFAULT_TAB_ORDER,
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
tabProps,
|
||||||
|
templateName: templateData.name,
|
||||||
|
order: templateData.order || DEFAULT_TAB_ORDER,
|
||||||
|
...fillProps,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} }
|
||||||
|
</Fill>
|
||||||
|
) ) }
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
WooProductTabItem.Slot = ( { fillProps, template, children } ) => (
|
||||||
|
<Slot
|
||||||
|
name={ `woocommerce_product_tab_${ template }` }
|
||||||
|
fillProps={ fillProps }
|
||||||
|
>
|
||||||
|
{ ( fills ) => {
|
||||||
|
const tabData = fills.reduce(
|
||||||
|
( { childrenMap, tabs }, fill ) => {
|
||||||
|
const props: WooProductTabItemProps & { order: number } =
|
||||||
|
fill[ 0 ].props;
|
||||||
|
if ( props && props.tabProps ) {
|
||||||
|
childrenMap[ props.tabProps.name ] = fill[ 0 ];
|
||||||
|
const tabProps =
|
||||||
|
typeof props.tabProps === 'function'
|
||||||
|
? props.tabProps( fillProps )
|
||||||
|
: props.tabProps;
|
||||||
|
tabs.push( {
|
||||||
|
...tabProps,
|
||||||
|
order: props.order ?? DEFAULT_TAB_ORDER,
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
childrenMap,
|
||||||
|
tabs,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{ childrenMap: {}, tabs: [] } as {
|
||||||
|
childrenMap: Record< string, ReactElement >;
|
||||||
|
tabs: Array< TabPanel.Tab & { order: number } >;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const orderedTabs = tabData.tabs.sort( ( a, b ) => {
|
||||||
|
return a.order - b.order;
|
||||||
|
} );
|
||||||
|
|
||||||
|
return children( orderedTabs, tabData.childrenMap );
|
||||||
|
} }
|
||||||
|
</Slot>
|
||||||
|
);
|
|
@ -1,7 +1,4 @@
|
||||||
export {
|
export * from './components';
|
||||||
ProductSectionLayout as __experimentalProductSectionLayout,
|
|
||||||
ProductFieldSection as __experimentalProductFieldSection,
|
|
||||||
} from './product-section-layout';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utils
|
* Utils
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
@import 'product-section-layout/style.scss';
|
@import 'components/product-section-layout/style.scss';
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { isValidElement, Fragment } from 'react';
|
||||||
|
import { Slot, Fill } from '@wordpress/components';
|
||||||
|
import { cloneElement, createElement } from '@wordpress/element';
|
||||||
|
|
||||||
|
type ChildrenProps = {
|
||||||
|
order: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an object with the children and props that will be used by `cloneElement`. They will change depending on the
|
||||||
|
* type of children passed in.
|
||||||
|
*
|
||||||
|
* @param {Node} children - Node children.
|
||||||
|
* @param {number} order - Node order.
|
||||||
|
* @param {Array} props - Fill props.
|
||||||
|
* @param {Object} injectProps - Props to inject.
|
||||||
|
* @return {Object} Object with the keys: children and props.
|
||||||
|
*/
|
||||||
|
function getChildrenAndProps< T = Fill.Props, S = Record< string, unknown > >(
|
||||||
|
children: React.ReactNode,
|
||||||
|
order: number,
|
||||||
|
props: T,
|
||||||
|
injectProps?: S
|
||||||
|
) {
|
||||||
|
if ( typeof children === 'function' ) {
|
||||||
|
return {
|
||||||
|
children: children( { ...props, order, ...injectProps } ),
|
||||||
|
props: { order, ...injectProps },
|
||||||
|
};
|
||||||
|
} else if ( isValidElement( children ) ) {
|
||||||
|
// This checks whether 'children' is a react element or a standard HTML element.
|
||||||
|
if ( typeof children?.type === 'function' ) {
|
||||||
|
return {
|
||||||
|
children,
|
||||||
|
props: {
|
||||||
|
...props,
|
||||||
|
order,
|
||||||
|
...injectProps,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
children: children as React.ReactElement< ChildrenProps >,
|
||||||
|
props: { order, ...injectProps },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
throw Error( 'Invalid children type' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ordered fill item.
|
||||||
|
*
|
||||||
|
* @param {Node} children - Node children.
|
||||||
|
* @param {number} order - Node order.
|
||||||
|
* @param {Array} props - Fill props.
|
||||||
|
* @param {Object} injectProps - Props to inject.
|
||||||
|
* @return {Node} Node.
|
||||||
|
*/
|
||||||
|
function createOrderedChildren< T = Fill.Props, S = Record< string, unknown > >(
|
||||||
|
children: React.ReactNode,
|
||||||
|
order: number,
|
||||||
|
props: T,
|
||||||
|
injectProps?: S
|
||||||
|
) {
|
||||||
|
const { children: childrenToRender, props: propsToRender } =
|
||||||
|
getChildrenAndProps( children, order, props, injectProps );
|
||||||
|
return cloneElement( childrenToRender, propsToRender );
|
||||||
|
}
|
||||||
|
export { createOrderedChildren };
|
|
@ -17,6 +17,9 @@ import {
|
||||||
} from './get-product-variation-title';
|
} from './get-product-variation-title';
|
||||||
import { preventLeavingProductForm } from './prevent-leaving-product-form';
|
import { preventLeavingProductForm } from './prevent-leaving-product-form';
|
||||||
|
|
||||||
|
export * from './create-ordered-children';
|
||||||
|
export * from './sort-fills-by-order';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
AUTO_DRAFT_NAME,
|
AUTO_DRAFT_NAME,
|
||||||
formatCurrencyDisplayValue,
|
formatCurrencyDisplayValue,
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
* External dependencies
|
||||||
|
*/
|
||||||
|
import { Fragment } from 'react';
|
||||||
|
import { Slot } from '@wordpress/components';
|
||||||
|
import { createElement } from '@wordpress/element';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort fills by order for slot children.
|
||||||
|
*
|
||||||
|
* @param {Array} fills - slot's `Fill`s.
|
||||||
|
* @return {Node} Node.
|
||||||
|
*/
|
||||||
|
export const sortFillsByOrder: Slot.Props[ 'children' ] = ( fills ) => {
|
||||||
|
// Copy fills array here because its type is readonly array that doesn't have .sort method in Typescript definition.
|
||||||
|
const sortedFills = [ ...fills ].sort( ( a, b ) => {
|
||||||
|
return a[ 0 ].props.order - b[ 0 ].props.order;
|
||||||
|
} );
|
||||||
|
|
||||||
|
return <Fragment>{ sortedFills }</Fragment>;
|
||||||
|
};
|
|
@ -2,12 +2,12 @@
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { Link } from '@woocommerce/components';
|
||||||
import {
|
import {
|
||||||
__experimentalWooProductSectionItem as WooProductSectionItem,
|
__experimentalWooProductSectionItem as WooProductSectionItem,
|
||||||
__experimentalWooProductFieldItem as WooProductFieldItem,
|
__experimentalWooProductFieldItem as WooProductFieldItem,
|
||||||
Link,
|
__experimentalProductSectionLayout as ProductSectionLayout,
|
||||||
} from '@woocommerce/components';
|
} from '@woocommerce/product-editor';
|
||||||
import { __experimentalProductSectionLayout as ProductSectionLayout } from '@woocommerce/product-editor';
|
|
||||||
import { recordEvent } from '@woocommerce/tracks';
|
import { recordEvent } from '@woocommerce/tracks';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
*/
|
*/
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import {
|
import {
|
||||||
|
__experimentalProductFieldSection as ProductFieldSection,
|
||||||
__experimentalWooProductSectionItem as WooProductSectionItem,
|
__experimentalWooProductSectionItem as WooProductSectionItem,
|
||||||
__experimentalWooProductFieldItem as WooProductFieldItem,
|
__experimentalWooProductFieldItem as WooProductFieldItem,
|
||||||
} from '@woocommerce/components';
|
} from '@woocommerce/product-editor';
|
||||||
import { __experimentalProductFieldSection as ProductFieldSection } from '@woocommerce/product-editor';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { Link } from '@woocommerce/components';
|
||||||
import {
|
import {
|
||||||
__experimentalWooProductSectionItem as WooProductSectionItem,
|
__experimentalWooProductSectionItem as WooProductSectionItem,
|
||||||
__experimentalWooProductFieldItem as WooProductFieldItem,
|
__experimentalWooProductFieldItem as WooProductFieldItem,
|
||||||
Link,
|
__experimentalProductFieldSection as ProductFieldSection,
|
||||||
} from '@woocommerce/components';
|
} from '@woocommerce/product-editor';
|
||||||
import { __experimentalProductFieldSection as ProductFieldSection } from '@woocommerce/product-editor';
|
|
||||||
import { recordEvent } from '@woocommerce/tracks';
|
import { recordEvent } from '@woocommerce/tracks';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,13 +3,15 @@
|
||||||
*/
|
*/
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import {
|
import {
|
||||||
__experimentalWooProductSectionItem as WooProductSectionItem,
|
|
||||||
__experimentalWooProductFieldItem as WooProductFieldItem,
|
|
||||||
Link,
|
Link,
|
||||||
useFormContext,
|
useFormContext,
|
||||||
CollapsibleContent,
|
CollapsibleContent,
|
||||||
} from '@woocommerce/components';
|
} from '@woocommerce/components';
|
||||||
import { __experimentalProductSectionLayout as ProductSectionLayout } from '@woocommerce/product-editor';
|
import {
|
||||||
|
__experimentalWooProductSectionItem as WooProductSectionItem,
|
||||||
|
__experimentalWooProductFieldItem as WooProductFieldItem,
|
||||||
|
__experimentalProductSectionLayout as ProductSectionLayout,
|
||||||
|
} from '@woocommerce/product-editor';
|
||||||
import { Card, CardBody } from '@wordpress/components';
|
import { Card, CardBody } from '@wordpress/components';
|
||||||
import { recordEvent } from '@woocommerce/tracks';
|
import { recordEvent } from '@woocommerce/tracks';
|
||||||
import { getAdminLink } from '@woocommerce/settings';
|
import { getAdminLink } from '@woocommerce/settings';
|
||||||
|
|
|
@ -3,13 +3,15 @@
|
||||||
*/
|
*/
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import {
|
import {
|
||||||
__experimentalWooProductSectionItem as WooProductSectionItem,
|
|
||||||
__experimentalWooProductFieldItem as WooProductFieldItem,
|
|
||||||
Link,
|
Link,
|
||||||
useFormContext,
|
useFormContext,
|
||||||
CollapsibleContent,
|
CollapsibleContent,
|
||||||
} from '@woocommerce/components';
|
} from '@woocommerce/components';
|
||||||
import { __experimentalProductSectionLayout as ProductSectionLayout } from '@woocommerce/product-editor';
|
import {
|
||||||
|
__experimentalWooProductSectionItem as WooProductSectionItem,
|
||||||
|
__experimentalWooProductFieldItem as WooProductFieldItem,
|
||||||
|
__experimentalProductSectionLayout as ProductSectionLayout,
|
||||||
|
} from '@woocommerce/product-editor';
|
||||||
import { recordEvent } from '@woocommerce/tracks';
|
import { recordEvent } from '@woocommerce/tracks';
|
||||||
import { Product } from '@woocommerce/data';
|
import { Product } from '@woocommerce/data';
|
||||||
import { useContext } from '@wordpress/element';
|
import { useContext } from '@wordpress/element';
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
/**
|
/**
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import {
|
import { renderField, useFormContext } from '@woocommerce/components';
|
||||||
__experimentalWooProductFieldItem as WooProductFieldItem,
|
import { __experimentalWooProductFieldItem as WooProductFieldItem } from '@woocommerce/product-editor';
|
||||||
renderField,
|
|
||||||
useFormContext,
|
|
||||||
} from '@woocommerce/components';
|
|
||||||
import { Product, ProductFormField } from '@woocommerce/data';
|
import { Product, ProductFormField } from '@woocommerce/data';
|
||||||
|
|
||||||
export const Fields: React.FC< { fields: ProductFormField[] } > = ( {
|
export const Fields: React.FC< { fields: ProductFormField[] } > = ( {
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { __experimentalWooProductSectionItem as WooProductSectionItem } from '@woocommerce/components';
|
import {
|
||||||
import { __experimentalProductFieldSection as ProductFieldSection } from '@woocommerce/product-editor';
|
__experimentalProductFieldSection as ProductFieldSection,
|
||||||
|
__experimentalWooProductSectionItem as WooProductSectionItem,
|
||||||
|
} from '@woocommerce/product-editor';
|
||||||
import { ProductFormSection } from '@woocommerce/data';
|
import { ProductFormSection } from '@woocommerce/data';
|
||||||
|
|
||||||
export const Sections: React.FC< { sections: ProductFormSection[] } > = ( {
|
export const Sections: React.FC< { sections: ProductFormSection[] } > = ( {
|
||||||
|
|
|
@ -6,8 +6,8 @@ import { registerPlugin } from '@wordpress/plugins';
|
||||||
import {
|
import {
|
||||||
__experimentalWooProductTabItem as WooProductTabItem,
|
__experimentalWooProductTabItem as WooProductTabItem,
|
||||||
__experimentalWooProductSectionItem as WooProductSectionItem,
|
__experimentalWooProductSectionItem as WooProductSectionItem,
|
||||||
useFormContext,
|
} from '@woocommerce/product-editor';
|
||||||
} from '@woocommerce/components';
|
import { useFormContext } from '@woocommerce/components';
|
||||||
import { Product } from '@woocommerce/data';
|
import { Product } from '@woocommerce/data';
|
||||||
import { useMemo } from '@wordpress/element';
|
import { useMemo } from '@wordpress/element';
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { registerPlugin } from '@wordpress/plugins';
|
||||||
import {
|
import {
|
||||||
__experimentalWooProductTabItem as WooProductTabItem,
|
__experimentalWooProductTabItem as WooProductTabItem,
|
||||||
__experimentalWooProductSectionItem as WooProductSectionItem,
|
__experimentalWooProductSectionItem as WooProductSectionItem,
|
||||||
} from '@woocommerce/components';
|
} from '@woocommerce/product-editor';
|
||||||
import { PartialProduct } from '@woocommerce/data';
|
import { PartialProduct } from '@woocommerce/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -5,8 +5,8 @@ import { __ } from '@wordpress/i18n';
|
||||||
import {
|
import {
|
||||||
__experimentalWooProductSectionItem as WooProductSectionItem,
|
__experimentalWooProductSectionItem as WooProductSectionItem,
|
||||||
__experimentalWooProductFieldItem as WooProductFieldItem,
|
__experimentalWooProductFieldItem as WooProductFieldItem,
|
||||||
} from '@woocommerce/components';
|
__experimentalProductSectionLayout as ProductSectionLayout,
|
||||||
import { __experimentalProductSectionLayout as ProductSectionLayout } from '@woocommerce/product-editor';
|
} from '@woocommerce/product-editor';
|
||||||
import { PartialProduct, OPTIONS_STORE_NAME } from '@woocommerce/data';
|
import { PartialProduct, OPTIONS_STORE_NAME } from '@woocommerce/data';
|
||||||
import { useSelect } from '@wordpress/data';
|
import { useSelect } from '@wordpress/data';
|
||||||
import { useState } from '@wordpress/element';
|
import { useState } from '@wordpress/element';
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { __ } from '@wordpress/i18n';
|
||||||
import { useEffect } from '@wordpress/element';
|
import { useEffect } from '@wordpress/element';
|
||||||
import { TabPanel, Tooltip } from '@wordpress/components';
|
import { TabPanel, Tooltip } from '@wordpress/components';
|
||||||
import { navigateTo, getNewPath, getQuery } from '@woocommerce/navigation';
|
import { navigateTo, getNewPath, getQuery } from '@woocommerce/navigation';
|
||||||
import { __experimentalWooProductTabItem as WooProductTabItem } from '@woocommerce/components';
|
import { __experimentalWooProductTabItem as WooProductTabItem } from '@woocommerce/product-editor';
|
||||||
import { PartialProduct } from '@woocommerce/data';
|
import { PartialProduct } from '@woocommerce/data';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: update
|
||||||
|
|
||||||
|
Update imports of product slot fills to new @woocommerce/product-editor library
|
2675
pnpm-lock.yaml
2675
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue