@wordpress/block-editor 12.3.4 → 12.5.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 (192) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +4 -0
  3. package/build/components/block-heading-level-dropdown/heading-level-icon.js +10 -2
  4. package/build/components/block-heading-level-dropdown/heading-level-icon.js.map +1 -1
  5. package/build/components/block-heading-level-dropdown/index.native.js +4 -3
  6. package/build/components/block-heading-level-dropdown/index.native.js.map +1 -1
  7. package/build/components/block-parent-selector/index.js +8 -5
  8. package/build/components/block-parent-selector/index.js.map +1 -1
  9. package/build/components/block-removal-warning-modal/index.js +18 -25
  10. package/build/components/block-removal-warning-modal/index.js.map +1 -1
  11. package/build/components/block-tools/block-contextual-toolbar.js +7 -11
  12. package/build/components/block-tools/block-contextual-toolbar.js.map +1 -1
  13. package/build/components/global-styles/color-panel.js +1 -1
  14. package/build/components/global-styles/color-panel.js.map +1 -1
  15. package/build/components/global-styles/hooks.js +2 -2
  16. package/build/components/global-styles/hooks.js.map +1 -1
  17. package/build/components/global-styles/typography-panel.js +34 -2
  18. package/build/components/global-styles/typography-panel.js.map +1 -1
  19. package/build/components/index.js +19 -1
  20. package/build/components/index.js.map +1 -1
  21. package/build/components/inserter/media-tab/hooks.js +2 -21
  22. package/build/components/inserter/media-tab/hooks.js.map +1 -1
  23. package/build/components/inserter/reusable-block-rename-hint.js +62 -0
  24. package/build/components/inserter/reusable-block-rename-hint.js.map +1 -0
  25. package/build/components/inserter/reusable-blocks-tab.js +5 -1
  26. package/build/components/inserter/reusable-blocks-tab.js.map +1 -1
  27. package/build/components/inserter/reusable-blocks-tab.native.js +2 -2
  28. package/build/components/inserter/reusable-blocks-tab.native.js.map +1 -1
  29. package/build/components/inserter/tabs.native.js +1 -1
  30. package/build/components/inserter/tabs.native.js.map +1 -1
  31. package/build/components/inserter-draggable-blocks/index.js +9 -1
  32. package/build/components/inserter-draggable-blocks/index.js.map +1 -1
  33. package/build/components/link-control/constants.js +1 -1
  34. package/build/components/link-control/constants.js.map +1 -1
  35. package/build/components/link-control/search-create-button.js +5 -21
  36. package/build/components/link-control/search-create-button.js.map +1 -1
  37. package/build/components/link-control/search-item.js +13 -30
  38. package/build/components/link-control/search-item.js.map +1 -1
  39. package/build/components/link-control/search-results.js +2 -2
  40. package/build/components/link-control/search-results.js.map +1 -1
  41. package/build/components/list-view/appender.js +2 -6
  42. package/build/components/list-view/appender.js.map +1 -1
  43. package/build/components/provider/index.js +5 -2
  44. package/build/components/provider/index.js.map +1 -1
  45. package/build/components/writing-flow/use-tab-nav.js +10 -27
  46. package/build/components/writing-flow/use-tab-nav.js.map +1 -1
  47. package/build/components/writing-mode-control/index.js +70 -0
  48. package/build/components/writing-mode-control/index.js.map +1 -0
  49. package/build/hooks/behaviors.js +25 -20
  50. package/build/hooks/behaviors.js.map +1 -1
  51. package/build/hooks/supports.js +7 -1
  52. package/build/hooks/supports.js.map +1 -1
  53. package/build/hooks/typography.js +2 -1
  54. package/build/hooks/typography.js.map +1 -1
  55. package/build/hooks/utils.js +4 -2
  56. package/build/hooks/utils.js.map +1 -1
  57. package/build/private-apis.js +3 -0
  58. package/build/private-apis.js.map +1 -1
  59. package/build/private-apis.native.js +3 -0
  60. package/build/private-apis.native.js.map +1 -1
  61. package/build/store/actions.js +195 -1
  62. package/build/store/actions.js.map +1 -1
  63. package/build/store/index.js +10 -1
  64. package/build/store/index.js.map +1 -1
  65. package/build/store/private-actions.js +46 -40
  66. package/build/store/private-actions.js.map +1 -1
  67. package/build/store/private-selectors.js +3 -3
  68. package/build/store/private-selectors.js.map +1 -1
  69. package/build/store/reducer.js +22 -8
  70. package/build/store/reducer.js.map +1 -1
  71. package/build/store/selectors.js +6 -4
  72. package/build/store/selectors.js.map +1 -1
  73. package/build-module/components/block-heading-level-dropdown/heading-level-icon.js +9 -2
  74. package/build-module/components/block-heading-level-dropdown/heading-level-icon.js.map +1 -1
  75. package/build-module/components/block-heading-level-dropdown/index.native.js +4 -3
  76. package/build-module/components/block-heading-level-dropdown/index.native.js.map +1 -1
  77. package/build-module/components/block-parent-selector/index.js +7 -5
  78. package/build-module/components/block-parent-selector/index.js.map +1 -1
  79. package/build-module/components/block-removal-warning-modal/index.js +19 -23
  80. package/build-module/components/block-removal-warning-modal/index.js.map +1 -1
  81. package/build-module/components/block-tools/block-contextual-toolbar.js +8 -11
  82. package/build-module/components/block-tools/block-contextual-toolbar.js.map +1 -1
  83. package/build-module/components/global-styles/color-panel.js +1 -1
  84. package/build-module/components/global-styles/color-panel.js.map +1 -1
  85. package/build-module/components/global-styles/hooks.js +2 -2
  86. package/build-module/components/global-styles/hooks.js.map +1 -1
  87. package/build-module/components/global-styles/typography-panel.js +33 -2
  88. package/build-module/components/global-styles/typography-panel.js.map +1 -1
  89. package/build-module/components/index.js +6 -0
  90. package/build-module/components/index.js.map +1 -1
  91. package/build-module/components/inserter/media-tab/hooks.js +2 -21
  92. package/build-module/components/inserter/media-tab/hooks.js.map +1 -1
  93. package/build-module/components/inserter/reusable-block-rename-hint.js +48 -0
  94. package/build-module/components/inserter/reusable-block-rename-hint.js.map +1 -0
  95. package/build-module/components/inserter/reusable-blocks-tab.js +4 -1
  96. package/build-module/components/inserter/reusable-blocks-tab.js.map +1 -1
  97. package/build-module/components/inserter/reusable-blocks-tab.native.js +2 -2
  98. package/build-module/components/inserter/reusable-blocks-tab.native.js.map +1 -1
  99. package/build-module/components/inserter/tabs.native.js +1 -1
  100. package/build-module/components/inserter/tabs.native.js.map +1 -1
  101. package/build-module/components/inserter-draggable-blocks/index.js +9 -2
  102. package/build-module/components/inserter-draggable-blocks/index.js.map +1 -1
  103. package/build-module/components/link-control/constants.js +1 -1
  104. package/build-module/components/link-control/constants.js.map +1 -1
  105. package/build-module/components/link-control/search-create-button.js +7 -20
  106. package/build-module/components/link-control/search-create-button.js.map +1 -1
  107. package/build-module/components/link-control/search-item.js +14 -28
  108. package/build-module/components/link-control/search-item.js.map +1 -1
  109. package/build-module/components/link-control/search-results.js +3 -3
  110. package/build-module/components/link-control/search-results.js.map +1 -1
  111. package/build-module/components/list-view/appender.js +2 -6
  112. package/build-module/components/list-view/appender.js.map +1 -1
  113. package/build-module/components/provider/index.js +5 -2
  114. package/build-module/components/provider/index.js.map +1 -1
  115. package/build-module/components/writing-flow/use-tab-nav.js +8 -26
  116. package/build-module/components/writing-flow/use-tab-nav.js.map +1 -1
  117. package/build-module/components/writing-mode-control/index.js +57 -0
  118. package/build-module/components/writing-mode-control/index.js.map +1 -0
  119. package/build-module/hooks/behaviors.js +26 -20
  120. package/build-module/hooks/behaviors.js.map +1 -1
  121. package/build-module/hooks/supports.js +7 -1
  122. package/build-module/hooks/supports.js.map +1 -1
  123. package/build-module/hooks/typography.js +2 -1
  124. package/build-module/hooks/typography.js.map +1 -1
  125. package/build-module/hooks/utils.js +4 -2
  126. package/build-module/hooks/utils.js.map +1 -1
  127. package/build-module/private-apis.js +2 -0
  128. package/build-module/private-apis.js.map +1 -1
  129. package/build-module/private-apis.native.js +2 -0
  130. package/build-module/private-apis.native.js.map +1 -1
  131. package/build-module/store/actions.js +191 -1
  132. package/build-module/store/actions.js.map +1 -1
  133. package/build-module/store/index.js +10 -1
  134. package/build-module/store/index.js.map +1 -1
  135. package/build-module/store/private-actions.js +45 -36
  136. package/build-module/store/private-actions.js.map +1 -1
  137. package/build-module/store/private-selectors.js +2 -2
  138. package/build-module/store/private-selectors.js.map +1 -1
  139. package/build-module/store/reducer.js +22 -8
  140. package/build-module/store/reducer.js.map +1 -1
  141. package/build-module/store/selectors.js +6 -4
  142. package/build-module/store/selectors.js.map +1 -1
  143. package/build-style/style-rtl.css +88 -81
  144. package/build-style/style.css +88 -81
  145. package/package.json +31 -31
  146. package/src/components/block-draggable/style.scss +1 -0
  147. package/src/components/block-heading-level-dropdown/heading-level-icon.js +6 -1
  148. package/src/components/block-heading-level-dropdown/index.native.js +8 -4
  149. package/src/components/block-inspector/style.scss +2 -1
  150. package/src/components/block-parent-selector/index.js +13 -8
  151. package/src/components/block-removal-warning-modal/index.js +16 -27
  152. package/src/components/block-tools/block-contextual-toolbar.js +5 -11
  153. package/src/components/block-tools/style.scss +69 -26
  154. package/src/components/font-family/README.md +71 -0
  155. package/src/components/global-styles/color-panel.js +1 -1
  156. package/src/components/global-styles/hooks.js +2 -0
  157. package/src/components/global-styles/typography-panel.js +40 -0
  158. package/src/components/index.js +6 -0
  159. package/src/components/inserter/media-tab/hooks.js +2 -22
  160. package/src/components/inserter/reusable-block-rename-hint.js +52 -0
  161. package/src/components/inserter/reusable-blocks-tab.js +4 -0
  162. package/src/components/inserter/reusable-blocks-tab.native.js +2 -2
  163. package/src/components/inserter/style.scss +28 -0
  164. package/src/components/inserter/tabs.native.js +5 -1
  165. package/src/components/inserter-draggable-blocks/index.js +13 -2
  166. package/src/components/link-control/constants.js +1 -1
  167. package/src/components/link-control/search-create-button.js +8 -26
  168. package/src/components/link-control/search-item.js +21 -43
  169. package/src/components/link-control/search-results.js +48 -46
  170. package/src/components/link-control/style.scss +18 -68
  171. package/src/components/link-control/test/index.js +6 -7
  172. package/src/components/list-view/appender.js +5 -6
  173. package/src/components/panel-color-settings/README.md +98 -0
  174. package/src/components/provider/index.js +9 -2
  175. package/src/components/recursion-provider/README.md +101 -0
  176. package/src/components/writing-flow/use-tab-nav.js +10 -33
  177. package/src/components/writing-mode-control/index.js +68 -0
  178. package/src/components/writing-mode-control/style.scss +18 -0
  179. package/src/hooks/behaviors.js +25 -16
  180. package/src/hooks/supports.js +7 -0
  181. package/src/hooks/typography.js +2 -0
  182. package/src/hooks/utils.js +3 -0
  183. package/src/private-apis.js +2 -0
  184. package/src/private-apis.native.js +2 -0
  185. package/src/store/actions.js +194 -1
  186. package/src/store/index.js +10 -0
  187. package/src/store/private-actions.js +39 -39
  188. package/src/store/private-selectors.js +2 -2
  189. package/src/store/reducer.js +22 -8
  190. package/src/store/selectors.js +9 -6
  191. package/src/store/test/actions.js +111 -0
  192. package/src/store/test/private-actions.js +56 -0
@@ -0,0 +1,98 @@
1
+ # PanelColorSettings
2
+
3
+ `PanelColorSettings` is a React component that renders a UI for managing various color settings.
4
+ It is essentially a wrapper around the `PanelColorGradientSettings` component, but specifically disables the gradient features.
5
+
6
+ ## Usage
7
+
8
+ ```jsx
9
+ /**
10
+ * WordPress dependencies
11
+ */
12
+ import { PanelColorSettings } from '@wordpress/block-editor';
13
+ import { useState } from '@wordpress/element';
14
+ import { __ } from '@wordpress/i18n';
15
+
16
+ // ...
17
+
18
+ const MyPanelColorSettings = () => {
19
+ const [ textColor, setTextColor ] = useState( { color: '#000' } );
20
+ const [ backgroundColor, setBackgroundColor ] = useState( {
21
+ color: '#fff',
22
+ } );
23
+ const [ overlayTextColor, setOverlayTextColor ] = useState( {
24
+ color: '#000',
25
+ } );
26
+ const [ overlayBackgroundColor, setOverlayBackgroundColor ] = useState( {
27
+ color: '#eee',
28
+ } );
29
+
30
+ return (
31
+ <PanelColorSettings
32
+ __experimentalIsRenderedInSidebar
33
+ title={ __( 'Color' ) }
34
+ colorSettings={ [
35
+ {
36
+ value: textColor.color,
37
+ onChange: setTextColor,
38
+ label: __( 'Text' ),
39
+ },
40
+ {
41
+ value: backgroundColor.color,
42
+ onChange: setBackgroundColor,
43
+ label: __( 'Background' ),
44
+ },
45
+ {
46
+ value: overlayTextColor.color,
47
+ onChange: setOverlayTextColor,
48
+ label: __( 'Submenu & overlay text' ),
49
+ },
50
+ {
51
+ value: overlayBackgroundColor.color,
52
+ onChange: setOverlayBackgroundColor,
53
+ label: __( 'Submenu & overlay background' ),
54
+ },
55
+ ] }
56
+ />
57
+ );
58
+ };
59
+
60
+ /// ...
61
+
62
+ <MyPanelColorSettings />;
63
+ ```
64
+
65
+ ## Props
66
+
67
+ The component accepts the following props:
68
+
69
+ ### colorSettings
70
+
71
+ A user-provided set of color settings.
72
+
73
+ - Type: `Array`
74
+ - Required: No
75
+
76
+ Colors settings are provided as an array of objects with the following schema:
77
+
78
+ | Property | Description | Type |
79
+ | -------- | --------------------------------- | -------- |
80
+ | value | The current color of the setting | string |
81
+ | onChange | Callback on change of the setting | Function |
82
+ | label | Label of the setting | string |
83
+
84
+ Additionally, the following `PanelColorGradientSettings` props are supported and directly passed down to the underlying `PanelColorGradientSettings` instance:
85
+
86
+ - `className` - added to the underlying `ToolsPanel` instance.
87
+ - `colors` - array of colors to be used.
88
+ - `gradients` - not recommended to be used since `PanelColorSettings` resets it.
89
+ - `disableCustomColors` - whether addition of custom colors is enabled
90
+ - `disableCustomGradients` - not recommended to be used since `PanelColorSettings` sets it.
91
+ - `children` - displayed below the underlying `PanelColorGradientSettings` instance.
92
+ - `settings` - not recommended to be used, since `PanelColorSettings` builds it from the `colorSettings` prop.
93
+ - `title` - title of the underlying `ToolsPanel`.
94
+ - `showTitle` - whether to show the title of the `ToolsPanel`.
95
+ - `__experimentalIsRenderedInSidebar`
96
+ - `enableAlpha` - whether to enable setting opacity when specifying a color.
97
+
98
+ Please refer to the `PanelColorGradientSettings` component for more information.
@@ -28,9 +28,16 @@ export const ExperimentalBlockEditorProvider = withRegistryProvider(
28
28
  ...settings,
29
29
  __internalIsInitialized: true,
30
30
  },
31
- stripExperimentalSettings
31
+ {
32
+ stripExperimentalSettings,
33
+ reset: true,
34
+ }
32
35
  );
33
- }, [ settings ] );
36
+ }, [
37
+ settings,
38
+ stripExperimentalSettings,
39
+ __experimentalUpdateSettings,
40
+ ] );
34
41
 
35
42
  // Syncs the entity provider with changes in the block-editor store.
36
43
  useBlockSync( props );
@@ -0,0 +1,101 @@
1
+ # RecursionProvider
2
+
3
+ According to Gutenberg's block rendering architecture, any block type capable of recursion should be responsible for handling its own infinite loops.
4
+
5
+ To help with detecting infinite loops on the client, the `RecursionProvider` component and the `useHasRecursion()` hook are used to identify if a block has already been rendered.
6
+
7
+ ## Usage
8
+
9
+ ```jsx
10
+ /**
11
+ * WordPress dependencies
12
+ */
13
+ import {
14
+ __experimentalRecursionProvider as RecursionProvider,
15
+ __experimentalUseHasRecursion as useHasRecursion,
16
+ useBlockProps,
17
+ Warning,
18
+ } from '@wordpress/block-editor';
19
+ import { __ } from '@wordpress/i18n';
20
+
21
+ export default function MyRecursiveBlockEdit( { attributes: { ref } } ) {
22
+ const hasAlreadyRendered = useHasRecursion( ref );
23
+ const blockProps = useBlockProps( {
24
+ className: 'my-block__custom-class',
25
+ } );
26
+
27
+ if ( hasAlreadyRendered ) {
28
+ return (
29
+ <div { ...blockProps }>
30
+ <Warning>
31
+ { __( 'Block cannot be rendered inside itself.' ) }
32
+ </Warning>
33
+ </div>
34
+ );
35
+ }
36
+
37
+ return (
38
+ <RecursionProvider uniqueId={ ref }>
39
+ Block editing code here....
40
+ </RecursionProvider>
41
+ );
42
+ }
43
+
44
+ /// ...
45
+
46
+ <MyRecursiveBlockEdit />;
47
+ ```
48
+
49
+ ## Props
50
+
51
+ The component accepts the following props:
52
+
53
+ ### uniqueId
54
+
55
+ Any value that acts as a unique identifier for a block instance.
56
+
57
+ - Type: `any`
58
+ - Required: Yes
59
+
60
+ ### children
61
+
62
+ Components to be rendered as content.
63
+
64
+ - Type: `Element`
65
+ - Required: Yes.
66
+
67
+ ### blockName
68
+
69
+ Optional block name.
70
+
71
+ - Type: `String`
72
+ - Required: No
73
+ - Default: ''
74
+
75
+ # `useHasRecursion()`
76
+
77
+ Used in conjunction with `RecursionProvider`, this hook is used to identify if a block has already been rendered.
78
+
79
+ ## Usage
80
+
81
+ For example usage, refer to the example above.
82
+
83
+ ## Props
84
+
85
+ The component accepts the following props:
86
+
87
+ ### uniqueId
88
+
89
+ Any value that acts as a unique identifier for a block instance.
90
+
91
+ - Type: `any`
92
+ - Required: Yes
93
+
94
+ ### blockName
95
+
96
+ Optional block name.
97
+
98
+ - Type: `String`
99
+ - Required: No
100
+ - Default: ''
101
+
@@ -11,6 +11,7 @@ import { useRef } from '@wordpress/element';
11
11
  * Internal dependencies
12
12
  */
13
13
  import { store as blockEditorStore } from '../../store';
14
+ import { isInSameBlock, isInsideRootBlock } from '../../utils/dom';
14
15
 
15
16
  export default function useTabNav() {
16
17
  const container = useRef();
@@ -116,41 +117,20 @@ export default function useTabNav() {
116
117
  return;
117
118
  }
118
119
 
120
+ const nextTabbable = focus.tabbable[ direction ]( event.target );
121
+
119
122
  // We want to constrain the tabbing to the block and its child blocks.
120
123
  // If the preceding form element is within a different block,
121
124
  // such as two sibling image blocks in the placeholder state,
122
125
  // we want shift + tab from the first form element to move to the image
123
126
  // block toolbar and not the previous image block's form element.
124
- // TODO: Should this become a utility function?
125
- /**
126
- * Determine whether an element is part of or is the selected block.
127
- *
128
- * @param {Object} selectedBlockElement
129
- * @param {Object} element
130
- * @return {boolean} Whether the element is part of or is the selected block.
131
- */
132
- const isElementPartOfSelectedBlock = (
133
- selectedBlockElement,
134
- element
135
- ) => {
136
- // Check if the element is or is within the selected block by finding the
137
- // closest element with a data-block attribute and seeing if
138
- // it matches our current selected block ID
139
- const elementBlockId = element
140
- .closest( '[data-block]' )
141
- ?.getAttribute( 'data-block' );
142
- const isElementSameBlock =
143
- elementBlockId === getSelectedBlockClientId();
144
-
145
- // Check if the element is a child of the selected block. This could be a
146
- // child block in a group or column block, etc.
147
- const isElementChildOfBlock =
148
- selectedBlockElement.contains( element );
149
-
150
- return isElementSameBlock || isElementChildOfBlock;
151
- };
127
+ const currentBlock = event.target.closest( '[data-block]' );
128
+ const isElementPartOfSelectedBlock =
129
+ currentBlock &&
130
+ nextTabbable &&
131
+ ( isInSameBlock( currentBlock, nextTabbable ) ||
132
+ isInsideRootBlock( currentBlock, nextTabbable ) );
152
133
 
153
- const nextTabbable = focus.tabbable[ direction ]( event.target );
154
134
  // Allow tabbing from the block wrapper to a form element,
155
135
  // and between form elements rendered in a block and its child blocks,
156
136
  // such as inside a placeholder. Form elements are generally
@@ -159,10 +139,7 @@ export default function useTabNav() {
159
139
  // future they can be rendered in an iframe or shadow DOM.
160
140
  if (
161
141
  isFormElement( nextTabbable ) &&
162
- isElementPartOfSelectedBlock(
163
- event.target.closest( '[data-block]' ),
164
- nextTabbable
165
- )
142
+ isElementPartOfSelectedBlock
166
143
  ) {
167
144
  return;
168
145
  }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import classnames from 'classnames';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { BaseControl, Button } from '@wordpress/components';
10
+ import { __, isRTL } from '@wordpress/i18n';
11
+ import { textHorizontal, textVertical } from '@wordpress/icons';
12
+
13
+ const WRITING_MODES = [
14
+ {
15
+ name: __( 'Horizontal' ),
16
+ value: 'horizontal-tb',
17
+ icon: textHorizontal,
18
+ },
19
+ {
20
+ name: __( 'Vertical' ),
21
+ value: isRTL() ? 'vertical-lr' : 'vertical-rl',
22
+ icon: textVertical,
23
+ },
24
+ ];
25
+
26
+ /**
27
+ * Control to facilitate writing mode selections.
28
+ *
29
+ * @param {Object} props Component props.
30
+ * @param {string} props.className Class name to add to the control.
31
+ * @param {string} props.value Currently selected writing mode.
32
+ * @param {Function} props.onChange Handles change in the writing mode selection.
33
+ *
34
+ * @return {WPElement} Writing Mode control.
35
+ */
36
+ export default function WritingModeControl( { className, value, onChange } ) {
37
+ return (
38
+ <fieldset
39
+ className={ classnames(
40
+ 'block-editor-writing-mode-control',
41
+ className
42
+ ) }
43
+ >
44
+ <BaseControl.VisualLabel as="legend">
45
+ { __( 'Orientation' ) }
46
+ </BaseControl.VisualLabel>
47
+ <div className="block-editor-writing-mode-control__buttons">
48
+ { WRITING_MODES.map( ( writingMode ) => {
49
+ return (
50
+ <Button
51
+ key={ writingMode.value }
52
+ icon={ writingMode.icon }
53
+ label={ writingMode.name }
54
+ isPressed={ writingMode.value === value }
55
+ onClick={ () => {
56
+ onChange(
57
+ writingMode.value === value
58
+ ? undefined
59
+ : writingMode.value
60
+ );
61
+ } }
62
+ />
63
+ );
64
+ } ) }
65
+ </div>
66
+ </fieldset>
67
+ );
68
+ }
@@ -0,0 +1,18 @@
1
+ .block-editor-writing-mode-control {
2
+ border: 0;
3
+ margin: 0;
4
+ padding: 0;
5
+
6
+ .block-editor-writing-mode-control__buttons {
7
+ // 4px of padding makes the row 40px high, same as an input.
8
+ padding: $grid-unit-05 0;
9
+ display: flex;
10
+ }
11
+
12
+ .components-button.has-icon {
13
+ height: $grid-unit-40;
14
+ margin-right: $grid-unit-05;
15
+ min-width: $grid-unit-40;
16
+ padding: 0;
17
+ }
18
+ }
@@ -7,6 +7,7 @@ import { __ } from '@wordpress/i18n';
7
7
  import { hasBlockSupport } from '@wordpress/blocks';
8
8
  import { createHigherOrderComponent } from '@wordpress/compose';
9
9
  import { useSelect } from '@wordpress/data';
10
+ import { useMemo } from '@wordpress/element';
10
11
 
11
12
  /**
12
13
  * Internal dependencies
@@ -65,35 +66,40 @@ function BehaviorsControl( {
65
66
  ...behaviorsOptions,
66
67
  ];
67
68
 
69
+ const { behaviors, behaviorsValue } = useMemo( () => {
70
+ const mergedBehaviors = {
71
+ ...themeBehaviors,
72
+ ...( blockBehaviors || {} ),
73
+ };
74
+
75
+ let value = '';
76
+ if ( blockBehaviors === undefined ) {
77
+ value = 'default';
78
+ }
79
+ if ( blockBehaviors?.lightbox.enabled ) {
80
+ value = 'lightbox';
81
+ }
82
+ return {
83
+ behaviors: mergedBehaviors,
84
+ behaviorsValue: value,
85
+ };
86
+ }, [ blockBehaviors, themeBehaviors ] );
68
87
  // If every behavior is disabled, do not show the behaviors inspector control.
69
88
  if ( behaviorsOptions.length === 0 ) {
70
89
  return null;
71
90
  }
72
- // Block behaviors take precedence over theme behaviors.
73
- const behaviors = { ...themeBehaviors, ...( blockBehaviors || {} ) };
74
91
 
75
92
  const helpText = disabled
76
93
  ? __( 'The lightbox behavior is disabled for linked images.' )
77
94
  : '';
78
95
 
79
- const value = () => {
80
- if ( blockBehaviors === undefined ) {
81
- return 'default';
82
- }
83
- if ( behaviors?.lightbox.enabled ) {
84
- return 'lightbox';
85
- }
86
- return '';
87
- };
88
-
89
96
  return (
90
97
  <InspectorControls group="advanced">
91
- { /* This div is needed to prevent a margin bottom between the dropdown and the button. */ }
92
98
  <div>
93
99
  <SelectControl
94
100
  label={ __( 'Behaviors' ) }
95
101
  // At the moment we are only supporting one behavior (Lightbox)
96
- value={ value() }
102
+ value={ behaviorsValue }
97
103
  options={ options }
98
104
  onChange={ onChangeBehavior }
99
105
  hideCancelButton={ true }
@@ -101,7 +107,7 @@ function BehaviorsControl( {
101
107
  size="__unstable-large"
102
108
  disabled={ disabled }
103
109
  />
104
- { behaviors?.lightbox.enabled && (
110
+ { behaviorsValue === 'lightbox' && (
105
111
  <SelectControl
106
112
  label={ __( 'Animation' ) }
107
113
  // At the moment we are only supporting one behavior (Lightbox)
@@ -115,7 +121,10 @@ function BehaviorsControl( {
115
121
  value: 'zoom',
116
122
  label: __( 'Zoom' ),
117
123
  },
118
- { value: 'fade', label: 'Fade' },
124
+ {
125
+ value: 'fade',
126
+ label: __( 'Fade' ),
127
+ },
119
128
  ] }
120
129
  onChange={ onChangeAnimation }
121
130
  hideCancelButton={ false }
@@ -30,11 +30,17 @@ const TEXT_COLUMNS_SUPPORT_KEY = 'typography.textColumns';
30
30
  * decorations e.g. settings found in `block.json`.
31
31
  */
32
32
  const TEXT_DECORATION_SUPPORT_KEY = 'typography.__experimentalTextDecoration';
33
+ /**
34
+ * Key within block settings' supports array indicating support for writing mode
35
+ * e.g. settings found in `block.json`.
36
+ */
37
+ const WRITING_MODE_SUPPORT_KEY = 'typography.__experimentalWritingMode';
33
38
  /**
34
39
  * Key within block settings' supports array indicating support for text
35
40
  * transforms e.g. settings found in `block.json`.
36
41
  */
37
42
  const TEXT_TRANSFORM_SUPPORT_KEY = 'typography.__experimentalTextTransform';
43
+
38
44
  /**
39
45
  * Key within block settings' supports array indicating support for letter-spacing
40
46
  * e.g. settings found in `block.json`.
@@ -50,6 +56,7 @@ const TYPOGRAPHY_SUPPORT_KEYS = [
50
56
  TEXT_COLUMNS_SUPPORT_KEY,
51
57
  TEXT_DECORATION_SUPPORT_KEY,
52
58
  TEXT_TRANSFORM_SUPPORT_KEY,
59
+ WRITING_MODE_SUPPORT_KEY,
53
60
  LETTER_SPACING_SUPPORT_KEY,
54
61
  ];
55
62
  const SPACING_SUPPORT_KEY = 'spacing';
@@ -30,6 +30,7 @@ const TEXT_DECORATION_SUPPORT_KEY = 'typography.__experimentalTextDecoration';
30
30
  const TEXT_COLUMNS_SUPPORT_KEY = 'typography.textColumns';
31
31
  const FONT_STYLE_SUPPORT_KEY = 'typography.__experimentalFontStyle';
32
32
  const FONT_WEIGHT_SUPPORT_KEY = 'typography.__experimentalFontWeight';
33
+ const WRITING_MODE_SUPPORT_KEY = 'typography.__experimentalWritingMode';
33
34
  export const TYPOGRAPHY_SUPPORT_KEY = 'typography';
34
35
  export const TYPOGRAPHY_SUPPORT_KEYS = [
35
36
  LINE_HEIGHT_SUPPORT_KEY,
@@ -39,6 +40,7 @@ export const TYPOGRAPHY_SUPPORT_KEYS = [
39
40
  FONT_FAMILY_SUPPORT_KEY,
40
41
  TEXT_COLUMNS_SUPPORT_KEY,
41
42
  TEXT_DECORATION_SUPPORT_KEY,
43
+ WRITING_MODE_SUPPORT_KEY,
42
44
  TEXT_TRANSFORM_SUPPORT_KEY,
43
45
  LETTER_SPACING_SUPPORT_KEY,
44
46
  ];
@@ -136,6 +136,7 @@ export function useBlockSettings( name, parentLayout ) {
136
136
  const lineHeight = useSetting( 'typography.lineHeight' );
137
137
  const textColumns = useSetting( 'typography.textColumns' );
138
138
  const textDecoration = useSetting( 'typography.textDecoration' );
139
+ const writingMode = useSetting( 'typography.writingMode' );
139
140
  const textTransform = useSetting( 'typography.textTransform' );
140
141
  const letterSpacing = useSetting( 'typography.letterSpacing' );
141
142
  const padding = useSetting( 'spacing.padding' );
@@ -211,6 +212,7 @@ export function useBlockSettings( name, parentLayout ) {
211
212
  textDecoration,
212
213
  textTransform,
213
214
  letterSpacing,
215
+ writingMode,
214
216
  },
215
217
  spacing: {
216
218
  spacingSizes: {
@@ -244,6 +246,7 @@ export function useBlockSettings( name, parentLayout ) {
244
246
  textDecoration,
245
247
  textTransform,
246
248
  letterSpacing,
249
+ writingMode,
247
250
  padding,
248
251
  margin,
249
252
  blockGap,
@@ -5,6 +5,7 @@ import * as globalStyles from './components/global-styles';
5
5
  import { ExperimentalBlockEditorProvider } from './components/provider';
6
6
  import { lock } from './lock-unlock';
7
7
  import { getRichTextValues } from './components/rich-text/content';
8
+ import { kebabCase } from './utils/object';
8
9
  import ResizableBoxPopover from './components/resizable-box-popover';
9
10
  import { ComposedPrivateInserter as PrivateInserter } from './components/inserter';
10
11
  import { PrivateListView } from './components/list-view';
@@ -27,6 +28,7 @@ lock( privateApis, {
27
28
  ...globalStyles,
28
29
  ExperimentalBlockEditorProvider,
29
30
  getRichTextValues,
31
+ kebabCase,
30
32
  PrivateInserter,
31
33
  PrivateListView,
32
34
  ResizableBoxPopover,
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import * as globalStyles from './components/global-styles';
5
5
  import { ExperimentalBlockEditorProvider } from './components/provider';
6
+ import { kebabCase } from './utils/object';
6
7
  import { lock } from './lock-unlock';
7
8
 
8
9
  /**
@@ -11,5 +12,6 @@ import { lock } from './lock-unlock';
11
12
  export const privateApis = {};
12
13
  lock( privateApis, {
13
14
  ...globalStyles,
15
+ kebabCase,
14
16
  ExperimentalBlockEditorProvider,
15
17
  } );