Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Mobile] - Global styles - Add support to render font sizes and line height #34144

Merged
merged 17 commits into from
Sep 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ function BlockForType( {
baseGlobalStyles,
} ) {
const defaultColors = useSetting( 'color.palette' ) || emptyArray;
const fontSizes = useSetting( 'typography.fontSizes' ) || emptyArray;
const globalStyle = useGlobalStyles();
const mergedStyle = useMemo( () => {
return getMergedGlobalStyles(
Expand All @@ -59,7 +60,8 @@ function BlockForType( {
wrapperProps.style,
attributes,
defaultColors,
name
name,
fontSizes
);
}, [
defaultColors,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ exports[`File block renders file error state without crashing 1`] = `
disableEditingMenu={false}
focusable={true}
fontFamily="serif"
fontSize={16}
isMultiline={false}
maxImagesWidth={200}
onBackspace={[Function]}
Expand Down Expand Up @@ -150,6 +151,7 @@ exports[`File block renders file error state without crashing 1`] = `
disableEditingMenu={false}
focusable={true}
fontFamily="serif"
fontSize={16}
isMultiline={false}
maxImagesWidth={200}
minWidth={40}
Expand Down Expand Up @@ -259,6 +261,7 @@ exports[`File block renders file without crashing 1`] = `
disableEditingMenu={false}
focusable={true}
fontFamily="serif"
fontSize={16}
isMultiline={false}
maxImagesWidth={200}
onBackspace={[Function]}
Expand Down Expand Up @@ -330,6 +333,7 @@ exports[`File block renders file without crashing 1`] = `
disableEditingMenu={false}
focusable={true}
fontFamily="serif"
fontSize={16}
isMultiline={false}
maxImagesWidth={200}
minWidth={40}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ exports[`Search Block renders block with button inside option 1`] = `
disableEditingMenu={false}
focusable={true}
fontFamily="serif"
fontSize={16}
isMultiline={false}
maxImagesWidth={200}
onBackspace={[Function]}
Expand Down Expand Up @@ -126,6 +127,7 @@ exports[`Search Block renders block with button inside option 1`] = `
disableEditingMenu={false}
focusable={true}
fontFamily="serif"
fontSize={16}
isMultiline={false}
maxImagesWidth={200}
minWidth={75}
Expand Down Expand Up @@ -196,6 +198,7 @@ exports[`Search Block renders block with icon button option matches snapshot 1`]
disableEditingMenu={false}
focusable={true}
fontFamily="serif"
fontSize={16}
isMultiline={false}
maxImagesWidth={200}
onBackspace={[Function]}
Expand Down Expand Up @@ -356,6 +359,7 @@ exports[`Search Block renders block with label hidden matches snapshot 1`] = `
disableEditingMenu={false}
focusable={true}
fontFamily="serif"
fontSize={16}
isMultiline={false}
maxImagesWidth={200}
minWidth={75}
Expand Down Expand Up @@ -426,6 +430,7 @@ exports[`Search Block renders with default configuration matches snapshot 1`] =
disableEditingMenu={false}
focusable={true}
fontFamily="serif"
fontSize={16}
isMultiline={false}
maxImagesWidth={200}
onBackspace={[Function]}
Expand Down Expand Up @@ -529,6 +534,7 @@ exports[`Search Block renders with default configuration matches snapshot 1`] =
disableEditingMenu={false}
focusable={true}
fontFamily="serif"
fontSize={16}
isMultiline={false}
maxImagesWidth={200}
minWidth={75}
Expand Down Expand Up @@ -599,6 +605,7 @@ exports[`Search Block renders with no-button option matches snapshot 1`] = `
disableEditingMenu={false}
focusable={true}
fontFamily="serif"
fontSize={16}
isMultiline={false}
maxImagesWidth={200}
onBackspace={[Function]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
BLOCK_STYLE_ATTRIBUTES,
getBlockPaddings,
getBlockColors,
getBlockTypography,
} from './utils';

const GlobalStylesContext = createContext( { style: {} } );
Expand All @@ -27,7 +28,8 @@ export const getMergedGlobalStyles = (
wrapperPropsStyle,
blockAttributes,
defaultColors,
blockName
blockName,
fontSizes
) => {
const baseGlobalColors = {
baseColors: baseGlobalStyles || {},
Expand Down Expand Up @@ -60,8 +62,19 @@ export const getMergedGlobalStyles = (
blockStyleAttributes,
blockColors
);
const blockTypography = getBlockTypography(
blockStyleAttributes,
fontSizes,
blockName,
baseGlobalStyles
);

return { ...mergedStyle, ...blockPaddings, ...blockColors };
return {
...mergedStyle,
...blockPaddings,
...blockColors,
...blockTypography,
};
};

export const useGlobalStyles = () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
/**
* External dependencies
*/
import { find, startsWith, get } from 'lodash';
import { find, startsWith, get, camelCase, has } from 'lodash';

export const BLOCK_STYLE_ATTRIBUTES = [
'textColor',
'backgroundColor',
'style',
'color',
'fontSize',
];

// Mapping style properties name to native
Expand Down Expand Up @@ -121,6 +122,62 @@ export function getBlockColors(
return blockStyles;
}

export function getBlockTypography(
blockStyleAttributes,
fontSizes,
blockName,
baseGlobalStyles
) {
const typographyStyles = {};
const customBlockStyles = blockStyleAttributes?.style?.typography || {};
const blockGlobalStyles = baseGlobalStyles?.blocks?.[ blockName ];

// Global styles
if ( blockGlobalStyles?.typography ) {
const fontSize = blockGlobalStyles?.typography?.fontSize;
const lineHeight = blockGlobalStyles?.typography?.lineHeight;

if ( fontSize ) {
if ( parseInt( fontSize, 10 ) ) {
typographyStyles.fontSize = fontSize;
} else {
const mappedFontSize = find( fontSizes, {
slug: fontSize,
} );

if ( mappedFontSize ) {
typographyStyles.fontSize = mappedFontSize?.size;
}
}
}

if ( lineHeight ) {
typographyStyles.lineHeight = lineHeight;
}
}

if ( blockStyleAttributes?.fontSize ) {
const mappedFontSize = find( fontSizes, {
slug: blockStyleAttributes?.fontSize,
} );

if ( mappedFontSize ) {
typographyStyles.fontSize = mappedFontSize?.size;
}
}

// Custom styles
if ( customBlockStyles?.fontSize ) {
typographyStyles.fontSize = customBlockStyles?.fontSize;
}

if ( customBlockStyles?.lineHeight ) {
typographyStyles.lineHeight = customBlockStyles?.lineHeight;
}

return typographyStyles;
}

export function parseStylesVariables( styles, mappedValues, customValues ) {
let stylesBase = styles;
const variables = [ 'preset', 'custom' ];
Expand Down Expand Up @@ -152,7 +209,15 @@ export function parseStylesVariables( styles, mappedValues, customValues ) {
const customValuesData = customValues ?? JSON.parse( stylesBase );
stylesBase = stylesBase.replace( regex, ( _$1, $2 ) => {
const path = $2.split( '--' );
return get( customValuesData, path );
if ( has( customValuesData, path ) ) {
return get( customValuesData, path );
}

// Check for camelcase properties
return get( customValuesData, [
...path.slice( 0, path.length - 1 ),
camelCase( path[ path.length - 1 ] ),
] );
} );
}
} );
Expand All @@ -161,14 +226,19 @@ export function parseStylesVariables( styles, mappedValues, customValues ) {
}

export function getMappedValues( features, palette ) {
const typography = features?.typography;
const colors = { ...palette?.theme, ...palette?.user };
const fontSizes = {
...typography?.fontSizes?.theme,
...typography?.fontSizes?.user,
};
const mappedValues = {
color: {
values: colors,
slug: 'color',
},
'font-size': {
values: features?.typography?.fontSizes?.theme,
values: fontSizes,
slug: 'size',
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,12 @@ public void setFontSize(ReactAztecText view, float fontSize) {
(int) Math.ceil(PixelUtil.toPixelFromSP(fontSize)));
}

@ReactProp(name = ViewProps.LINE_HEIGHT)
public void setLineHeight(ReactAztecText view, float lineHeight) {
float textSize = view.getTextSize();
view.setLineSpacing(textSize * lineHeight, (float) (lineHeight / textSize));
}

@ReactProp(name = ViewProps.FONT_FAMILY)
public void setFontFamily(ReactAztecText view, String fontFamily) {
int style = Typeface.NORMAL;
Expand Down
31 changes: 29 additions & 2 deletions packages/react-native-aztec/ios/RNTAztecView/RCTAztecView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class RCTAztecView: Aztec.TextView {
get {
return super.textAlignment
}
}
}

private var previousContentSize: CGSize = .zero

Expand Down Expand Up @@ -109,6 +109,10 @@ class RCTAztecView: Aztec.TextView {
/// Font weight for all contents. Once this is set, it will always override the font weight for all of its
/// contents, regardless of what HTML is provided to Aztec.
private var fontWeight: String? = nil

/// Line height for all contents. Once this is set, it will always override the font size for all of its
/// contents, regardless of what HTML is provided to Aztec.
private var lineHeight: CGFloat? = nil

// MARK: - Formats

Expand Down Expand Up @@ -588,6 +592,7 @@ class RCTAztecView: Aztec.TextView {
}
fontSize = size
refreshFont()
refreshLineHeight()
}

@objc func setFontWeight(_ weight: String) {
Expand All @@ -597,6 +602,14 @@ class RCTAztecView: Aztec.TextView {
fontWeight = weight
refreshFont()
}

@objc func setLineHeight(_ newLineHeight: CGFloat) {
guard lineHeight != newLineHeight else {
return
}
lineHeight = newLineHeight
refreshLineHeight()
}

// MARK: - Font Refreshing

Expand Down Expand Up @@ -650,9 +663,23 @@ class RCTAztecView: Aztec.TextView {
/// This method should not be called directly. Call `refreshFont()` instead.
///
private func refreshTypingAttributesAndPlaceholderFont() {
let currentFont = font(from: typingAttributes)
let currentFont = font(from: typingAttributes)
placeholderLabel.font = currentFont
}

/// This method refreshes the line height.
private func refreshLineHeight() {
if let lineHeight = lineHeight {
let attributeString = NSMutableAttributedString(string: self.text)
let style = NSMutableParagraphStyle()
let currentFontSize = fontSize ?? defaultFont.pointSize
let lineSpacing = ((currentFontSize * lineHeight) / UIScreen.main.scale) - (currentFontSize / lineHeight) / 2

style.lineSpacing = lineSpacing
defaultParagraphStyle.regularLineSpacing = lineSpacing
textStorage.addAttribute(NSAttributedString.Key.paragraphStyle, value: style, range: NSMakeRange(0, textStorage.length))
}
}

// MARK: - Formatting interface

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ @interface RCT_EXTERN_MODULE(RCTAztecViewManager, NSObject)
RCT_EXPORT_VIEW_PROPERTY(fontFamily, NSString)
RCT_EXPORT_VIEW_PROPERTY(fontSize, CGFloat)
RCT_EXPORT_VIEW_PROPERTY(fontWeight, NSString)
RCT_EXPORT_VIEW_PROPERTY(lineHeight, CGFloat)

RCT_EXPORT_VIEW_PROPERTY(disableEditingMenu, BOOL)
RCT_REMAP_VIEW_PROPERTY(textAlign, textAlignment, NSTextAlignment)
Expand Down
6 changes: 2 additions & 4 deletions packages/react-native-aztec/src/AztecView.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,8 @@ class AztecView extends Component {
window.console.warn(
"Removing lineHeight style as it's not supported by native AztecView"
);
// IMPORTANT: Current Gutenberg implementation is supporting line-height without unit e.g. 'line-height':1.5
// and library which we are using to convert css to react-native requires unit to be included with dimension
// https://github.com/kristerkari/css-to-react-native-transform/blob/945866e84a505fdfb1a43b03ebe4bd32784a7f22/src/index.spec.js#L1234
// which means that we would need to patch the library if we want to support line-height from native AztecView in the future.
// Prevents passing line-heigth within styles to avoid a crash due to values without units
// We now support this but passing line-height as a prop instead
}

return (
Expand Down
Loading