/
layout-child.js
138 lines (127 loc) · 3.49 KB
/
layout-child.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/**
* WordPress dependencies
*/
import { useInstanceId } from '@wordpress/compose';
import { useSelect } from '@wordpress/data';
/**
* Internal dependencies
*/
import { store as blockEditorStore } from '../store';
import { useStyleOverride } from './utils';
import { useLayout } from '../components/block-list/layout';
import { GridVisualizer, GridItemResizer } from '../components/grid-visualizer';
function useBlockPropsChildLayoutStyles( { style } ) {
const shouldRenderChildLayoutStyles = useSelect( ( select ) => {
return ! select( blockEditorStore ).getSettings().disableLayoutStyles;
} );
const layout = style?.layout ?? {};
const { selfStretch, flexSize, columnSpan, rowSpan, parentColumnWidth } =
layout;
const id = useInstanceId( useBlockPropsChildLayoutStyles );
const selector = `.wp-container-content-${ id }`;
let css = '';
if ( shouldRenderChildLayoutStyles ) {
if ( selfStretch === 'fixed' && flexSize ) {
css = `${ selector } {
flex-basis: ${ flexSize };
box-sizing: border-box;
}`;
} else if ( selfStretch === 'fill' ) {
css = `${ selector } {
flex-grow: 1;
}`;
} else if ( columnSpan ) {
css = `${ selector } {
grid-column: span ${ columnSpan };
}`;
}
/**
* If parentColumnWidth is set, the grid is responsive
* so a container query is needed for the span to resize.
*/
if ( columnSpan && parentColumnWidth ) {
// Calculate the container query value.
const columnSpanNumber = parseInt( columnSpan );
let parentColumnValue = parseFloat( parentColumnWidth );
/**
* 12rem is the default minimumColumnWidth value.
* If parentColumnValue is not a number, default to 12.
*/
if ( isNaN( parentColumnValue ) ) {
parentColumnValue = 12;
}
let parentColumnUnit = parentColumnWidth?.replace(
parentColumnValue,
''
);
/**
* Check that parent column unit is either 'px', 'rem' or 'em'.
* If not, default to 'rem'.
*/
if ( ! [ 'px', 'rem', 'em' ].includes( parentColumnUnit ) ) {
parentColumnUnit = 'rem';
}
const defaultGapValue = parentColumnUnit === 'px' ? 24 : 1.5;
const containerQueryValue =
columnSpanNumber * parentColumnValue +
( columnSpanNumber - 1 ) * defaultGapValue;
css += `@container (max-width: ${ containerQueryValue }${ parentColumnUnit }) {
${ selector } {
grid-column: 1 / -1;
}
}`;
}
if ( rowSpan ) {
css += `${ selector } {
grid-row: span ${ rowSpan };
}`;
}
}
useStyleOverride( { css } );
// Only attach a container class if there is generated CSS to be attached.
if ( ! css ) {
return;
}
// Attach a `wp-container-content` id-based classname.
return { className: `wp-container-content-${ id }` };
}
function ChildLayoutControlsPure( { clientId, style, setAttributes } ) {
const parentLayout = useLayout() || {};
const rootClientId = useSelect(
( select ) => {
return select( blockEditorStore ).getBlockRootClientId( clientId );
},
[ clientId ]
);
if ( parentLayout.type !== 'grid' ) {
return null;
}
return (
<>
<GridVisualizer clientId={ rootClientId } />
<GridItemResizer
clientId={ clientId }
onChange={ ( { rowSpan, columnSpan } ) => {
setAttributes( {
style: {
...style,
layout: {
...style?.layout,
rowSpan,
columnSpan,
},
},
} );
} }
/>
</>
);
}
export default {
useBlockProps: useBlockPropsChildLayoutStyles,
edit: ChildLayoutControlsPure,
attributeKeys: [ 'style' ],
hasSupport() {
return true;
},
};