PluginProbe
User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor / 4.0.3
User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor v4.0.3
4.0.3 4.0.2 4.0.1 4.0.0 3.16.6 3.16.5 3.16.4 3.16.3 3.16.2 3.16.1 3.16.0 3.15.9 3.9.9 3.9.5 3.9.6 3.9.7 3.9.8 1.1.7 1.1.8 1.1.9 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 All 341 releases
profile-builder / form-builder / blocks / src / components / BlockToolbarDelete.js

BlockToolbarDelete.js in User Profile Builder – Beautiful User Registration Forms, User Profiles & User Role Editor 4.0.3, at form-builder/blocks/src/components/BlockToolbarDelete.js

102 lines 4.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Toolbar Delete button on PB form CPTs (replaces Options ⋮; CSS hides the menu).
3 * Form-only remove — global row stays. Hidden for mandatoryTypes / !canRemoveBlock.
4 */
5
6 import { addFilter } from '@wordpress/hooks';
7 import { __ } from '@wordpress/i18n';
8 import { BlockControls } from '@wordpress/block-editor';
9 import { ToolbarGroup, ToolbarButton } from '@wordpress/components';
10 import { useSelect } from '@wordpress/data';
11 import { removeBlocksWithUndo } from '../lib/removeBlocksWithUndo';
12
13 // Mandatory default field types whose Delete affordance must never appear —
14 // same source and fallback as the Existing Fields panel's MANDATORY_DEFAULT_TYPES
15 // (window.wppbFb.mandatoryTypes, populated by the inline-script bridge before
16 // this bundle inits). Falls back to the hardcoded triple if the bridge is absent.
17 const MANDATORY_FIELD_TYPES = new Set(
18 ( typeof window !== 'undefined' && window.wppbFb &&
19 Array.isArray( window.wppbFb.mandatoryTypes ) && window.wppbFb.mandatoryTypes.length )
20 ? window.wppbFb.mandatoryTypes
21 : [ 'Default - Username', 'Default - E-mail', 'Default - Password' ]
22 );
23
24 // Resolve a block name to its PB field-type label via the canonical
25 // blockToFieldType map (single home under conditionalFields), then test for a
26 // mandatory type. Read lazily (not memoized at module load) so it tracks the
27 // bridge like BaseFieldEdit's getMetaNameConfig() does.
28 function isMandatoryFieldType( blockName ) {
29 const fb = ( typeof window !== 'undefined' && window.wppbFb ) || {};
30 const map = ( fb.conditionalFields && fb.conditionalFields.blockToFieldType ) || {};
31 return MANDATORY_FIELD_TYPES.has( map[ blockName ] );
32 }
33
34 // Inline trash glyph — matches the FormPreviewButton convention of inlining
35 // SVGs (fill via inline style, which also beats Gutenberg's block-icon
36 // `svg { fill: currentColor }` override) instead of a @wordpress/icons
37 // dependency that would pull the package into the bundle.
38 const TrashIcon = () => (
39 <svg
40 width="24"
41 height="24"
42 viewBox="0 0 24 24"
43 xmlns="http://www.w3.org/2000/svg"
44 aria-hidden="true"
45 focusable="false"
46 >
47 <path
48 style={ { fill: 'currentColor' } }
49 d="M9 3h6v2h5v2H4V5h5V3zm-3 6h2v9H6V9zm5 0h2v9h-2V9zm5 0h2v9h-2V9zM5 7h14l-1 13a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1L5 7z"
50 />
51 </svg>
52 );
53
54 function DeleteToolbarControl( { clientId } ) {
55 const canRemove = useSelect(
56 ( select ) => select( 'core/block-editor' ).canRemoveBlock( clientId ),
57 [ clientId ]
58 );
59
60 if ( ! canRemove ) return null;
61
62 return (
63 <BlockControls>
64 <ToolbarGroup>
65 <ToolbarButton
66 icon={ <TrashIcon /> }
67 label={ __( 'Remove field', 'profile-builder' ) }
68 // Snackbar-Undo instead of a silent removeBlock: global
69 // undo is disabled in this editor, so this is the only
70 // in-session recovery path.
71 onClick={ () => removeBlocksWithUndo( [ clientId ] ) }
72 />
73 </ToolbarGroup>
74 </BlockControls>
75 );
76 }
77
78 const withDeleteToolbarButton = ( BlockEdit ) => ( props ) => {
79 const { name, isSelected, clientId } = props;
80 const isPbBlock = typeof name === 'string' && name.startsWith( 'profile-builder/' );
81 // Field-type gate: never add the Delete button to a mandatory field. Cheap,
82 // hook-free, so it's evaluated here in the wrapper rather than inside
83 // DeleteToolbarControl (which then never mounts for mandatory fields).
84 const showDelete = isPbBlock && isSelected && ! isMandatoryFieldType( name );
85
86 return (
87 <>
88 <BlockEdit { ...props } />
89 { showDelete && <DeleteToolbarControl clientId={ clientId } /> }
90 </>
91 );
92 };
93
94 // editor.BlockEdit filters apply at render time (not registration time), so —
95 // unlike the blocks.registerBlockType filters at the top of index.js — this
96 // import's position relative to the block imports is not load-bearing.
97 addFilter(
98 'editor.BlockEdit',
99 'profile-builder/block-toolbar-delete',
100 withDeleteToolbarButton
101 );
102