@wordpress/block-editor 11.6.0 → 11.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +4 -0
  3. package/build/components/block-list/block-html.js +1 -3
  4. package/build/components/block-list/block-html.js.map +1 -1
  5. package/build/components/block-preview/auto.js +6 -23
  6. package/build/components/block-preview/auto.js.map +1 -1
  7. package/build/components/editor-styles/index.js +20 -2
  8. package/build/components/editor-styles/index.js.map +1 -1
  9. package/build/components/global-styles/color-panel.js +583 -0
  10. package/build/components/global-styles/color-panel.js.map +1 -0
  11. package/build/components/global-styles/dimensions-panel.js +8 -30
  12. package/build/components/global-styles/dimensions-panel.js.map +1 -1
  13. package/build/components/global-styles/get-block-css-selector.js +129 -0
  14. package/build/components/global-styles/get-block-css-selector.js.map +1 -0
  15. package/build/components/global-styles/hooks.js +53 -1
  16. package/build/components/global-styles/hooks.js.map +1 -1
  17. package/build/components/global-styles/index.js +18 -2
  18. package/build/components/global-styles/index.js.map +1 -1
  19. package/build/components/global-styles/typography-panel.js +9 -35
  20. package/build/components/global-styles/typography-panel.js.map +1 -1
  21. package/build/components/global-styles/use-global-styles-output.js +160 -86
  22. package/build/components/global-styles/use-global-styles-output.js.map +1 -1
  23. package/build/components/global-styles/utils.js +2 -1
  24. package/build/components/global-styles/utils.js.map +1 -1
  25. package/build/components/image-size-control/index.js +8 -5
  26. package/build/components/image-size-control/index.js.map +1 -1
  27. package/build/components/inspector-controls-tabs/position-controls-panel.js +43 -7
  28. package/build/components/inspector-controls-tabs/position-controls-panel.js.map +1 -1
  29. package/build/components/line-height-control/index.js +15 -1
  30. package/build/components/line-height-control/index.js.map +1 -1
  31. package/build/components/list-view/appender.js +105 -0
  32. package/build/components/list-view/appender.js.map +1 -0
  33. package/build/components/list-view/block.js +5 -5
  34. package/build/components/list-view/block.js.map +1 -1
  35. package/build/components/list-view/branch.js +25 -5
  36. package/build/components/list-view/branch.js.map +1 -1
  37. package/build/components/list-view/index.js +37 -13
  38. package/build/components/list-view/index.js.map +1 -1
  39. package/build/components/media-replace-flow/index.js +13 -4
  40. package/build/components/media-replace-flow/index.js.map +1 -1
  41. package/build/components/rich-text/format-edit.js +2 -30
  42. package/build/components/rich-text/format-edit.js.map +1 -1
  43. package/build/components/writing-flow/use-input.js +4 -8
  44. package/build/components/writing-flow/use-input.js.map +1 -1
  45. package/build/hooks/border.js +0 -1
  46. package/build/hooks/border.js.map +1 -1
  47. package/build/hooks/color.js +92 -229
  48. package/build/hooks/color.js.map +1 -1
  49. package/build/hooks/content-lock-ui.js +4 -2
  50. package/build/hooks/content-lock-ui.js.map +1 -1
  51. package/build/hooks/{color-panel.js → contrast-checker.js} +11 -49
  52. package/build/hooks/contrast-checker.js.map +1 -0
  53. package/build/hooks/dimensions.js +0 -1
  54. package/build/hooks/dimensions.js.map +1 -1
  55. package/build/hooks/duotone.js +3 -1
  56. package/build/hooks/duotone.js.map +1 -1
  57. package/build/hooks/position.js +2 -2
  58. package/build/hooks/position.js.map +1 -1
  59. package/build/hooks/style.js +23 -26
  60. package/build/hooks/style.js.map +1 -1
  61. package/build/hooks/typography.js +0 -1
  62. package/build/hooks/typography.js.map +1 -1
  63. package/build/hooks/utils.js +25 -76
  64. package/build/hooks/utils.js.map +1 -1
  65. package/build/layouts/grid.js +165 -0
  66. package/build/layouts/grid.js.map +1 -0
  67. package/build/layouts/index.js +3 -1
  68. package/build/layouts/index.js.map +1 -1
  69. package/build/private-apis.js +4 -1
  70. package/build/private-apis.js.map +1 -1
  71. package/build/utils/object.js +76 -0
  72. package/build/utils/object.js.map +1 -0
  73. package/build-module/components/block-list/block-html.js +1 -3
  74. package/build-module/components/block-list/block-html.js.map +1 -1
  75. package/build-module/components/block-preview/auto.js +6 -22
  76. package/build-module/components/block-preview/auto.js.map +1 -1
  77. package/build-module/components/editor-styles/index.js +19 -2
  78. package/build-module/components/editor-styles/index.js.map +1 -1
  79. package/build-module/components/global-styles/color-panel.js +554 -0
  80. package/build-module/components/global-styles/color-panel.js.map +1 -0
  81. package/build-module/components/global-styles/dimensions-panel.js +7 -30
  82. package/build-module/components/global-styles/dimensions-panel.js.map +1 -1
  83. package/build-module/components/global-styles/get-block-css-selector.js +120 -0
  84. package/build-module/components/global-styles/get-block-css-selector.js.map +1 -0
  85. package/build-module/components/global-styles/hooks.js +51 -1
  86. package/build-module/components/global-styles/hooks.js.map +1 -1
  87. package/build-module/components/global-styles/index.js +3 -1
  88. package/build-module/components/global-styles/index.js.map +1 -1
  89. package/build-module/components/global-styles/typography-panel.js +8 -35
  90. package/build-module/components/global-styles/typography-panel.js.map +1 -1
  91. package/build-module/components/global-styles/use-global-styles-output.js +161 -87
  92. package/build-module/components/global-styles/use-global-styles-output.js.map +1 -1
  93. package/build-module/components/global-styles/utils.js +2 -1
  94. package/build-module/components/global-styles/utils.js.map +1 -1
  95. package/build-module/components/image-size-control/index.js +8 -5
  96. package/build-module/components/image-size-control/index.js.map +1 -1
  97. package/build-module/components/inspector-controls-tabs/position-controls-panel.js +42 -7
  98. package/build-module/components/inspector-controls-tabs/position-controls-panel.js.map +1 -1
  99. package/build-module/components/line-height-control/index.js +15 -1
  100. package/build-module/components/line-height-control/index.js.map +1 -1
  101. package/build-module/components/list-view/appender.js +88 -0
  102. package/build-module/components/list-view/appender.js.map +1 -0
  103. package/build-module/components/list-view/block.js +5 -4
  104. package/build-module/components/list-view/block.js.map +1 -1
  105. package/build-module/components/list-view/branch.js +22 -5
  106. package/build-module/components/list-view/branch.js.map +1 -1
  107. package/build-module/components/list-view/index.js +32 -12
  108. package/build-module/components/list-view/index.js.map +1 -1
  109. package/build-module/components/media-replace-flow/index.js +12 -4
  110. package/build-module/components/media-replace-flow/index.js.map +1 -1
  111. package/build-module/components/rich-text/format-edit.js +3 -31
  112. package/build-module/components/rich-text/format-edit.js.map +1 -1
  113. package/build-module/components/writing-flow/use-input.js +4 -8
  114. package/build-module/components/writing-flow/use-input.js.map +1 -1
  115. package/build-module/hooks/border.js +0 -1
  116. package/build-module/hooks/border.js.map +1 -1
  117. package/build-module/hooks/color.js +90 -232
  118. package/build-module/hooks/color.js.map +1 -1
  119. package/build-module/hooks/content-lock-ui.js +4 -2
  120. package/build-module/hooks/content-lock-ui.js.map +1 -1
  121. package/build-module/hooks/{color-panel.js → contrast-checker.js} +10 -44
  122. package/build-module/hooks/contrast-checker.js.map +1 -0
  123. package/build-module/hooks/dimensions.js +0 -1
  124. package/build-module/hooks/dimensions.js.map +1 -1
  125. package/build-module/hooks/duotone.js +4 -2
  126. package/build-module/hooks/duotone.js.map +1 -1
  127. package/build-module/hooks/position.js +3 -3
  128. package/build-module/hooks/position.js.map +1 -1
  129. package/build-module/hooks/style.js +23 -26
  130. package/build-module/hooks/style.js.map +1 -1
  131. package/build-module/hooks/typography.js +0 -1
  132. package/build-module/hooks/typography.js.map +1 -1
  133. package/build-module/hooks/utils.js +23 -73
  134. package/build-module/hooks/utils.js.map +1 -1
  135. package/build-module/layouts/grid.js +151 -0
  136. package/build-module/layouts/grid.js.map +1 -0
  137. package/build-module/layouts/index.js +2 -1
  138. package/build-module/layouts/index.js.map +1 -1
  139. package/build-module/private-apis.js +3 -1
  140. package/build-module/private-apis.js.map +1 -1
  141. package/build-module/utils/object.js +69 -0
  142. package/build-module/utils/object.js.map +1 -0
  143. package/build-style/style-rtl.css +26 -6
  144. package/build-style/style.css +26 -6
  145. package/package.json +31 -31
  146. package/src/components/block-draggable/content.scss +1 -1
  147. package/src/components/block-list/block-html.js +1 -1
  148. package/src/components/block-preview/auto.js +2 -17
  149. package/src/components/colors-gradients/style.scss +8 -8
  150. package/src/components/editor-styles/index.js +29 -1
  151. package/src/components/global-styles/color-panel.js +706 -0
  152. package/src/components/global-styles/dimensions-panel.js +13 -42
  153. package/src/components/global-styles/get-block-css-selector.js +129 -0
  154. package/src/components/global-styles/hooks.js +80 -0
  155. package/src/components/global-styles/index.js +2 -1
  156. package/src/components/global-styles/test/use-global-styles-output.js +30 -1
  157. package/src/components/global-styles/typography-panel.js +26 -51
  158. package/src/components/global-styles/use-global-styles-output.js +163 -80
  159. package/src/components/global-styles/utils.js +3 -0
  160. package/src/components/image-size-control/index.js +4 -3
  161. package/src/components/image-size-control/test/index.js +2 -2
  162. package/src/components/inner-blocks/README.md +1 -1
  163. package/src/components/inspector-controls-tabs/position-controls-panel.js +40 -9
  164. package/src/components/line-height-control/index.js +10 -1
  165. package/src/components/list-view/appender.js +101 -0
  166. package/src/components/list-view/block.js +5 -4
  167. package/src/components/list-view/branch.js +30 -1
  168. package/src/components/list-view/index.js +43 -10
  169. package/src/components/list-view/style.scss +19 -0
  170. package/src/components/media-replace-flow/index.js +36 -24
  171. package/src/components/media-replace-flow/style.scss +5 -2
  172. package/src/components/rich-text/format-edit.js +2 -32
  173. package/src/components/writing-flow/use-input.js +4 -5
  174. package/src/hooks/border.js +0 -1
  175. package/src/hooks/color.js +120 -296
  176. package/src/hooks/content-lock-ui.js +6 -2
  177. package/src/hooks/{color-panel.js → contrast-checker.js} +10 -46
  178. package/src/hooks/dimensions.js +0 -1
  179. package/src/hooks/duotone.js +8 -5
  180. package/src/hooks/position.js +3 -3
  181. package/src/hooks/style.js +29 -28
  182. package/src/hooks/test/utils.js +0 -104
  183. package/src/hooks/typography.js +0 -1
  184. package/src/hooks/utils.js +27 -70
  185. package/src/layouts/grid.js +172 -0
  186. package/src/layouts/index.js +2 -1
  187. package/src/layouts/test/grid.js +21 -0
  188. package/src/private-apis.js +2 -0
  189. package/src/utils/object.js +69 -0
  190. package/src/utils/test/object.js +107 -0
  191. package/tsconfig.tsbuildinfo +1 -1
  192. package/build/hooks/color-panel.js.map +0 -1
  193. package/build-module/hooks/color-panel.js.map +0 -1
@@ -0,0 +1,706 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import classnames from 'classnames';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import {
10
+ __experimentalToolsPanel as ToolsPanel,
11
+ __experimentalToolsPanelItem as ToolsPanelItem,
12
+ __experimentalHStack as HStack,
13
+ __experimentalZStack as ZStack,
14
+ __experimentalDropdownContentWrapper as DropdownContentWrapper,
15
+ TabPanel,
16
+ ColorIndicator,
17
+ Flex,
18
+ FlexItem,
19
+ Dropdown,
20
+ Button,
21
+ } from '@wordpress/components';
22
+ import { useCallback } from '@wordpress/element';
23
+ import { __ } from '@wordpress/i18n';
24
+
25
+ /**
26
+ * Internal dependencies
27
+ */
28
+ import ColorGradientControl from '../colors-gradients/control';
29
+ import { useColorsPerOrigin, useGradientsPerOrigin } from './hooks';
30
+ import { getValueFromVariable } from './utils';
31
+ import { immutableSet } from '../../utils/object';
32
+
33
+ export function useHasColorPanel( settings ) {
34
+ const hasTextPanel = useHasTextPanel( settings );
35
+ const hasBackgroundPanel = useHasBackgroundPanel( settings );
36
+ const hasLinkPanel = useHasLinkPanel( settings );
37
+ const hasHeadingPanel = useHasHeadingPanel( settings );
38
+ const hasButtonPanel = useHasHeadingPanel( settings );
39
+ const hasCaptionPanel = useHasCaptionPanel( settings );
40
+
41
+ return (
42
+ hasTextPanel ||
43
+ hasBackgroundPanel ||
44
+ hasLinkPanel ||
45
+ hasHeadingPanel ||
46
+ hasButtonPanel ||
47
+ hasCaptionPanel
48
+ );
49
+ }
50
+
51
+ export function useHasTextPanel( settings ) {
52
+ const colors = useColorsPerOrigin( settings );
53
+ return (
54
+ settings?.color?.text &&
55
+ ( colors?.length > 0 || settings?.color?.custom )
56
+ );
57
+ }
58
+
59
+ export function useHasLinkPanel( settings ) {
60
+ const colors = useColorsPerOrigin( settings );
61
+ return (
62
+ settings?.color?.link &&
63
+ ( colors?.length > 0 || settings?.color?.custom )
64
+ );
65
+ }
66
+
67
+ export function useHasCaptionPanel( settings ) {
68
+ const colors = useColorsPerOrigin( settings );
69
+ return (
70
+ settings?.color?.caption &&
71
+ ( colors?.length > 0 || settings?.color?.custom )
72
+ );
73
+ }
74
+
75
+ export function useHasHeadingPanel( settings ) {
76
+ const colors = useColorsPerOrigin( settings );
77
+ const gradients = useGradientsPerOrigin( settings );
78
+ return (
79
+ settings?.color?.heading &&
80
+ ( colors?.length > 0 ||
81
+ settings?.color?.custom ||
82
+ gradients?.length > 0 ||
83
+ settings?.color?.customGradient )
84
+ );
85
+ }
86
+
87
+ export function useHasButtonPanel( settings ) {
88
+ const colors = useColorsPerOrigin( settings );
89
+ const gradients = useGradientsPerOrigin( settings );
90
+ return (
91
+ settings?.color?.button &&
92
+ ( colors?.length > 0 ||
93
+ settings?.color?.custom ||
94
+ gradients?.length > 0 ||
95
+ settings?.color?.customGradient )
96
+ );
97
+ }
98
+
99
+ export function useHasBackgroundPanel( settings ) {
100
+ const colors = useColorsPerOrigin( settings );
101
+ const gradients = useGradientsPerOrigin( settings );
102
+ return (
103
+ settings?.color?.background &&
104
+ ( colors?.length > 0 ||
105
+ settings?.color?.custom ||
106
+ gradients?.length > 0 ||
107
+ settings?.color?.customGradient )
108
+ );
109
+ }
110
+
111
+ function ColorToolsPanel( {
112
+ resetAllFilter,
113
+ onChange,
114
+ value,
115
+ panelId,
116
+ children,
117
+ } ) {
118
+ const resetAll = () => {
119
+ const updatedValue = resetAllFilter( value );
120
+ onChange( updatedValue );
121
+ };
122
+
123
+ return (
124
+ <ToolsPanel
125
+ label={ __( 'Color' ) }
126
+ resetAll={ resetAll }
127
+ panelId={ panelId }
128
+ hasInnerWrapper
129
+ className="color-block-support-panel"
130
+ __experimentalFirstVisibleItemClass="first"
131
+ __experimentalLastVisibleItemClass="last"
132
+ >
133
+ <div className="color-block-support-panel__inner-wrapper">
134
+ { children }
135
+ </div>
136
+ </ToolsPanel>
137
+ );
138
+ }
139
+
140
+ const DEFAULT_CONTROLS = {
141
+ text: true,
142
+ background: true,
143
+ link: true,
144
+ heading: true,
145
+ button: true,
146
+ caption: true,
147
+ };
148
+
149
+ const popoverProps = {
150
+ placement: 'left-start',
151
+ offset: 36,
152
+ shift: true,
153
+ };
154
+
155
+ const LabeledColorIndicators = ( { indicators, label } ) => (
156
+ <HStack justify="flex-start">
157
+ <ZStack isLayered={ false } offset={ -8 }>
158
+ { indicators.map( ( indicator, index ) => (
159
+ <Flex key={ index } expanded={ false }>
160
+ <ColorIndicator colorValue={ indicator } />
161
+ </Flex>
162
+ ) ) }
163
+ </ZStack>
164
+ <FlexItem
165
+ className="block-editor-panel-color-gradient-settings__color-name"
166
+ title={ label }
167
+ >
168
+ { label }
169
+ </FlexItem>
170
+ </HStack>
171
+ );
172
+
173
+ function ColorPanelTab( {
174
+ isGradient,
175
+ inheritedValue,
176
+ userValue,
177
+ setValue,
178
+ colorGradientControlSettings,
179
+ } ) {
180
+ return (
181
+ <ColorGradientControl
182
+ { ...colorGradientControlSettings }
183
+ showTitle={ false }
184
+ enableAlpha
185
+ __experimentalIsRenderedInSidebar
186
+ colorValue={ isGradient ? undefined : inheritedValue }
187
+ gradientValue={ isGradient ? inheritedValue : undefined }
188
+ onColorChange={ isGradient ? undefined : setValue }
189
+ onGradientChange={ isGradient ? setValue : undefined }
190
+ clearable={ inheritedValue === userValue }
191
+ headingLevel={ 3 }
192
+ />
193
+ );
194
+ }
195
+
196
+ function ColorPanelDropdown( {
197
+ label,
198
+ hasValue,
199
+ resetValue,
200
+ isShownByDefault,
201
+ indicators,
202
+ tabs,
203
+ colorGradientControlSettings,
204
+ panelId,
205
+ } ) {
206
+ const tabConfigs = tabs.map( ( { key, label: tabLabel } ) => {
207
+ return {
208
+ name: key,
209
+ title: tabLabel,
210
+ };
211
+ } );
212
+
213
+ return (
214
+ <ToolsPanelItem
215
+ className="block-editor-tools-panel-color-gradient-settings__item"
216
+ hasValue={ hasValue }
217
+ label={ label }
218
+ onDeselect={ resetValue }
219
+ isShownByDefault={ isShownByDefault }
220
+ panelId={ panelId }
221
+ >
222
+ <Dropdown
223
+ popoverProps={ popoverProps }
224
+ className="block-editor-tools-panel-color-gradient-settings__dropdown"
225
+ renderToggle={ ( { onToggle, isOpen } ) => {
226
+ const toggleProps = {
227
+ onClick: onToggle,
228
+ className: classnames(
229
+ 'block-editor-panel-color-gradient-settings__dropdown',
230
+ { 'is-open': isOpen }
231
+ ),
232
+ 'aria-expanded': isOpen,
233
+ };
234
+
235
+ return (
236
+ <Button { ...toggleProps }>
237
+ <LabeledColorIndicators
238
+ indicators={ indicators }
239
+ label={ label }
240
+ />
241
+ </Button>
242
+ );
243
+ } }
244
+ renderContent={ () => (
245
+ <DropdownContentWrapper paddingSize="none">
246
+ <div className="block-editor-panel-color-gradient-settings__dropdown-content">
247
+ { tabs.length === 1 && (
248
+ <ColorPanelTab
249
+ { ...tabs[ 0 ] }
250
+ colorGradientControlSettings={
251
+ colorGradientControlSettings
252
+ }
253
+ />
254
+ ) }
255
+ { tabs.length > 1 && (
256
+ <TabPanel tabs={ tabConfigs }>
257
+ { ( tab ) => {
258
+ const selectedTab = tabs.find(
259
+ ( t ) => t.key === tab.name
260
+ );
261
+
262
+ if ( ! selectedTab ) {
263
+ return null;
264
+ }
265
+
266
+ return (
267
+ <ColorPanelTab
268
+ { ...selectedTab }
269
+ colorGradientControlSettings={
270
+ colorGradientControlSettings
271
+ }
272
+ />
273
+ );
274
+ } }
275
+ </TabPanel>
276
+ ) }
277
+ </div>
278
+ </DropdownContentWrapper>
279
+ ) }
280
+ />
281
+ </ToolsPanelItem>
282
+ );
283
+ }
284
+
285
+ export default function ColorPanel( {
286
+ as: Wrapper = ColorToolsPanel,
287
+ value,
288
+ onChange,
289
+ inheritedValue = value,
290
+ settings,
291
+ panelId,
292
+ defaultControls = DEFAULT_CONTROLS,
293
+ children,
294
+ } ) {
295
+ const colors = useColorsPerOrigin( settings );
296
+ const gradients = useGradientsPerOrigin( settings );
297
+ const areCustomSolidsEnabled = settings?.color?.custom;
298
+ const areCustomGradientsEnabled = settings?.color?.customGradient;
299
+ const hasSolidColors = colors.length > 0 || areCustomSolidsEnabled;
300
+ const hasGradientColors = gradients.length > 0 || areCustomGradientsEnabled;
301
+ const decodeValue = ( rawValue ) =>
302
+ getValueFromVariable( { settings }, '', rawValue );
303
+ const encodeColorValue = ( colorValue ) => {
304
+ const allColors = colors.flatMap(
305
+ ( { colors: originColors } ) => originColors
306
+ );
307
+ const colorObject = allColors.find(
308
+ ( { color } ) => color === colorValue
309
+ );
310
+ return colorObject
311
+ ? 'var:preset|color|' + colorObject.slug
312
+ : colorValue;
313
+ };
314
+ const encodeGradientValue = ( gradientValue ) => {
315
+ const allGradients = gradients.flatMap(
316
+ ( { gradients: originGradients } ) => originGradients
317
+ );
318
+ const gradientObject = allGradients.find(
319
+ ( { gradient } ) => gradient === gradientValue
320
+ );
321
+ return gradientObject
322
+ ? 'var:preset|gradient|' + gradientObject.slug
323
+ : gradientValue;
324
+ };
325
+
326
+ // Text Color
327
+ const showTextPanel = useHasTextPanel( settings );
328
+ const textColor = decodeValue( inheritedValue?.color?.text );
329
+ const userTextColor = decodeValue( value?.color?.text );
330
+ const hasTextColor = () => !! userTextColor;
331
+ const setTextColor = ( newColor ) => {
332
+ onChange(
333
+ immutableSet(
334
+ value,
335
+ [ 'color', 'text' ],
336
+ encodeColorValue( newColor )
337
+ )
338
+ );
339
+ };
340
+ const resetTextColor = () => setTextColor( undefined );
341
+
342
+ // BackgroundColor
343
+ const showBackgroundPanel = useHasBackgroundPanel( settings );
344
+ const backgroundColor = decodeValue( inheritedValue?.color?.background );
345
+ const userBackgroundColor = decodeValue( value?.color?.background );
346
+ const gradient = decodeValue( inheritedValue?.color?.gradient );
347
+ const userGradient = decodeValue( value?.color?.gradient );
348
+ const hasBackground = () => !! userBackgroundColor || !! userGradient;
349
+ const setBackgroundColor = ( newColor ) => {
350
+ const newValue = immutableSet(
351
+ value,
352
+ [ 'color', 'background' ],
353
+ encodeColorValue( newColor )
354
+ );
355
+ newValue.color.gradient = undefined;
356
+ onChange( newValue );
357
+ };
358
+ const setGradient = ( newGradient ) => {
359
+ const newValue = immutableSet(
360
+ value,
361
+ [ 'color', 'gradient' ],
362
+ encodeGradientValue( newGradient )
363
+ );
364
+ newValue.color.background = undefined;
365
+ onChange( newValue );
366
+ };
367
+ const resetBackground = () => {
368
+ const newValue = immutableSet(
369
+ value,
370
+ [ 'color', 'background' ],
371
+ undefined
372
+ );
373
+ newValue.color.gradient = undefined;
374
+ onChange( newValue );
375
+ };
376
+
377
+ // Links
378
+ const showLinkPanel = useHasLinkPanel( settings );
379
+ const linkColor = decodeValue(
380
+ inheritedValue?.elements?.link?.color?.text
381
+ );
382
+ const userLinkColor = decodeValue( value?.elements?.link?.color?.text );
383
+ const setLinkColor = ( newColor ) => {
384
+ onChange(
385
+ immutableSet(
386
+ value,
387
+ [ 'elements', 'link', 'color', 'text' ],
388
+ encodeColorValue( newColor )
389
+ )
390
+ );
391
+ };
392
+ const hoverLinkColor = decodeValue(
393
+ inheritedValue?.elements?.link?.[ ':hover' ]?.color?.text
394
+ );
395
+ const userHoverLinkColor = decodeValue(
396
+ value?.elements?.link?.[ ':hover' ]?.color?.text
397
+ );
398
+ const setHoverLinkColor = ( newColor ) => {
399
+ onChange(
400
+ immutableSet(
401
+ value,
402
+ [ 'elements', 'link', ':hover', 'color', 'text' ],
403
+ encodeColorValue( newColor )
404
+ )
405
+ );
406
+ };
407
+ const hasLink = () => !! userLinkColor || !! userHoverLinkColor;
408
+ const resetLink = () => {
409
+ let newValue = immutableSet(
410
+ value,
411
+ [ 'elements', 'link', ':hover', 'color', 'text' ],
412
+ undefined
413
+ );
414
+ newValue = immutableSet(
415
+ newValue,
416
+ [ 'elements', 'link', 'color', 'text' ],
417
+ undefined
418
+ );
419
+ onChange( newValue );
420
+ };
421
+
422
+ // Elements
423
+ const elements = [
424
+ {
425
+ name: 'caption',
426
+ label: __( 'Captions' ),
427
+ showPanel: useHasCaptionPanel( settings ),
428
+ },
429
+ {
430
+ name: 'button',
431
+ label: __( 'Button' ),
432
+ showPanel: useHasButtonPanel( settings ),
433
+ },
434
+ {
435
+ name: 'heading',
436
+ label: __( 'Heading' ),
437
+ showPanel: useHasHeadingPanel( settings ),
438
+ },
439
+ {
440
+ name: 'h1',
441
+ label: __( 'H1' ),
442
+ showPanel: useHasHeadingPanel( settings ),
443
+ },
444
+ {
445
+ name: 'h2',
446
+ label: __( 'H2' ),
447
+ showPanel: useHasHeadingPanel( settings ),
448
+ },
449
+ {
450
+ name: 'h3',
451
+ label: __( 'H3' ),
452
+ showPanel: useHasHeadingPanel( settings ),
453
+ },
454
+ {
455
+ name: 'h4',
456
+ label: __( 'H4' ),
457
+ showPanel: useHasHeadingPanel( settings ),
458
+ },
459
+ {
460
+ name: 'h5',
461
+ label: __( 'H5' ),
462
+ showPanel: useHasHeadingPanel( settings ),
463
+ },
464
+ {
465
+ name: 'h6',
466
+ label: __( 'H6' ),
467
+ showPanel: useHasHeadingPanel( settings ),
468
+ },
469
+ ];
470
+
471
+ const resetAllFilter = useCallback( ( previousValue ) => {
472
+ return {
473
+ ...previousValue,
474
+ color: undefined,
475
+ elements: {
476
+ ...previousValue?.elements,
477
+ link: {
478
+ ...previousValue?.elements?.link,
479
+ color: undefined,
480
+ ':hover': {
481
+ color: undefined,
482
+ },
483
+ },
484
+ ...elements.reduce( ( acc, element ) => {
485
+ return {
486
+ ...acc,
487
+ [ element.name ]: {
488
+ ...previousValue?.elements?.[ element.name ],
489
+ color: undefined,
490
+ },
491
+ };
492
+ }, {} ),
493
+ },
494
+ };
495
+ }, [] );
496
+
497
+ const items = [
498
+ showTextPanel && {
499
+ key: 'text',
500
+ label: __( 'Text' ),
501
+ hasValue: hasTextColor,
502
+ resetValue: resetTextColor,
503
+ isShownByDefault: defaultControls.text,
504
+ indicators: [ textColor ],
505
+ tabs: [
506
+ {
507
+ key: 'text',
508
+ label: __( 'Text' ),
509
+ inheritedValue: textColor,
510
+ setValue: setTextColor,
511
+ userValue: userTextColor,
512
+ },
513
+ ],
514
+ },
515
+ showBackgroundPanel && {
516
+ key: 'background',
517
+ label: __( 'Background' ),
518
+ hasValue: hasBackground,
519
+ resetValue: resetBackground,
520
+ isShownByDefault: defaultControls.background,
521
+ indicators: [ gradient ?? backgroundColor ],
522
+ tabs: [
523
+ {
524
+ key: 'background',
525
+ label: __( 'Solid' ),
526
+ inheritedValue: backgroundColor,
527
+ setValue: setBackgroundColor,
528
+ userValue: userBackgroundColor,
529
+ },
530
+ {
531
+ key: 'gradient',
532
+ label: __( 'Gradient' ),
533
+ inheritedValue: gradient,
534
+ setValue: setGradient,
535
+ userValue: userGradient,
536
+ isGradient: true,
537
+ },
538
+ ],
539
+ },
540
+ showLinkPanel && {
541
+ key: 'link',
542
+ label: __( 'Link' ),
543
+ hasValue: hasLink,
544
+ resetValue: resetLink,
545
+ isShownByDefault: defaultControls.link,
546
+ indicators: [ linkColor, hoverLinkColor ],
547
+ tabs: [
548
+ {
549
+ key: 'link',
550
+ label: __( 'Default' ),
551
+ inheritedValue: linkColor,
552
+ setValue: setLinkColor,
553
+ userValue: userLinkColor,
554
+ },
555
+ {
556
+ key: 'hover',
557
+ label: __( 'Hover' ),
558
+ inheritedValue: hoverLinkColor,
559
+ setValue: setHoverLinkColor,
560
+ userValue: userHoverLinkColor,
561
+ },
562
+ ],
563
+ },
564
+ ].filter( Boolean );
565
+
566
+ elements.forEach( ( { name, label, showPanel } ) => {
567
+ if ( ! showPanel ) return;
568
+
569
+ const elementBackgroundColor = decodeValue(
570
+ inheritedValue?.elements?.[ name ]?.color?.background
571
+ );
572
+ const elementGradient = decodeValue(
573
+ inheritedValue?.elements?.[ name ]?.color?.gradient
574
+ );
575
+ const elementTextColor = decodeValue(
576
+ inheritedValue?.elements?.[ name ]?.color?.text
577
+ );
578
+ const elementBackgroundUserColor = decodeValue(
579
+ value?.elements?.[ name ]?.color?.background
580
+ );
581
+ const elementGradientUserColor = decodeValue(
582
+ value?.elements?.[ name ]?.color?.gradient
583
+ );
584
+ const elementTextUserColor = decodeValue(
585
+ value?.elements?.[ name ]?.color?.text
586
+ );
587
+ const hasElement = () =>
588
+ !! (
589
+ elementTextUserColor ||
590
+ elementBackgroundUserColor ||
591
+ elementGradientUserColor
592
+ );
593
+ const resetElement = () => {
594
+ const newValue = immutableSet(
595
+ value,
596
+ [ 'elements', name, 'color', 'background' ],
597
+ undefined
598
+ );
599
+ newValue.elements[ name ].color.gradient = undefined;
600
+ newValue.elements[ name ].color.text = undefined;
601
+ onChange( newValue );
602
+ };
603
+
604
+ const setElementTextColor = ( newTextColor ) => {
605
+ onChange(
606
+ immutableSet(
607
+ value,
608
+ [ 'elements', name, 'color', 'text' ],
609
+ encodeColorValue( newTextColor )
610
+ )
611
+ );
612
+ };
613
+ const setElementBackgroundColor = ( newBackgroundColor ) => {
614
+ const newValue = immutableSet(
615
+ value,
616
+ [ 'elements', name, 'color', 'background' ],
617
+ encodeColorValue( newBackgroundColor )
618
+ );
619
+ newValue.elements[ name ].color.gradient = undefined;
620
+ onChange( newValue );
621
+ };
622
+ const setElementGradient = ( newGradient ) => {
623
+ const newValue = immutableSet(
624
+ value,
625
+ [ 'elements', name, 'color', 'gradient' ],
626
+ encodeGradientValue( newGradient )
627
+ );
628
+ newValue.elements[ name ].color.background = undefined;
629
+ onChange( newValue );
630
+ };
631
+ const supportsTextColor = true;
632
+ // Background color is not supported for `caption`
633
+ // as there isn't yet a way to set padding for the element.
634
+ const supportsBackground = name !== 'caption';
635
+
636
+ items.push( {
637
+ key: name,
638
+ label,
639
+ hasValue: hasElement,
640
+ resetValue: resetElement,
641
+ isShownByDefault: defaultControls[ name ],
642
+ indicators:
643
+ supportsTextColor && supportsBackground
644
+ ? [
645
+ elementTextColor,
646
+ elementGradient ?? elementBackgroundColor,
647
+ ]
648
+ : [
649
+ supportsTextColor
650
+ ? elementTextColor
651
+ : elementGradient ?? elementBackgroundColor,
652
+ ],
653
+ tabs: [
654
+ hasSolidColors &&
655
+ supportsTextColor && {
656
+ key: 'text',
657
+ label: __( 'Text' ),
658
+ inheritedValue: elementTextColor,
659
+ setValue: setElementTextColor,
660
+ userValue: elementTextUserColor,
661
+ },
662
+ hasSolidColors &&
663
+ supportsBackground && {
664
+ key: 'background',
665
+ label: __( 'Background' ),
666
+ inheritedValue: elementBackgroundColor,
667
+ setValue: setElementBackgroundColor,
668
+ userValue: elementBackgroundUserColor,
669
+ },
670
+ hasGradientColors &&
671
+ supportsBackground && {
672
+ key: 'gradient',
673
+ label: __( 'Gradient' ),
674
+ inheritedValue: elementGradient,
675
+ setValue: setElementGradient,
676
+ userValue: elementGradientUserColor,
677
+ isGradient: true,
678
+ },
679
+ ].filter( Boolean ),
680
+ } );
681
+ } );
682
+
683
+ return (
684
+ <Wrapper
685
+ resetAllFilter={ resetAllFilter }
686
+ value={ value }
687
+ onChange={ onChange }
688
+ panelId={ panelId }
689
+ >
690
+ { items.map( ( item ) => (
691
+ <ColorPanelDropdown
692
+ key={ item.key }
693
+ { ...item }
694
+ colorGradientControlSettings={ {
695
+ colors,
696
+ disableCustomColors: ! areCustomSolidsEnabled,
697
+ gradients,
698
+ disableCustomGradients: ! areCustomGradientsEnabled,
699
+ } }
700
+ panelId={ panelId }
701
+ />
702
+ ) ) }
703
+ { children }
704
+ </Wrapper>
705
+ );
706
+ }