diff --git a/packages/js/product-editor/changelog/add-44169-edit b/packages/js/product-editor/changelog/add-44169-edit
new file mode 100644
index 00000000000..2312ba32796
--- /dev/null
+++ b/packages/js/product-editor/changelog/add-44169-edit
@@ -0,0 +1,4 @@
+Significance: minor
+Type: add
+
+Edit Custom Fields for New Product Editor
diff --git a/packages/js/product-editor/src/blocks/product-fields/custom-fields/block.json b/packages/js/product-editor/src/blocks/product-fields/custom-fields/block.json
index d5932e0004b..73824721fe2 100644
--- a/packages/js/product-editor/src/blocks/product-fields/custom-fields/block.json
+++ b/packages/js/product-editor/src/blocks/product-fields/custom-fields/block.json
@@ -21,7 +21,5 @@
"inserter": false,
"lock": false,
"__experimentalToolbar": false
- },
- "usesContext": [ "postType" ],
- "editorStyle": "file:./editor.css"
+ }
}
diff --git a/packages/js/product-editor/src/blocks/product-fields/custom-fields/editor.scss b/packages/js/product-editor/src/blocks/product-fields/custom-fields/editor.scss
deleted file mode 100644
index 2ff3974413d..00000000000
--- a/packages/js/product-editor/src/blocks/product-fields/custom-fields/editor.scss
+++ /dev/null
@@ -1,2 +0,0 @@
-.wp-block-woocommerce-product-custom-fields-field {
-}
diff --git a/packages/js/product-editor/src/blocks/style.scss b/packages/js/product-editor/src/blocks/style.scss
index 7099f75bd10..29502c134b0 100644
--- a/packages/js/product-editor/src/blocks/style.scss
+++ b/packages/js/product-editor/src/blocks/style.scss
@@ -1,7 +1,6 @@
@import "product-fields/attributes/editor.scss";
@import "product-fields/description/editor.scss";
@import "product-fields/catalog-visibility/editor.scss";
-@import "product-fields/custom-fields/editor.scss";
@import "product-fields/custom-fields-toggle/editor.scss";
@import "product-fields/downloads/editor.scss";
@import "product-fields/images/editor.scss";
diff --git a/packages/js/product-editor/src/components/custom-fields/custom-fields.tsx b/packages/js/product-editor/src/components/custom-fields/custom-fields.tsx
index ef30ecac777..08412d972f8 100644
--- a/packages/js/product-editor/src/components/custom-fields/custom-fields.tsx
+++ b/packages/js/product-editor/src/components/custom-fields/custom-fields.tsx
@@ -1,7 +1,8 @@
/**
* External dependencies
*/
-import { createElement } from '@wordpress/element';
+import { Button } from '@wordpress/components';
+import { createElement, Fragment, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import classNames from 'classnames';
@@ -9,47 +10,87 @@ import classNames from 'classnames';
* Internal dependencies
*/
import { useCustomFields } from '../../hooks/use-custom-fields';
+import { EditModal } from './edit-modal';
import { EmptyState } from './empty-state';
+import type { Metadata } from '../../types';
import type { CustomFieldsProps } from './types';
export function CustomFields( { className, ...props }: CustomFieldsProps ) {
- const { customFields } = useCustomFields();
+ const { customFields, updateCustomField } = useCustomFields();
+ const [ selectedCustomField, setSelectedCustomField ] =
+ useState< Metadata< string > >();
if ( customFields.length === 0 ) {
return ;
}
+ function customFieldEditButtonClickHandler(
+ customField: Metadata< string >
+ ) {
+ return function handleCustomFieldEditButtonClick() {
+ setSelectedCustomField( customField );
+ };
+ }
+
+ function handleEditModalUpdate( customField: Metadata< string > ) {
+ updateCustomField( customField );
+ setSelectedCustomField( undefined );
+ }
+
+ function handleEditModalCancel() {
+ setSelectedCustomField( undefined );
+ }
+
return (
-
-
-
- { __( 'Name', 'woocommerce' ) } |
- { __( 'Value', 'woocommerce' ) } |
- { __( 'Actions', 'woocommerce' ) } |
-
-
-
- { customFields.map( ( customField ) => (
-
-
- { customField.key }
- |
-
- { customField.value }
- |
- |
+ <>
+
+
+
+ { __( 'Name', 'woocommerce' ) } |
+ { __( 'Value', 'woocommerce' ) } |
+ { __( 'Actions', 'woocommerce' ) } |
- ) ) }
-
-
+
+
+ { customFields.map( ( customField ) => (
+
+
+ { customField.key }
+ |
+
+ { customField.value }
+ |
+
+
+ |
+
+ ) ) }
+
+
+
+ { selectedCustomField && (
+
+ ) }
+ >
);
}
diff --git a/packages/js/product-editor/src/components/custom-fields/edit-modal/edit-modal.tsx b/packages/js/product-editor/src/components/custom-fields/edit-modal/edit-modal.tsx
new file mode 100644
index 00000000000..634fc7f6d94
--- /dev/null
+++ b/packages/js/product-editor/src/components/custom-fields/edit-modal/edit-modal.tsx
@@ -0,0 +1,106 @@
+/**
+ * External dependencies
+ */
+import { Button, Modal } from '@wordpress/components';
+import { createElement, useState, useRef } from '@wordpress/element';
+import { __, sprintf } from '@wordpress/i18n';
+import classNames from 'classnames';
+import type { FocusEvent } from 'react';
+
+/**
+ * Internal dependencies
+ */
+import { TextControl } from '../../text-control';
+import type { Metadata } from '../../../types';
+import type { EditModalProps } from './types';
+
+function validateName( value: string ) {
+ if ( value.startsWith( '_' ) ) {
+ return __(
+ 'The name cannot begin with the underscore (_) character.',
+ 'woocommerce'
+ );
+ }
+}
+
+export function EditModal( {
+ initialValue,
+ onUpdate,
+ onCancel,
+ ...props
+}: EditModalProps ) {
+ const [ customField, setCustomField ] =
+ useState< Metadata< string > >( initialValue );
+ const [ validationError, setValidationError ] = useState< string >();
+ const nameTextRef = useRef< HTMLInputElement >( null );
+
+ function renderTitle() {
+ return sprintf(
+ /* translators: %s: the name of the custom field */
+ __( 'Edit %s', 'woocommerce' ),
+ customField.key
+ );
+ }
+
+ function handleNameChange( key: string ) {
+ setCustomField( ( current ) => ( { ...current, key } ) );
+ }
+
+ function handleNameBlur( event: FocusEvent< HTMLInputElement > ) {
+ const error = validateName( event.target.value );
+ setValidationError( error );
+ }
+
+ function handleValueChange( value: string ) {
+ setCustomField( ( current ) => ( { ...current, value } ) );
+ }
+
+ function handleUpdateButtonClick() {
+ const error = validateName( customField.key );
+ if ( error ) {
+ setValidationError( error );
+ nameTextRef.current?.focus();
+ return;
+ }
+
+ onUpdate( customField );
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/packages/js/product-editor/src/components/custom-fields/edit-modal/index.ts b/packages/js/product-editor/src/components/custom-fields/edit-modal/index.ts
new file mode 100644
index 00000000000..1983e31d98a
--- /dev/null
+++ b/packages/js/product-editor/src/components/custom-fields/edit-modal/index.ts
@@ -0,0 +1,2 @@
+export * from './edit-modal';
+export * from './types';
diff --git a/packages/js/product-editor/src/components/custom-fields/edit-modal/style.scss b/packages/js/product-editor/src/components/custom-fields/edit-modal/style.scss
new file mode 100644
index 00000000000..5818569d744
--- /dev/null
+++ b/packages/js/product-editor/src/components/custom-fields/edit-modal/style.scss
@@ -0,0 +1,15 @@
+.woocommerce-product-custom-fields__edit-modal {
+ min-width: 75%;
+
+ &-actions {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ gap: 12px;
+ margin-top: $grid-unit-40;
+ }
+
+ .components-base-control {
+ width: 100%;
+ }
+}
diff --git a/packages/js/product-editor/src/components/custom-fields/edit-modal/types.ts b/packages/js/product-editor/src/components/custom-fields/edit-modal/types.ts
new file mode 100644
index 00000000000..ac325182ec4
--- /dev/null
+++ b/packages/js/product-editor/src/components/custom-fields/edit-modal/types.ts
@@ -0,0 +1,18 @@
+/**
+ * External dependencies
+ */
+import { Modal } from '@wordpress/components';
+
+/**
+ * Internal dependencies
+ */
+import { Metadata } from '../../../types';
+
+export type EditModalProps = Omit<
+ Modal.Props,
+ 'title' | 'onRequestClose' | 'children'
+> & {
+ initialValue: Metadata< string >;
+ onUpdate( value: Metadata< string > ): void;
+ onCancel(): void;
+};
diff --git a/packages/js/product-editor/src/components/custom-fields/style.scss b/packages/js/product-editor/src/components/custom-fields/style.scss
index ffd20e40704..01c3efb1fca 100644
--- a/packages/js/product-editor/src/components/custom-fields/style.scss
+++ b/packages/js/product-editor/src/components/custom-fields/style.scss
@@ -1,4 +1,5 @@
@import "./empty-state/style.scss";
+@import "./edit-modal/style.scss";
.woocommerce-product-custom-fields {
&__table {
@@ -22,12 +23,13 @@
&-datacell {
padding-top: $grid-unit-30;
padding-bottom: $grid-unit-30;
+ overflow: hidden;
&:last-child {
display: flex;
align-items: center;
justify-content: flex-end;
- padding: 0;
+ padding: 0 2px 0 0;
gap: $grid-unit;
}
}
diff --git a/packages/js/product-editor/src/components/text-control/style.scss b/packages/js/product-editor/src/components/text-control/style.scss
new file mode 100644
index 00000000000..1ed4fa172fe
--- /dev/null
+++ b/packages/js/product-editor/src/components/text-control/style.scss
@@ -0,0 +1,12 @@
+.woocommerce-product-text-control {
+ &.has-error {
+ .components-input-control__container
+ .components-input-control__backdrop {
+ border-color: $studio-red-50;
+ }
+
+ .components-base-control__help {
+ color: $studio-red-50;
+ }
+ }
+}
diff --git a/packages/js/product-editor/src/components/text-control/text-control.tsx b/packages/js/product-editor/src/components/text-control/text-control.tsx
index 1fc71d829a1..19cc06bafff 100644
--- a/packages/js/product-editor/src/components/text-control/text-control.tsx
+++ b/packages/js/product-editor/src/components/text-control/text-control.tsx
@@ -33,9 +33,13 @@ export const TextControl = forwardRef( function ForwardedTextControl(
+ current.map( ( field ) => {
+ if ( customField.id && field.id === customField.id ) {
+ return customField;
+ }
+ return field;
+ } )
+ );
+ }
+
+ return { customFields, setCustomFields, updateCustomField };
}
diff --git a/packages/js/product-editor/src/style.scss b/packages/js/product-editor/src/style.scss
index 598ab494058..a3de9b2d224 100644
--- a/packages/js/product-editor/src/style.scss
+++ b/packages/js/product-editor/src/style.scss
@@ -49,6 +49,7 @@
@import "components/require-password/styles.scss";
@import "components/schedule-publish-modal/style.scss";
@import "components/custom-fields/style.scss";
+@import "components/text-control/style.scss";
/* Field Blocks */