From 74f26f4498b75de3b438f4dd751b6a9706f07ed8 Mon Sep 17 00:00:00 2001 From: Eddy Verbruggen Date: Thu, 13 Jul 2017 14:00:18 +0200 Subject: [PATCH] Add CSS support for line-height (#4534) * Add CSS support for line-height (issue #1664) * Implemented @vakrilov's feedback * Implemented @vakrilov's feedback (changed Android default impl) --- tests/app/ui/text-view/text-view-tests.ts | 12 +++++++++++ .../ui/styling/style-properties.d.ts | 1 + tns-core-modules/ui/styling/style/style.d.ts | 1 + tns-core-modules/ui/styling/style/style.ts | 1 + .../ui/text-base/text-base-common.ts | 12 ++++++++++- .../ui/text-base/text-base.android.ts | 9 ++++++++- .../ui/text-base/text-base.ios.ts | 20 +++++++++++++++++-- 7 files changed, 52 insertions(+), 4 deletions(-) diff --git a/tests/app/ui/text-view/text-view-tests.ts b/tests/app/ui/text-view/text-view-tests.ts index ce42ed181..e8fa09040 100644 --- a/tests/app/ui/text-view/text-view-tests.ts +++ b/tests/app/ui/text-view/text-view-tests.ts @@ -378,6 +378,18 @@ export var testNativeFontSizeFromLocal = function () { }); } +var expectedLineHeight = 10; +export var testLocalLineHeightFromCss = function () { + helper.buildUIAndRunTest(_createTextViewFunc(), function (views: Array) { + var textView = views[0]; + var page = views[1]; + + page.css = "textview { line-height: " + expectedLineHeight + "; }"; + var actualResult = textView.style.lineHeight; + TKUnit.assert(actualResult === expectedLineHeight, "Actual: " + actualResult + "; Expected: " + expectedLineHeight); + }); +} + var expectedColorHex = "#FFFF0000"; var expectedNormalizedColorHex = "#FF0000"; export var testLocalColorFromCss = function () { diff --git a/tns-core-modules/ui/styling/style-properties.d.ts b/tns-core-modules/ui/styling/style-properties.d.ts index 10c766bc9..12a44d619 100644 --- a/tns-core-modules/ui/styling/style-properties.d.ts +++ b/tns-core-modules/ui/styling/style-properties.d.ts @@ -86,6 +86,7 @@ export const minWidthProperty: CssProperty; export const widthProperty: CssProperty; export const heightProperty: CssProperty; +export const lineHeightProperty: CssProperty; export const marginProperty: ShorthandProperty; export const marginLeftProperty: CssProperty; export const marginRightProperty: CssProperty; diff --git a/tns-core-modules/ui/styling/style/style.d.ts b/tns-core-modules/ui/styling/style/style.d.ts index 2599f819f..6886b3de1 100644 --- a/tns-core-modules/ui/styling/style/style.d.ts +++ b/tns-core-modules/ui/styling/style/style.d.ts @@ -96,6 +96,7 @@ export class Style extends Observable { public visibility: Visibility; public letterSpacing: number; + public lineHeight: number; public textAlignment: TextAlignment; public textDecoration: TextDecoration; public textTransform: TextTransform; diff --git a/tns-core-modules/ui/styling/style/style.ts b/tns-core-modules/ui/styling/style/style.ts index ff8db41e6..96f8f517a 100644 --- a/tns-core-modules/ui/styling/style/style.ts +++ b/tns-core-modules/ui/styling/style/style.ts @@ -68,6 +68,7 @@ export class Style extends Observable implements StyleDefinition { public visibility: Visibility; public letterSpacing: number; + public lineHeight: number; public textAlignment: TextAlignment; public textDecoration: TextDecoration; public textTransform: TextTransform; diff --git a/tns-core-modules/ui/text-base/text-base-common.ts b/tns-core-modules/ui/text-base/text-base-common.ts index d8689243d..a2c43c704 100644 --- a/tns-core-modules/ui/text-base/text-base-common.ts +++ b/tns-core-modules/ui/text-base/text-base-common.ts @@ -55,6 +55,13 @@ export abstract class TextBaseCommon extends View implements TextBaseDefinition this.style.letterSpacing = value; } + get lineHeight(): number { + return this.style.lineHeight; + } + set lineHeight(value: number) { + this.style.lineHeight = value; + } + get textAlignment(): TextAlignment { return this.style.textAlignment; } @@ -202,4 +209,7 @@ export const textDecorationProperty = new CssProperty({ n textDecorationProperty.register(Style); export const letterSpacingProperty = new CssProperty({ name: "letterSpacing", cssName: "letter-spacing", defaultValue: 0, affectsLayout: isIOS, valueConverter: v => parseFloat(v) }); -letterSpacingProperty.register(Style); \ No newline at end of file +letterSpacingProperty.register(Style); + +export const lineHeightProperty = new CssProperty({ name: "lineHeight", cssName: "line-height", affectsLayout: isIOS, valueConverter: v => parseFloat(v) }); +lineHeightProperty.register(Style); diff --git a/tns-core-modules/ui/text-base/text-base.android.ts b/tns-core-modules/ui/text-base/text-base.android.ts index 5c3f785e2..c1785b704 100644 --- a/tns-core-modules/ui/text-base/text-base.android.ts +++ b/tns-core-modules/ui/text-base/text-base.android.ts @@ -5,7 +5,7 @@ import { TextBaseCommon, formattedTextProperty, textAlignmentProperty, textDecorationProperty, fontSizeProperty, textProperty, textTransformProperty, letterSpacingProperty, colorProperty, fontInternalProperty, paddingLeftProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty, Length, - whiteSpaceProperty, FormattedString, layout, Span, Color, isBold + whiteSpaceProperty, lineHeightProperty, FormattedString, layout, Span, Color, isBold } from "./text-base-common"; export * from "./text-base-common"; @@ -218,6 +218,13 @@ export class TextBase extends TextBaseCommon { } } + [lineHeightProperty.getDefault](): number { + return this.nativeView.getLineSpacingExtra() / layout.getDisplayDensity(); + } + [lineHeightProperty.setNative](value: number) { + this.nativeView.setLineSpacing(value * layout.getDisplayDensity(), 1); + } + [fontInternalProperty.getDefault](): android.graphics.Typeface { return this.nativeView.getTypeface(); } diff --git a/tns-core-modules/ui/text-base/text-base.ios.ts b/tns-core-modules/ui/text-base/text-base.ios.ts index cf7344a86..2d85ae595 100644 --- a/tns-core-modules/ui/text-base/text-base.ios.ts +++ b/tns-core-modules/ui/text-base/text-base.ios.ts @@ -2,8 +2,8 @@ import { Font } from "../styling/font"; import { TextBaseCommon, textProperty, formattedTextProperty, textAlignmentProperty, textDecorationProperty, - textTransformProperty, letterSpacingProperty, colorProperty, fontInternalProperty, FormattedString, - Span, Color, isBold + textTransformProperty, letterSpacingProperty, colorProperty, fontInternalProperty, lineHeightProperty, + FormattedString, Span, Color, isBold } from "./text-base-common"; export * from "./text-base-common"; @@ -92,6 +92,10 @@ export class TextBase extends TextBaseCommon { this._setNativeText(); } + [lineHeightProperty.setNative](value: number) { + this._setNativeText(); + } + _setNativeText(reset: boolean = false): void { if (reset) { const nativeView = this.nativeView; @@ -122,6 +126,12 @@ export class TextBase extends TextBaseCommon { attrText.addAttributeValueRange(NSKernAttributeName, this.letterSpacing * this.nativeView.font.pointSize, { location: 0, length: attrText.length }); } + if (this.style.lineHeight) { + const paragraphStyle = NSMutableParagraphStyle.alloc().init(); + paragraphStyle.lineSpacing = this.lineHeight; + attrText.addAttributeValueRange(NSParagraphStyleAttributeName, paragraphStyle, { location: 0, length: attrText.length }); + } + if (this.nativeView instanceof UIButton) { this.nativeView.setAttributedTitleForState(attrText, UIControlState.Normal); } @@ -154,6 +164,12 @@ export class TextBase extends TextBaseCommon { dict.set(NSKernAttributeName, style.letterSpacing * this.nativeView.font.pointSize); } + if (style.lineHeight) { + const paragraphStyle = NSMutableParagraphStyle.alloc().init(); + paragraphStyle.lineSpacing = style.lineHeight; + dict.set(NSParagraphStyleAttributeName, paragraphStyle); + } + const isTextView = this.nativeView instanceof UITextView; if (style.color && (dict.size > 0 || isTextView)) { dict.set(NSForegroundColorAttributeName, style.color.ios);