PluginProbe ʕ •ᴥ•ʔ
GenerateBlocks / 2.2.0
GenerateBlocks v2.2.0
trunk 1.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.7.0 1.7.1 1.7.2 1.7.3 1.8.0 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 2.0.0 2.0.1 2.0.2 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.3.0
generateblocks / src / blocks / element / components / BlockSettings.jsx
generateblocks / src / blocks / element / components Last commit date
BlockSettings.jsx 1 year ago InlineBackgroundImage.jsx 1 year ago
BlockSettings.jsx
272 lines
1 import { __ } from '@wordpress/i18n';
2 import { Button, BaseControl, Notice } from '@wordpress/components';
3 import { useState } from '@wordpress/element';
4 import { createBlock, cloneBlock } from '@wordpress/blocks';
5 import { useDispatch, useSelect } from '@wordpress/data';
6 import { store as blockEditorStore } from '@wordpress/block-editor';
7
8 import { OpenPanel, IconModal } from '@edge22/components';
9
10 import {
11 ApplyFilters,
12 URLControls,
13 TagNameControl,
14 GridColumnSelector,
15 gridColumnLayouts as layouts,
16 DynamicTagsOnboarder,
17 } from '@components/index.js';
18 import { useBlockStyles } from '@hooks/useBlockStyles';
19 import { getElementType } from '../utils/getElementType';
20 import { InlineBackgroundImage } from './InlineBackgroundImage';
21
22 export function BlockSettings( {
23 getStyleValue,
24 onStyleChange,
25 name,
26 attributes,
27 setAttributes,
28 clientId,
29 htmlAttributes,
30 styles,
31 context,
32 } ) {
33 const {
34 tagName,
35 } = attributes;
36
37 const [ openShapeLibrary, setOpenShapeLibrary ] = useState( false );
38 const {
39 insertBlocks,
40 removeBlock,
41 } = useDispatch( blockEditorStore );
42 const { getBlock } = useSelect( ( select ) => select( blockEditorStore ), [] );
43 const {
44 atRule,
45 } = useBlockStyles();
46
47 const panelProps = {
48 name,
49 attributes,
50 setAttributes,
51 clientId,
52 getStyleValue,
53 onStyleChange,
54 };
55
56 return (
57 <ApplyFilters
58 name="generateblocks.editor.blockControls"
59 blockName={ name }
60 getStyleValue={ getStyleValue }
61 onStyleChange={ onStyleChange }
62 currentAtRule={ atRule }
63 attributes={ attributes }
64 setAttributes={ setAttributes }
65 >
66 <OpenPanel
67 { ...panelProps }
68 shouldRender={ 'a' === tagName && '' === atRule }
69 panelId="link-destination"
70 >
71 <URLControls
72 label={ __( 'Link Destination', 'generateblocks' ) }
73 setAttributes={ setAttributes }
74 htmlAttributes={ htmlAttributes }
75 context={ context }
76 tagName={ tagName }
77 />
78 </OpenPanel>
79
80 <OpenPanel
81 { ...panelProps }
82 shouldRender={
83 'grid' === getStyleValue( 'display' ) &&
84 (
85 'grid' === getStyleValue( 'display', atRule ) ||
86 '' === getStyleValue( 'display', atRule )
87 )
88 }
89 panelId="grid"
90 >
91 <BaseControl
92 label={ __( 'Layout', 'generateblocks' ) }
93 id="grid-template-columns"
94 >
95 <GridColumnSelector
96 value={ getStyleValue( 'gridTemplateColumns', atRule ) }
97 onClick={ ( value ) => {
98 if ( value === getStyleValue( 'gridTemplateColumns', atRule ) ) {
99 // If the same layout is clicked, remove the layout.
100 onStyleChange( 'gridTemplateColumns', '', atRule );
101 return;
102 }
103
104 onStyleChange( 'gridTemplateColumns', value, atRule );
105
106 if ( '' !== atRule ) {
107 // Don't add/remove blocks for at rules.
108 return;
109 }
110
111 const selectedLayout = layouts.find( ( { layout } ) => layout === value );
112 const selectedLayoutDivCount = selectedLayout?.divs || 0;
113 const innerBlocksCount = getBlock( clientId ).innerBlocks.length;
114
115 if ( selectedLayoutDivCount > innerBlocksCount ) {
116 const lastInnerBlock = getBlock( clientId ).innerBlocks[ innerBlocksCount - 1 ];
117
118 if ( lastInnerBlock ) {
119 const newBlockCount = selectedLayoutDivCount - innerBlocksCount;
120 const newBlocksToInsert = [];
121
122 for ( let i = 0; i < newBlockCount; i++ ) {
123 const clonedBlock = cloneBlock(
124 lastInnerBlock,
125 {
126 uniqueId: '',
127 }
128 );
129 newBlocksToInsert.push( clonedBlock );
130 }
131
132 insertBlocks( newBlocksToInsert, innerBlocksCount, clientId, false );
133 }
134 } else if ( selectedLayoutDivCount < innerBlocksCount ) {
135 const blocksToRemove = getBlock( clientId )?.innerBlocks
136 .slice( selectedLayoutDivCount )
137 .filter( ( block ) => (
138 'generateblocks/element' === block.name &&
139 0 === block.innerBlocks.length
140 ) );
141
142 if ( blocksToRemove.length ) {
143 blocksToRemove.forEach( ( block ) => {
144 removeBlock( block.clientId, false );
145 } );
146 }
147 }
148 } }
149 />
150 </BaseControl>
151 </OpenPanel>
152
153 <OpenPanel
154 { ...panelProps }
155 shouldRender={ '' === atRule }
156 panelId="shapes"
157 >
158 <BaseControl
159 label={ __( 'Shape', 'generateblocks' ) }
160 id="shape"
161 >
162 <Button
163 variant="secondary"
164 size="compact"
165 onClick={ () => setOpenShapeLibrary( true ) }
166 style={ { display: 'block' } }
167 >
168 { __( 'Open Shape Library', 'generateblocks' ) }
169 </Button>
170 </BaseControl>
171
172 { !! openShapeLibrary && (
173 <IconModal
174 title={ __( 'Shape Library', 'generateblocks' ) }
175 iconType="divider"
176 setIsOpen={ setOpenShapeLibrary }
177 icons={ generateBlocksInfo.svgShapes }
178 onChange={ ( value ) => {
179 setAttributes( {
180 styles: {
181 ...styles,
182 position: 'relative',
183 },
184 } );
185
186 const newShapeBlock = createBlock(
187 'generateblocks/shape',
188 {
189 html: value,
190 className: 'gb-shape--divider',
191 styles: {
192 position: 'absolute',
193 bottom: '0',
194 left: '0',
195 right: '0',
196 overflowX: 'hidden',
197 overflowY: 'hidden',
198 pointerEvents: 'none',
199 color: '#000000',
200 svg: {
201 fill: 'currentColor',
202 width: '100%',
203 },
204 },
205 },
206 );
207
208 insertBlocks(
209 newShapeBlock,
210 0,
211 clientId,
212 true
213 );
214
215 setOpenShapeLibrary( false );
216 } }
217 />
218 ) }
219 </OpenPanel>
220
221 <OpenPanel
222 { ...panelProps }
223 shouldRender={ 'container' === getElementType( tagName ) && '' === atRule }
224 panelId="inline-background-image"
225 >
226 <InlineBackgroundImage
227 label={ __( 'Inline Background Image', 'generateblocks' ) }
228 htmlAttributes={ htmlAttributes }
229 setAttributes={ setAttributes }
230 styles={ styles }
231 onStyleChange={ onStyleChange }
232 context={ context }
233 />
234 </OpenPanel>
235
236 <OpenPanel
237 { ...panelProps }
238 panelId="settings"
239 >
240 { '' === atRule && (
241 <>
242 <TagNameControl
243 blockName="generateblocks/element"
244 value={ tagName }
245 onChange={ ( value ) => {
246 setAttributes( { tagName: value } );
247
248 if ( 'a' === value && ! styles?.display ) {
249 onStyleChange( 'display', 'block' );
250 }
251 } }
252 />
253
254 { 'a' === tagName && (
255 <BaseControl>
256 <Notice
257 status="warning"
258 isDismissible={ false }
259 >
260 { __( 'This container is now a link element. Be sure not to add any interactive elements inside of it, like buttons or other links.', 'generateblocks' ) }
261 </Notice>
262 </BaseControl>
263 ) }
264 </>
265 ) }
266 </OpenPanel>
267
268 <DynamicTagsOnboarder />
269 </ApplyFilters>
270 );
271 }
272