diff --git a/assets/src/js/bindings/block-editor.js b/assets/src/js/bindings/block-editor.js
new file mode 100644
index 00000000..b49aca93
--- /dev/null
+++ b/assets/src/js/bindings/block-editor.js
@@ -0,0 +1,345 @@
+/**
+ * WordPress dependencies
+ */
+import { useState, useEffect, useCallback, useMemo } from '@wordpress/element';
+import { addFilter } from '@wordpress/hooks';
+import { createHigherOrderComponent } from '@wordpress/compose';
+import {
+ InspectorControls,
+ useBlockBindingsUtils,
+} from '@wordpress/block-editor';
+import {
+ BaseControl,
+ ComboboxControl,
+ __experimentalToolsPanel as ToolsPanel,
+ __experimentalToolsPanelItem as ToolsPanelItem,
+ __experimentalHStack as HStack,
+} from '@wordpress/components';
+import { __ } from '@wordpress/i18n';
+import { useSelect } from '@wordpress/data';
+import { store as coreDataStore } from '@wordpress/core-data';
+import { store as editorStore } from '@wordpress/editor';
+
+/**
+ * Internal dependencies
+ */
+import BlockAttributesControlLinkedButton from './components/block-attributes-control-linked-button';
+
+// These constant and the function above have been copied from Gutenberg. It should be public, eventually.
+
+const BLOCK_BINDINGS_ALLOWED_BLOCKS = {
+ 'core/paragraph': [ 'content' ],
+ 'core/heading': [ 'content' ],
+ 'core/image': [ 'id', 'url', 'title', 'alt' ],
+ 'core/button': [ 'url', 'text', 'linkTarget', 'rel' ],
+};
+
+/**
+ * Gets the bindable attributes for a given block.
+ *
+ * @param {string} blockName The name of the block.
+ *
+ * @return {string[]} The bindable attributes for the block.
+ */
+function getBindableAttributes( blockName ) {
+ return BLOCK_BINDINGS_ALLOWED_BLOCKS[ blockName ];
+}
+
+/**
+ * Add custom controls to all blocks
+ */
+const withCustomControls = createHigherOrderComponent( ( BlockEdit ) => {
+ return ( props ) => {
+ const bindableAttributes = getBindableAttributes( props.name );
+ const showLinkedButton = props.name === 'core/image';
+ const { updateBlockBindings, removeAllBlockBindings } =
+ useBlockBindingsUtils();
+
+ const { postType, postId } = useSelect( ( select ) => {
+ const { getCurrentPostType, getCurrentPostId } =
+ select( editorStore );
+ return {
+ postType: getCurrentPostType(),
+ postId: getCurrentPostId(),
+ };
+ }, [] );
+
+ const fieldsGroups = useSelect(
+ ( select ) => {
+ const { getEditedEntityRecord } = select( coreDataStore );
+
+ if ( ! postType || ! postId ) {
+ return undefined;
+ }
+
+ const record = getEditedEntityRecord(
+ 'postType',
+ postType,
+ postId
+ );
+ return record?.scf_field_groups;
+ },
+ [ postType, postId ]
+ );
+
+ const currentBindings = props.attributes?.metadata?.bindings || {};
+
+ const fields = useMemo(
+ () =>
+ fieldsGroups?.reduce( ( acc, fieldGroup ) => {
+ const groupFields =
+ fieldGroup.fields?.map( ( field ) => ( {
+ ...field,
+ fieldGroupTitle: fieldGroup.title,
+ name: field.name,
+ label: field.label,
+ value: field.value,
+ } ) ) || [];
+
+ return [ ...acc, ...groupFields ];
+ }, [] ) || [],
+ [ fieldsGroups ]
+ );
+
+ const fieldsSuggestions = useMemo( () => {
+ if ( props.name === 'core/image' ) {
+ // return only the type image fields
+ return fields
+ .filter( ( field ) => field.type === 'image' )
+ .map( ( field ) => ( {
+ value: field.name,
+ label: field.label,
+ } ) );
+ } else {
+ return fields.map( ( field ) => ( {
+ value: field.name,
+ label: field.label,
+ } ) );
+ }
+ }, [ fields ] );
+
+ // Initialize the field state with an empty object to track multiple attributes
+ const [ boundFields, setBoundFields ] = useState( {} );
+ const [ allBoundFields, setAllBoundFields ] = useState(
+ props.name === 'core/image'
+ );
+
+ // Memoize the stringified currentBindings to avoid unnecessary effect runs
+ const currentBindingsKey = useMemo(
+ () => JSON.stringify( currentBindings ),
+ [ currentBindings ]
+ );
+
+ // Initialize bound fields from current bindings when they change
+ useEffect( () => {
+ if ( Object.keys( currentBindings ).length > 0 ) {
+ const initialBoundFields = {};
+
+ // Extract field values from current bindings
+ Object.keys( currentBindings ).forEach( ( attribute ) => {
+ if ( currentBindings[ attribute ]?.args?.key ) {
+ initialBoundFields[ attribute ] =
+ currentBindings[ attribute ].args.key;
+ }
+ } );
+
+ setBoundFields( initialBoundFields );
+ } else {
+ // Clear bound fields when there are no current bindings
+ setBoundFields( {} );
+ }
+ }, [ currentBindingsKey ] );
+
+ // Memoize the change handler to prevent creating new function on each render
+ const handleFieldChange = useCallback(
+ ( attributes, value ) => {
+ // Ensure attributes is always an array.
+ const attributeArray = Array.isArray( attributes )
+ ? attributes
+ : [ attributes ];
+
+ if ( attributeArray.length > 1 ) {
+ setBoundFields( ( prevState ) => {
+ const newState = { ...prevState };
+ const bindings = {};
+
+ attributeArray.forEach( ( attr ) => {
+ newState[ attr ] = value;
+ bindings[ attr ] = {
+ source: 'acf/field',
+ args: {
+ key: value,
+ },
+ };
+ } );
+
+ // Update all bindings at once.
+ updateBlockBindings( bindings );
+
+ return newState;
+ } );
+ } else {
+ const singleAttribute = attributeArray[ 0 ];
+ setBoundFields( ( prevState ) => ( {
+ ...prevState,
+ [ singleAttribute ]: value,
+ } ) );
+ updateBlockBindings( {
+ [ singleAttribute ]: {
+ source: 'acf/field',
+ args: {
+ key: value,
+ },
+ },
+ } );
+ }
+ },
+ [ updateBlockBindings ]
+ );
+
+ const handleReset = useCallback( () => {
+ removeAllBlockBindings();
+ setBoundFields( {} );
+ }, [ removeAllBlockBindings ] );
+
+ if ( fieldsSuggestions.length === 0 || ! bindableAttributes ) {
+ return ;
+ }
+
+ return (
+ <>
+
+
+
+ { showLinkedButton && (
+
+
+ { allBoundFields
+ ? __(
+ 'Unlink all attributes',
+ 'secure-custom-fields'
+ )
+ : __(
+ 'Link all attributes',
+ 'secure-custom-fields'
+ ) }
+
+ {
+ setAllBoundFields( ! allBoundFields );
+ } }
+ />
+
+ ) }
+ { allBoundFields ? (
+
+ !! boundFields[ bindableAttributes[ 0 ] ]
+ }
+ label={ __(
+ 'All attributes',
+ 'secure-custom-fields'
+ ) }
+ onDeselect={ () =>
+ handleFieldChange( bindableAttributes, '' )
+ }
+ isShownByDefault={ true }
+ >
+
+ handleFieldChange(
+ bindableAttributes,
+ value
+ )
+ }
+ />
+
+ ) : (
+ <>
+ { bindableAttributes.map( ( attribute ) => (
+
+ !! boundFields[ attribute ]
+ }
+ label={ attribute }
+ onDeselect={ () =>
+ handleFieldChange( attribute, '' )
+ }
+ isShownByDefault={ true }
+ >
+
+ handleFieldChange(
+ attribute,
+ value
+ )
+ }
+ />
+
+ ) ) }
+ >
+ ) }
+
+
+ >
+ );
+ };
+}, 'withCustomControls' );
+
+if ( window.scf?.betaFeatures?.connect_fields ) {
+ addFilter(
+ 'editor.BlockEdit',
+ 'secure-custom-fields/with-custom-controls',
+ withCustomControls
+ );
+}
diff --git a/assets/src/js/bindings/components/block-attributes-control-linked-button.js b/assets/src/js/bindings/components/block-attributes-control-linked-button.js
new file mode 100644
index 00000000..5824344a
--- /dev/null
+++ b/assets/src/js/bindings/components/block-attributes-control-linked-button.js
@@ -0,0 +1,27 @@
+/**
+ * WordPress dependencies
+ */
+import { link, linkOff } from '@wordpress/icons';
+import { __ } from '@wordpress/i18n';
+import { Button } from '@wordpress/components';
+
+const BlockAttributesControlLinkedButton = (
+ props
+) => {
+ const { className, isLinked, onClick } = props;
+
+ const label = isLinked ? __( 'Unlink sides' ) : __( 'Link sides' );
+
+ return (
+
+ );
+};
+
+export default BlockAttributesControlLinkedButton;
\ No newline at end of file
diff --git a/assets/src/js/bindings/index.js b/assets/src/js/bindings/index.js
index 278d4879..c81a6544 100644
--- a/assets/src/js/bindings/index.js
+++ b/assets/src/js/bindings/index.js
@@ -1 +1,2 @@
import './sources.js';
+import './block-editor.js';
diff --git a/assets/src/js/bindings/sources.js b/assets/src/js/bindings/sources.js
index 0dcfced6..cbbbd1ae 100644
--- a/assets/src/js/bindings/sources.js
+++ b/assets/src/js/bindings/sources.js
@@ -4,6 +4,7 @@
import { __ } from '@wordpress/i18n';
import { registerBlockBindingsSource } from '@wordpress/blocks';
import { store as coreDataStore } from '@wordpress/core-data';
+import { dateI18n } from '@wordpress/date';
/**
* Get the value of a specific field from the ACF fields.
@@ -24,6 +25,8 @@ const resolveImageAttribute = ( imageObj, attribute ) => {
return imageObj.alt_text || '';
case 'title':
return imageObj.title?.rendered || '';
+ case 'id':
+ return imageObj.id;
default:
return '';
}
@@ -43,12 +46,19 @@ registerBlockBindingsSource( {
)
: undefined;
const result = {};
-
Object.entries( bindings ).forEach(
( [ attribute, { args } = {} ] ) => {
const fieldName = args?.key;
-
+ const mergedFields = fields?.scf_field_groups
+ ? Object.fromEntries(
+ fields.scf_field_groups
+ .flatMap( ( group ) => group.fields || [] )
+ .map( ( field ) => [ field.name, field ] )
+ )
+ : {};
const fieldValue = getFieldValue( fields, fieldName );
+ const fieldType = mergedFields[ fieldName ]?.type;
+
if ( typeof fieldValue === 'object' && fieldValue !== null ) {
let value = '';
@@ -59,7 +69,7 @@ registerBlockBindingsSource( {
}
result[ attribute ] = value;
- } else if ( typeof fieldValue === 'number' ) {
+ } else if ( 'number' === typeof fieldValue ) {
if ( attribute === 'content' ) {
result[ attribute ] = fieldValue.toString() || '';
} else {
@@ -69,6 +79,12 @@ registerBlockBindingsSource( {
attribute
);
}
+ } else if ( 'date_picker' === fieldType && fieldValue ) {
+ result[ attribute ] =
+ dateI18n(
+ mergedFields[ fieldName ]?.display_format,
+ fieldValue
+ ) || '';
} else {
result[ attribute ] = fieldValue || '';
}
diff --git a/assets/src/sass/_forms.scss b/assets/src/sass/_forms.scss
index 7cb7883d..c9430736 100644
--- a/assets/src/sass/_forms.scss
+++ b/assets/src/sass/_forms.scss
@@ -313,5 +313,4 @@ p.submit .acf-spinner {
margin: 0;
}
}
-}
-
+}
\ No newline at end of file
diff --git a/includes/admin/beta-features.php b/includes/admin/beta-features.php
index 1051fd58..9baebbe4 100644
--- a/includes/admin/beta-features.php
+++ b/includes/admin/beta-features.php
@@ -35,8 +35,7 @@ class SCF_Admin_Beta_Features {
* @return void
*/
public function __construct() {
- // Temporarily disabled - will be enabled when beta feature is ready
- // add_action( 'admin_menu', array( $this, 'admin_menu' ), 20 );
+ add_action( 'admin_menu', array( $this, 'admin_menu' ), 20 );
}
/**
@@ -78,26 +77,6 @@ public function get_beta_features() {
return $this->beta_features;
}
- /**
- * Localizes the beta features data.
- *
- * @since SCF 6.5.0
- *
- * @return void
- */
- public function localize_beta_features() {
- $beta_features = array();
- foreach ( $this->get_beta_features() as $name => $beta_feature ) {
- $beta_features[ $name ] = $beta_feature->is_enabled();
- }
-
- acf_localize_data(
- array(
- 'betaFeatures' => $beta_features,
- )
- );
- }
-
/**
* This function will add the SCF beta features menu item to the WP admin
*
@@ -115,7 +94,7 @@ public function admin_menu() {
$page = add_submenu_page( 'edit.php?post_type=acf-field-group', __( 'Beta Features', 'secure-custom-fields' ), __( 'Beta Features', 'secure-custom-fields' ), acf_get_setting( 'capability' ), 'scf-beta-features', array( $this, 'html' ) );
add_action( 'load-' . $page, array( $this, 'load' ) );
- add_action( 'admin_enqueue_scripts', array( $this, 'localize_beta_features' ), 20 );
+ add_action( 'admin_enqueue_scripts', array( $this, 'add_beta_features_script' ), 20 );
}
/**
@@ -155,7 +134,7 @@ public function admin_body_class( $classes ) {
*/
private function include_beta_features() {
acf_include( 'includes/admin/beta-features/class-scf-beta-feature.php' );
- acf_include( 'includes/admin/beta-features/class-scf-beta-feature-editor-sidebar.php' );
+ acf_include( 'includes/admin/beta-features/class-scf-beta-feature-connect-fields.php' );
add_action( 'scf/include_admin_beta_features', array( $this, 'register_beta_features' ) );
@@ -170,7 +149,7 @@ private function include_beta_features() {
* @return void
*/
public function register_beta_features() {
- scf_register_admin_beta_feature( 'SCF_Admin_Beta_Feature_Editor_Sidebar' );
+ scf_register_admin_beta_feature( 'SCF_Admin_Beta_Feature_Connect_Fields' );
}
/**
@@ -255,6 +234,28 @@ public function metabox_html( $post, $metabox ) {
acf_nonce_input( $beta_feature->name );
echo '';
}
+
+ /**
+ * Adds the editor sidebar script to the page.
+ *
+ * @since SCF 6.5.0
+ *
+ * @return void
+ */
+ public function add_beta_features_script() {
+ // Check if the connected fields feature is enabled
+
+ $script = 'window.scf = window.scf || {};
+window.scf = window.scf || {};
+window.scf.betaFeatures = window.scf.betaFeatures || {};';
+ foreach ( $this->get_beta_features() as $name => $beta_feature ) {
+ if ( $beta_feature->is_enabled() ) {
+ $script .= sprintf( 'window.scf.betaFeatures.%s = true;', esc_js( $name ) );
+ }
+ }
+
+ wp_add_inline_script( 'wp-block-editor', $script, 'before' );
+ }
}
// initialize
diff --git a/includes/admin/beta-features/class-scf-beta-feature-connect-fields.php b/includes/admin/beta-features/class-scf-beta-feature-connect-fields.php
new file mode 100644
index 00000000..5f09643e
--- /dev/null
+++ b/includes/admin/beta-features/class-scf-beta-feature-connect-fields.php
@@ -0,0 +1,38 @@
+name = 'connect_fields';
+ $this->title = __( 'Connect Fields', 'secure-custom-fields' );
+ $this->description = __( 'Connects field to binding compatible blocks.', 'secure-custom-fields' );
+ }
+ }
+endif;
diff --git a/includes/rest-api/class-acf-rest-types-endpoint.php b/includes/rest-api/class-acf-rest-types-endpoint.php
index d1867cbd..7a75c86d 100644
--- a/includes/rest-api/class-acf-rest-types-endpoint.php
+++ b/includes/rest-api/class-acf-rest-types-endpoint.php
@@ -37,11 +37,12 @@ public function __construct() {
* @return void
*/
public function register_extra_fields() {
- if ( ! (bool) get_option( 'scf_beta_feature_editor_sidebar_enabled', false ) ) {
+ if ( ! (bool) get_option( 'scf_beta_feature_connect_fields_enabled', false ) ) {
return;
}
+ $post_types = get_post_types( array( 'show_in_rest' => true ) );
register_rest_field(
- 'type',
+ $post_types,
'scf_field_groups',
array(
'get_callback' => array( $this, 'get_scf_fields' ),
@@ -50,16 +51,19 @@ public function register_extra_fields() {
);
}
- /**
- * Get SCF fields for a post type.
- *
- * @since SCF 6.5.0
- *
- * @param array $post_type_object The post type object.
- * @return array Array of field data.
- */
+ /**
+ * Get SCF fields for a post type.
+ *
+ * @since 6.5.0
+ *
+ * @param array $post_type_object The post type object.
+ * @return array Array of field data.
+ */
public function get_scf_fields( $post_type_object ) {
- $post_type = $post_type_object['slug'];
+ if ( ! isset( $post_type_object['id'] ) || ! isset( $post_type_object['type'] ) ) {
+ return array();
+ }
+ $post_type = $post_type_object['type'];
$field_groups = acf_get_field_groups( array( 'post_type' => $post_type ) );
$field_groups_data = array();
@@ -69,8 +73,10 @@ public function get_scf_fields( $post_type_object ) {
foreach ( $fields as $field ) {
$group_fields[] = array(
- 'label' => $field['label'],
- 'type' => $field['type'],
+ 'label' => $field['label'],
+ 'type' => $field['type'],
+ 'name' => $field['name'],
+ 'display_format' => isset( $field['display_format'] ) ? $field['display_format'] : '',
);
}
diff --git a/package-lock.json b/package-lock.json
index 008e3323..7219e9a2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,6 +5,7 @@
"packages": {
"": {
"dependencies": {
+ "@wordpress/icons": "^10.26.0",
"md5": "^2.3.0"
},
"devDependencies": {
@@ -1848,7 +1849,6 @@
"version": "7.25.7",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz",
"integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==",
- "dev": true,
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
@@ -4006,6 +4006,12 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/prop-types": {
+ "version": "15.7.15",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz",
+ "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==",
+ "license": "MIT"
+ },
"node_modules/@types/qs": {
"version": "6.9.18",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz",
@@ -4020,6 +4026,25 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/react": {
+ "version": "18.3.23",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.23.tgz",
+ "integrity": "sha512-/LDXMQh55EzZQ0uVAZmKKhfENivEvWz6E+EYzh+/MCjMhNsotd+ZHhBGIjFDTi6+fz0OhQQQLbTgdQIxxCsC0w==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/prop-types": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "18.3.7",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz",
+ "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^18.0.0"
+ }
+ },
"node_modules/@types/retry": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
@@ -4900,6 +4925,48 @@
"@playwright/test": ">=1"
}
},
+ "node_modules/@wordpress/element": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/@wordpress/element/-/element-6.26.0.tgz",
+ "integrity": "sha512-IlzQE7oVG4fuwRA5N7vhnr57kvf1HS08kwJwP+EC/olREnFEi8XOIeDa7rAEVXNAx2xeoLKQ6+K7Banp7+c6GA==",
+ "license": "GPL-2.0-or-later",
+ "dependencies": {
+ "@babel/runtime": "7.25.7",
+ "@types/react": "^18.2.79",
+ "@types/react-dom": "^18.2.25",
+ "@wordpress/escape-html": "^3.26.0",
+ "change-case": "^4.1.2",
+ "is-plain-object": "^5.0.0",
+ "react": "^18.3.0",
+ "react-dom": "^18.3.0"
+ },
+ "engines": {
+ "node": ">=18.12.0",
+ "npm": ">=8.19.2"
+ }
+ },
+ "node_modules/@wordpress/element/node_modules/is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@wordpress/escape-html": {
+ "version": "3.26.0",
+ "resolved": "https://registry.npmjs.org/@wordpress/escape-html/-/escape-html-3.26.0.tgz",
+ "integrity": "sha512-SQfSmUOMP32duStoxvrkydCtD/ELyNXpAwkE414swo8AQAKxBJMQDYE3PZy1uZ6YCtbSX7EHHAX9G1EeoHUzgg==",
+ "license": "GPL-2.0-or-later",
+ "dependencies": {
+ "@babel/runtime": "7.25.7"
+ },
+ "engines": {
+ "node": ">=18.12.0",
+ "npm": ">=8.19.2"
+ }
+ },
"node_modules/@wordpress/eslint-plugin": {
"version": "22.7.0",
"resolved": "https://registry.npmjs.org/@wordpress/eslint-plugin/-/eslint-plugin-22.7.0.tgz",
@@ -4990,6 +5057,21 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/@wordpress/icons": {
+ "version": "10.26.0",
+ "resolved": "https://registry.npmjs.org/@wordpress/icons/-/icons-10.26.0.tgz",
+ "integrity": "sha512-7XPcJbvy4s8USfcuMxdVE6qTaEYzRv0+TZa6Epbe61HFrvaMl9X0Mr+jcCyQ7qBp4jKHfHInWfywNeYOxc5SMg==",
+ "license": "GPL-2.0-or-later",
+ "dependencies": {
+ "@babel/runtime": "7.25.7",
+ "@wordpress/element": "^6.26.0",
+ "@wordpress/primitives": "^4.26.0"
+ },
+ "engines": {
+ "node": ">=18.12.0",
+ "npm": ">=8.19.2"
+ }
+ },
"node_modules/@wordpress/jest-console": {
"version": "8.21.0",
"resolved": "https://registry.npmjs.org/@wordpress/jest-console/-/jest-console-8.21.0.tgz",
@@ -5073,6 +5155,24 @@
"prettier": ">=3"
}
},
+ "node_modules/@wordpress/primitives": {
+ "version": "4.26.0",
+ "resolved": "https://registry.npmjs.org/@wordpress/primitives/-/primitives-4.26.0.tgz",
+ "integrity": "sha512-vmqKlqQxyv9XDKeIntd70SpRJeU0uXWj6iQDZmmbsOcDWL3UNIOFeN5dB25vDeyoseQ+r+JNnoU+hq7cpQa/8Q==",
+ "license": "GPL-2.0-or-later",
+ "dependencies": {
+ "@babel/runtime": "7.25.7",
+ "@wordpress/element": "^6.26.0",
+ "clsx": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=18.12.0",
+ "npm": ">=8.19.2"
+ },
+ "peerDependencies": {
+ "react": "^18.0.0"
+ }
+ },
"node_modules/@wordpress/priority-queue": {
"version": "3.22.0",
"resolved": "https://registry.npmjs.org/@wordpress/priority-queue/-/priority-queue-3.22.0.tgz",
@@ -7358,7 +7458,6 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz",
"integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"pascal-case": "^3.1.2",
@@ -7443,7 +7542,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz",
"integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==",
- "dev": true,
"license": "MIT",
"dependencies": {
"no-case": "^3.0.4",
@@ -7472,7 +7570,6 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz",
"integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==",
- "dev": true,
"license": "MIT",
"dependencies": {
"camel-case": "^4.1.2",
@@ -7730,6 +7827,15 @@
"node": ">=6"
}
},
+ "node_modules/clsx": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
@@ -7906,7 +8012,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz",
"integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"no-case": "^3.0.4",
@@ -8467,6 +8572,12 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "license": "MIT"
+ },
"node_modules/cwd": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/cwd/-/cwd-0.10.0.tgz",
@@ -9059,7 +9170,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz",
"integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==",
- "dev": true,
"license": "MIT",
"dependencies": {
"no-case": "^3.0.4",
@@ -11740,7 +11850,6 @@
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz",
"integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==",
- "dev": true,
"license": "MIT",
"dependencies": {
"capital-case": "^1.0.4",
@@ -14026,7 +14135,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "dev": true,
"license": "MIT"
},
"node_modules/js-yaml": {
@@ -14626,7 +14734,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
- "dev": true,
"license": "MIT",
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
@@ -14639,7 +14746,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
"integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"tslib": "^2.0.3"
@@ -15313,7 +15419,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
"integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"lower-case": "^2.0.2",
@@ -15970,7 +16075,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
"integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==",
- "dev": true,
"license": "MIT",
"dependencies": {
"dot-case": "^3.0.4",
@@ -16052,7 +16156,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",
"integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==",
- "dev": true,
"license": "MIT",
"dependencies": {
"no-case": "^3.0.4",
@@ -16063,7 +16166,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz",
"integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"dot-case": "^3.0.4",
@@ -17327,7 +17429,6 @@
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
- "dev": true,
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0"
@@ -17340,9 +17441,7 @@
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
- "dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
@@ -17616,8 +17715,7 @@
"node_modules/regenerator-runtime": {
"version": "0.14.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
- "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
- "dev": true
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
},
"node_modules/regenerator-transform": {
"version": "0.15.2",
@@ -18116,9 +18214,7 @@
"version": "0.23.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
- "dev": true,
"license": "MIT",
- "peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
}
@@ -18242,7 +18338,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz",
"integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"no-case": "^3.0.4",
@@ -18617,7 +18712,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz",
"integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"dot-case": "^3.0.4",
@@ -20359,7 +20453,6 @@
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
- "dev": true,
"license": "0BSD"
},
"node_modules/tsutils": {
@@ -20695,7 +20788,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz",
"integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"tslib": "^2.0.3"
@@ -20705,7 +20797,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz",
"integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==",
- "dev": true,
"license": "MIT",
"dependencies": {
"tslib": "^2.0.3"
diff --git a/package.json b/package.json
index b315ec42..8ff50f4e 100644
--- a/package.json
+++ b/package.json
@@ -11,6 +11,7 @@
"watch": "webpack --watch"
},
"dependencies": {
+ "@wordpress/icons": "^10.26.0",
"md5": "^2.3.0"
},
"devDependencies": {
diff --git a/secure-custom-fields.php b/secure-custom-fields.php
index 0622d80f..7a6a8513 100644
--- a/secure-custom-fields.php
+++ b/secure-custom-fields.php
@@ -878,7 +878,7 @@ function scf_plugin_deactivated_notice() {
function scf_plugin_uninstall() {
// List of known beta features.
$beta_features = array(
- 'editor_sidebar',
+ 'connect_fields',
);
foreach ( $beta_features as $beta_feature ) {