PluginProbe ʕ •ᴥ•ʔ
FrontBlocks for Gutenberg/GeneratePress / 1.5.2
FrontBlocks for Gutenberg/GeneratePress v1.5.2
1.5.2 1.5.1 1.4.0 1.5.0 trunk 0.2.0 0.2.1 0.2.2 0.2.3 0.2.4 0.2.5 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.1.0 1.2.0 1.2.1 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 ci-artifacts
frontblocks / assets / container-edge-alignment / frontblocks-edge-alignment-option.jsx
frontblocks / assets / container-edge-alignment Last commit date
frontblocks-edge-alignment-frontend.js 9 months ago frontblocks-edge-alignment-option.jsx 2 months ago frontblocks-edge-alignment-panel.css 1 week ago frontblocks-edge-alignment.css 1 week ago frontblocks-edge-alignment.js 2 months ago
frontblocks-edge-alignment-option.jsx
185 lines
1 const { addFilter } = wp.hooks;
2 const { createHigherOrderComponent } = wp.compose;
3 const { Fragment } = wp.element;
4 const { InspectorControls } = wp.blockEditor;
5 const { PanelBody, SelectControl } = wp.components;
6 const { __ } = wp.i18n;
7
8 const GB_BLOCKS = [ 'generateblocks/container', 'generateblocks/element' ];
9 const NATIVE_BLOCKS = [ 'core/group', 'core/columns' ];
10 const ALL_SUPPORTED_BLOCKS = [ ...GB_BLOCKS, ...NATIVE_BLOCKS ];
11
12 /**
13 * Add custom attributes to supported blocks.
14 */
15 function addEdgeAlignmentAttributes( settings, name ) {
16 if ( ! ALL_SUPPORTED_BLOCKS.includes( name ) ) {
17 return settings;
18 }
19
20 settings.attributes = Object.assign( settings.attributes, {
21 frblEdgeAlignment: {
22 type: 'string',
23 default: '',
24 },
25 } );
26
27 return settings;
28 }
29
30 addFilter(
31 'blocks.registerBlockType',
32 'frontblocks/edge-alignment-attributes',
33 addEdgeAlignmentAttributes
34 );
35
36 /**
37 * Check if a GenerateBlocks container uses the global container width.
38 * Only containers with var(--gb-container-width) should have edge alignment.
39 */
40 function usesGlobalMaxWidth( attributes ) {
41 if ( ! attributes.styles || typeof attributes.styles !== 'object' ) {
42 return false;
43 }
44
45 if (
46 attributes.styles.maxWidth &&
47 attributes.styles.maxWidth.includes( 'var(--gb-container-width)' )
48 ) {
49 if (
50 attributes.styles.marginLeft === 'auto' &&
51 attributes.styles.marginRight === 'auto'
52 ) {
53 return true;
54 }
55 }
56
57 return false;
58 }
59
60 /**
61 * Check if a native block uses a constrained (centered, max-width) layout.
62 * Matches core/group and core/columns with constrained layout or inherited layout.
63 */
64 function usesConstrainedLayout( attributes ) {
65 // No explicit layout — inherits from theme, which is typically constrained.
66 if ( ! attributes.layout ) {
67 return true;
68 }
69 return attributes.layout.type === 'constrained';
70 }
71
72 /**
73 * Add edge alignment controls to supported block inspector panels.
74 */
75 const withEdgeAlignmentControls = createHigherOrderComponent( ( BlockEdit ) => {
76 return ( props ) => {
77 if ( ! ALL_SUPPORTED_BLOCKS.includes( props.name ) ) {
78 return <BlockEdit { ...props } />;
79 }
80
81 const { attributes, setAttributes } = props;
82 const { frblEdgeAlignment } = attributes;
83 const isGBBlock = GB_BLOCKS.includes( props.name );
84
85 // Guard: only show panel when the block uses a centered/constrained layout.
86 const shouldShowPanel = isGBBlock
87 ? usesGlobalMaxWidth( attributes )
88 : usesConstrainedLayout( attributes );
89
90 if ( ! shouldShowPanel ) {
91 return <BlockEdit { ...props } />;
92 }
93
94 return (
95 <Fragment>
96 <BlockEdit { ...props } />
97 <InspectorControls>
98 <PanelBody
99 title={ __( 'FrontBlocks Edge Alignment', 'frontblocks' ) }
100 initialOpen={ false }
101 className="frbl-edge-alignment-panel"
102 >
103 <p className="frbl-edge-alignment-description">
104 { __(
105 'Remove padding from one side to create an edge-to-edge effect. Perfect for asymmetric layouts where content extends to the browser edge on one side.',
106 'frontblocks'
107 ) }
108 </p>
109 <SelectControl
110 label={ __( 'Align to Edge', 'frontblocks' ) }
111 value={ frblEdgeAlignment }
112 options={ [
113 {
114 label: __( 'None', 'frontblocks' ),
115 value: '',
116 },
117 {
118 label: __( 'Remove Left Padding', 'frontblocks' ),
119 value: 'left',
120 },
121 {
122 label: __( 'Remove Right Padding', 'frontblocks' ),
123 value: 'right',
124 },
125 ] }
126 onChange={ ( value ) =>
127 setAttributes( { frblEdgeAlignment: value } )
128 }
129 help={ __(
130 'Choose which side should extend to the browser edge.',
131 'frontblocks'
132 ) }
133 />
134 </PanelBody>
135 </InspectorControls>
136 </Fragment>
137 );
138 };
139 }, 'withEdgeAlignmentControls' );
140
141 addFilter(
142 'editor.BlockEdit',
143 'frontblocks/edge-alignment-controls',
144 withEdgeAlignmentControls
145 );
146
147 /**
148 * Add visual feedback classes in the editor.
149 */
150 const addEdgeAlignmentClass = createHigherOrderComponent( ( BlockListBlock ) => {
151 return ( props ) => {
152 if ( ! ALL_SUPPORTED_BLOCKS.includes( props.name ) ) {
153 return <BlockListBlock { ...props } />;
154 }
155
156 const { attributes } = props;
157 const { frblEdgeAlignment } = attributes;
158
159 let additionalClasses = '';
160
161 if ( frblEdgeAlignment === 'left' ) {
162 additionalClasses = ' frbl-edge-left';
163 } else if ( frblEdgeAlignment === 'right' ) {
164 additionalClasses = ' frbl-edge-right';
165 }
166
167 if ( additionalClasses ) {
168 return (
169 <BlockListBlock
170 { ...props }
171 className={ props.className + additionalClasses }
172 />
173 );
174 }
175
176 return <BlockListBlock { ...props } />;
177 };
178 }, 'addEdgeAlignmentClass' );
179
180 addFilter(
181 'editor.BlockListBlock',
182 'frontblocks/edge-alignment-class',
183 addEdgeAlignmentClass
184 );
185