Skip to content

Commit 56ebbcb

Browse files
authored
Add Typography: text orientation (writing mode) (#50822)
* Add Typography: text orientation (writing mode) * fix spacing CS issues * try to fix white space issue * Rename text orientation to writing mode * Add new text orientation icons
1 parent a09f124 commit 56ebbcb

File tree

23 files changed

+229
-3
lines changed

23 files changed

+229
-3
lines changed

docs/reference-guides/theme-json-reference/theme-json-living.md

+2
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ Settings related to typography.
158158
| lineHeight | boolean | false | |
159159
| textColumns | boolean | false | |
160160
| textDecoration | boolean | true | |
161+
| writingMode | boolean | false | |
161162
| textTransform | boolean | true | |
162163
| dropCap | boolean | true | |
163164
| fontSizes | array | | fluid, name, size, slug |
@@ -239,6 +240,7 @@ Typography styles.
239240
| lineHeight | string, object | |
240241
| textColumns | string | |
241242
| textDecoration | string, object | |
243+
| writingMode | string, object | |
242244
| textTransform | string, object | |
243245

244246
---

lib/block-supports/typography.php

+9-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ function gutenberg_register_typography_support( $block_type ) {
2929
$has_text_columns_support = _wp_array_get( $typography_supports, array( 'textColumns' ), false );
3030
$has_text_decoration_support = _wp_array_get( $typography_supports, array( '__experimentalTextDecoration' ), false );
3131
$has_text_transform_support = _wp_array_get( $typography_supports, array( '__experimentalTextTransform' ), false );
32+
$has_writing_mode_support = _wp_array_get( $typography_supports, array( '__experimentalWritingMode' ), false );
3233

3334
$has_typography_support = $has_font_family_support
3435
|| $has_font_size_support
@@ -38,7 +39,8 @@ function gutenberg_register_typography_support( $block_type ) {
3839
|| $has_line_height_support
3940
|| $has_text_columns_support
4041
|| $has_text_decoration_support
41-
|| $has_text_transform_support;
42+
|| $has_text_transform_support
43+
|| $has_writing_mode_support;
4244

4345
if ( ! $block_type->attributes ) {
4446
$block_type->attributes = array();
@@ -96,6 +98,7 @@ function gutenberg_apply_typography_support( $block_type, $block_attributes ) {
9698
$has_text_columns_support = _wp_array_get( $typography_supports, array( 'textColumns' ), false );
9799
$has_text_decoration_support = _wp_array_get( $typography_supports, array( '__experimentalTextDecoration' ), false );
98100
$has_text_transform_support = _wp_array_get( $typography_supports, array( '__experimentalTextTransform' ), false );
101+
$has_writing_mode_support = _wp_array_get( $typography_supports, array( '__experimentalWritingMode' ), false );
99102

100103
// Whether to skip individual block support features.
101104
$should_skip_font_size = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'fontSize' );
@@ -107,6 +110,7 @@ function gutenberg_apply_typography_support( $block_type, $block_attributes ) {
107110
$should_skip_text_decoration = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textDecoration' );
108111
$should_skip_text_transform = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'textTransform' );
109112
$should_skip_letter_spacing = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'letterSpacing' );
113+
$should_skip_writing_mode = wp_should_skip_block_supports_serialization( $block_type, 'typography', 'writingMode' );
110114

111115
$typography_block_styles = array();
112116
if ( $has_font_size_support && ! $should_skip_font_size ) {
@@ -158,6 +162,10 @@ function gutenberg_apply_typography_support( $block_type, $block_attributes ) {
158162
gutenberg_typography_get_preset_inline_style_value( $block_attributes['style']['typography']['letterSpacing'], 'letter-spacing' );
159163
}
160164

165+
if ( $has_writing_mode_support && ! $should_skip_writing_mode && isset( $block_attributes['style']['typography']['writingMode'] ) ) {
166+
$typography_block_styles['writingMode'] = _wp_array_get( $block_attributes, array( 'style', 'typography', 'writingMode' ), null );
167+
}
168+
161169
$attributes = array();
162170
$styles = gutenberg_style_engine_get_styles(
163171
array( 'typography' => $typography_block_styles ),

lib/class-wp-theme-json-gutenberg.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ class WP_Theme_JSON_Gutenberg {
202202
* `--wp--style--root--padding-*`, and `box-shadow` properties,
203203
* removed the `--wp--style--block-gap` property.
204204
* @since 6.2.0 Added `outline-*`, and `min-height` properties.
205+
* @since 6.3.0 Added `writing-mode` property.
205206
*
206207
* @var array
207208
*/
@@ -260,6 +261,7 @@ class WP_Theme_JSON_Gutenberg {
260261
'text-transform' => array( 'typography', 'textTransform' ),
261262
'filter' => array( 'filter', 'duotone' ),
262263
'box-shadow' => array( 'shadow' ),
264+
'writing-mode' => array( 'typography', 'writingMode' ),
263265
);
264266

265267
/**
@@ -339,7 +341,7 @@ class WP_Theme_JSON_Gutenberg {
339341
* @since 6.1.0 Added `layout.definitions` and `useRootPaddingAwareAlignments`.
340342
* @since 6.2.0 Added `dimensions.minHeight`, 'shadow.presets', 'shadow.defaultPresets',
341343
* `position.fixed` and `position.sticky`.
342-
* @since 6.3.0 Removed `layout.definitions`.
344+
* @since 6.3.0 Removed `layout.definitions`. Added `typography.writingMode`.
343345
* @var array
344346
*/
345347
const VALID_SETTINGS = array(
@@ -406,6 +408,7 @@ class WP_Theme_JSON_Gutenberg {
406408
'textColumns' => null,
407409
'textDecoration' => null,
408410
'textTransform' => null,
411+
'writingMode' => null,
409412
),
410413
'behaviors' => null,
411414
);
@@ -468,6 +471,7 @@ class WP_Theme_JSON_Gutenberg {
468471
'textColumns' => null,
469472
'textDecoration' => null,
470473
'textTransform' => null,
474+
'writingMode' => null,
471475
),
472476
'css' => null,
473477
);

lib/theme.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,8 @@
274274
"lineHeight": false,
275275
"textColumns": false,
276276
"textDecoration": true,
277-
"textTransform": true
277+
"textTransform": true,
278+
"writingMode": false
278279
},
279280
"blocks": {
280281
"core/button": {

packages/block-editor/src/components/global-styles/hooks.js

+2
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ const VALID_SETTINGS = [
7171
'typography.textColumns',
7272
'typography.textDecoration',
7373
'typography.textTransform',
74+
'typography.writingMode',
7475
];
7576

7677
export const useGlobalStylesReset = () => {
@@ -292,6 +293,7 @@ export function useSettingsForBlockElement(
292293
'letterSpacing',
293294
'textTransform',
294295
'textDecoration',
296+
'writingMode',
295297
].forEach( ( key ) => {
296298
if ( ! supportedStyles.includes( key ) ) {
297299
updatedSettings.typography = {

packages/block-editor/src/components/global-styles/typography-panel.js

+40
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import LineHeightControl from '../line-height-control';
1919
import LetterSpacingControl from '../letter-spacing-control';
2020
import TextTransformControl from '../text-transform-control';
2121
import TextDecorationControl from '../text-decoration-control';
22+
import WritingModeControl from '../writing-mode-control';
2223
import { getValueFromVariable } from './utils';
2324
import { setImmutably } from '../../utils/object';
2425

@@ -32,6 +33,7 @@ export function useHasTypographyPanel( settings ) {
3233
const hasLetterSpacing = useHasLetterSpacingControl( settings );
3334
const hasTextTransform = useHasTextTransformControl( settings );
3435
const hasTextDecoration = useHasTextDecorationControl( settings );
36+
const hasWritingMode = useHasWritingModeControl( settings );
3537
const hasTextColumns = useHasTextColumnsControl( settings );
3638
const hasFontSize = useHasFontSizeControl( settings );
3739

@@ -43,6 +45,7 @@ export function useHasTypographyPanel( settings ) {
4345
hasTextTransform ||
4446
hasFontSize ||
4547
hasTextDecoration ||
48+
hasWritingMode ||
4649
hasTextColumns
4750
);
4851
}
@@ -103,6 +106,10 @@ function useHasTextDecorationControl( settings ) {
103106
return settings?.typography?.textDecoration;
104107
}
105108

109+
function useHasWritingModeControl( settings ) {
110+
return settings?.typography?.writingMode;
111+
}
112+
106113
function useHasTextColumnsControl( settings ) {
107114
return settings?.typography?.textColumns;
108115
}
@@ -138,6 +145,7 @@ const DEFAULT_CONTROLS = {
138145
letterSpacing: true,
139146
textTransform: true,
140147
textDecoration: true,
148+
writingMode: true,
141149
textColumns: true,
142150
};
143151

@@ -310,6 +318,21 @@ export default function TypographyPanel( {
310318
const hasTextDecoration = () => !! value?.typography?.textDecoration;
311319
const resetTextDecoration = () => setTextDecoration( undefined );
312320

321+
// Text Orientation
322+
const hasWritingModeControl = useHasWritingModeControl( settings );
323+
const writingMode = decodeValue( inheritedValue?.typography?.writingMode );
324+
const setWritingMode = ( newValue ) => {
325+
onChange(
326+
setImmutably(
327+
value,
328+
[ 'typography', 'writingMode' ],
329+
newValue || undefined
330+
)
331+
);
332+
};
333+
const hasWritingMode = () => !! value?.typography?.writingMode;
334+
const resetWritingMode = () => setWritingMode( undefined );
335+
313336
const resetAllFilter = useCallback( ( previousValue ) => {
314337
return {
315338
...previousValue,
@@ -456,6 +479,23 @@ export default function TypographyPanel( {
456479
/>
457480
</ToolsPanelItem>
458481
) }
482+
{ hasWritingModeControl && (
483+
<ToolsPanelItem
484+
className="single-column"
485+
label={ __( 'Text orientation' ) }
486+
hasValue={ hasWritingMode }
487+
onDeselect={ resetWritingMode }
488+
isShownByDefault={ defaultControls.writingMode }
489+
panelId={ panelId }
490+
>
491+
<WritingModeControl
492+
value={ writingMode }
493+
onChange={ setWritingMode }
494+
size="__unstable-large"
495+
__nextHasNoMarginBottom
496+
/>
497+
</ToolsPanelItem>
498+
) }
459499
{ hasTextTransformControl && (
460500
<ToolsPanelItem
461501
label={ __( 'Letter case' ) }

packages/block-editor/src/components/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export { default as __experimentalFontFamilyControl } from './font-family';
5050
export { default as __experimentalLetterSpacingControl } from './letter-spacing-control';
5151
export { default as __experimentalTextDecorationControl } from './text-decoration-control';
5252
export { default as __experimentalTextTransformControl } from './text-transform-control';
53+
export { default as __experimentalWritingModeControl } from './writing-mode-control';
5354
export { default as __experimentalColorGradientControl } from './colors-gradients/control';
5455
export { default as __experimentalColorGradientSettingsDropdown } from './colors-gradients/dropdown';
5556
export { default as __experimentalPanelColorGradientSettings } from './colors-gradients/panel-color-gradient-settings';
Original file line numberDiff line numberDiff line change
@@ -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+
}
Original file line numberDiff line numberDiff line change
@@ -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+
}

packages/block-editor/src/hooks/supports.js

+7
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,17 @@ const TEXT_COLUMNS_SUPPORT_KEY = 'typography.textColumns';
3030
* decorations e.g. settings found in `block.json`.
3131
*/
3232
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';
3338
/**
3439
* Key within block settings' supports array indicating support for text
3540
* transforms e.g. settings found in `block.json`.
3641
*/
3742
const TEXT_TRANSFORM_SUPPORT_KEY = 'typography.__experimentalTextTransform';
43+
3844
/**
3945
* Key within block settings' supports array indicating support for letter-spacing
4046
* e.g. settings found in `block.json`.
@@ -50,6 +56,7 @@ const TYPOGRAPHY_SUPPORT_KEYS = [
5056
TEXT_COLUMNS_SUPPORT_KEY,
5157
TEXT_DECORATION_SUPPORT_KEY,
5258
TEXT_TRANSFORM_SUPPORT_KEY,
59+
WRITING_MODE_SUPPORT_KEY,
5360
LETTER_SPACING_SUPPORT_KEY,
5461
];
5562
const SPACING_SUPPORT_KEY = 'spacing';

packages/block-editor/src/hooks/typography.js

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const TEXT_DECORATION_SUPPORT_KEY = 'typography.__experimentalTextDecoration';
3030
const TEXT_COLUMNS_SUPPORT_KEY = 'typography.textColumns';
3131
const FONT_STYLE_SUPPORT_KEY = 'typography.__experimentalFontStyle';
3232
const FONT_WEIGHT_SUPPORT_KEY = 'typography.__experimentalFontWeight';
33+
const WRITING_MODE_SUPPORT_KEY = 'typography.__experimentalWritingMode';
3334
export const TYPOGRAPHY_SUPPORT_KEY = 'typography';
3435
export const TYPOGRAPHY_SUPPORT_KEYS = [
3536
LINE_HEIGHT_SUPPORT_KEY,
@@ -39,6 +40,7 @@ export const TYPOGRAPHY_SUPPORT_KEYS = [
3940
FONT_FAMILY_SUPPORT_KEY,
4041
TEXT_COLUMNS_SUPPORT_KEY,
4142
TEXT_DECORATION_SUPPORT_KEY,
43+
WRITING_MODE_SUPPORT_KEY,
4244
TEXT_TRANSFORM_SUPPORT_KEY,
4345
LETTER_SPACING_SUPPORT_KEY,
4446
];

packages/block-editor/src/hooks/utils.js

+3
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ export function useBlockSettings( name, parentLayout ) {
136136
const lineHeight = useSetting( 'typography.lineHeight' );
137137
const textColumns = useSetting( 'typography.textColumns' );
138138
const textDecoration = useSetting( 'typography.textDecoration' );
139+
const writingMode = useSetting( 'typography.writingMode' );
139140
const textTransform = useSetting( 'typography.textTransform' );
140141
const letterSpacing = useSetting( 'typography.letterSpacing' );
141142
const padding = useSetting( 'spacing.padding' );
@@ -211,6 +212,7 @@ export function useBlockSettings( name, parentLayout ) {
211212
textDecoration,
212213
textTransform,
213214
letterSpacing,
215+
writingMode,
214216
},
215217
spacing: {
216218
spacingSizes: {
@@ -244,6 +246,7 @@ export function useBlockSettings( name, parentLayout ) {
244246
textDecoration,
245247
textTransform,
246248
letterSpacing,
249+
writingMode,
247250
padding,
248251
margin,
249252
blockGap,

packages/block-library/src/paragraph/block.json

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
"__experimentalFontWeight": true,
5959
"__experimentalLetterSpacing": true,
6060
"__experimentalTextTransform": true,
61+
"__experimentalWritingMode": true,
6162
"__experimentalDefaultControls": {
6263
"fontSize": true
6364
}

packages/block-library/src/post-navigation-link/block.json

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"__experimentalTextTransform": true,
4646
"__experimentalTextDecoration": true,
4747
"__experimentalLetterSpacing": true,
48+
"__experimentalWritingMode": true,
4849
"__experimentalDefaultControls": {
4950
"fontSize": true
5051
}

0 commit comments

Comments
 (0)