Skip to content

Commit

Permalink
feat(typograph): add support for controlling text scaling on mobile t…
Browse files Browse the repository at this point in the history
…argets (#242)

This includes:
- On both iOS and Android, the ability to enable/disable text scaling for a Typograph.
- On iOS, the ability to specify the type (via `UIFontMetric` / `UIFont.TextStyle`) of scaling that should occur
  • Loading branch information
Westin Newell committed Nov 14, 2019
1 parent 56abc7a commit dba0f6a
Show file tree
Hide file tree
Showing 19 changed files with 191 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.1.0",
"license": "MIT",
"dependencies": {
"@diez/web-sdk-common": "^10.0.0-beta.3",
"@diez/web-sdk-common": "^10.0.0-beta.4",
"lottie-web": "^5.5.2"
}
}
2 changes: 1 addition & 1 deletion examples/lorem-ipsum/examples/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ EXTERNAL SOURCES:
:path: "../../build/diez-lorem-ipsum-ios"

SPEC CHECKSUMS:
DiezLoremIpsum: 3b02836469ae9dd33886900e766abcbaab33cc2c
DiezLoremIpsum: e4b40e70559db532d5256bc8eb279602f012b4fb
lottie-ios: 43a472d22b2dd2bed292cc4010c0b4d2e66d3ba8

PODFILE CHECKSUM: 0252dab712b9ae8559f499051289c6c08eadc0f9
Expand Down
2 changes: 1 addition & 1 deletion examples/poodle-surf/examples/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ EXTERNAL SOURCES:
:path: "../../build/diez-poodle-surf-ios"

SPEC CHECKSUMS:
DiezPoodleSurf: eed8e66e89bf423cd65c8270b65b46196a96ef97
DiezPoodleSurf: b53603060353a2513c351956743865861e6affac
lottie-ios: 43a472d22b2dd2bed292cc4010c0b4d2e66d3ba8

PODFILE CHECKSUM: 677d35819389b4af10b2328fe426d72e2250ac2d
Expand Down
9 changes: 8 additions & 1 deletion examples/poodle-surf/src/designs/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Font, LinearGradient, Toward, Typograph} from '@diez/prefabs';
import {Font, IOSTextStyle, LinearGradient, Toward, Typograph} from '@diez/prefabs';
import {poodleSurfTokens} from './PoodleSurf.sketch';

class Palette {
Expand Down Expand Up @@ -52,36 +52,43 @@ class Typographs {
font: Fonts.Nunito.Bold,
fontSize: FontSizes.Title,
color: palette.foreground,
iosTextStyle: IOSTextStyle.Title1,
});
headerCaption = new Typograph({
font: Fonts.Nunito.Regular,
fontSize: FontSizes.Caption,
color: palette.foreground,
iosTextStyle: IOSTextStyle.Caption1,
});
cardTitle = new Typograph({
font: Fonts.Nunito.Regular,
fontSize: FontSizes.CardTitle,
color: palette.contentForeground,
iosTextStyle: IOSTextStyle.Title2,
});
value = new Typograph({
font: Fonts.Nunito.Regular,
fontSize: FontSizes.Value,
color: palette.contentForeground,
iosTextStyle: IOSTextStyle.Headline,
});
unit = new Typograph({
font: Fonts.Nunito.Regular,
fontSize: FontSizes.Unit,
color: palette.contentForeground,
iosTextStyle: IOSTextStyle.Subheadline,
});
caption = new Typograph({
font: Fonts.Nunito.Regular,
fontSize: FontSizes.Caption,
color: palette.contentForeground,
iosTextStyle: IOSTextStyle.Caption2,
});
captionHeader = new Typograph({
font: Fonts.Nunito.Bold,
fontSize: FontSizes.Caption,
color: palette.contentForeground,
iosTextStyle: IOSTextStyle.Caption2,
});
}

Expand Down
2 changes: 1 addition & 1 deletion packages/prefabs/src/linear-gradient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class GradientStop extends prefab<GradientStopData>() {
/**
* The direction of a linear gradient relative to the containing view's edges.
*/
export const enum Toward {
export enum Toward {
Top = 0,
TopRight = 45,
Right = 90,
Expand Down
32 changes: 32 additions & 0 deletions packages/prefabs/src/typography.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,38 @@ export class Font extends prefab<FontData>() {
}
}

/**
* An enumeration of the supported iOS `UIFont.TextStyle`s.
*/
export enum IOSTextStyle {
Body = 'body',
Callout = 'callout',
Caption1 = 'caption1',
Caption2 = 'caption2',
Footnote = 'footnote',
Headline = 'headline',
Subheadline = 'subheadline',
LargeTitle = 'largeTitle',
Title1 = 'title1',
Title2 = 'title2',
Title3 = 'title3',
}

/**
* Typograph data.
*/
export interface TypographData {
font: Font;
fontSize: number;
color: Color;
/**
* The iOS `UIFont.TextStyle` of the `Typograph` (iOS only).
*/
iosTextStyle: IOSTextStyle;
/**
* Indicates whether the `Typograph` should scale with the system's accessibility settings (iOS and Android only).
*/
shouldScale: boolean;
}

/**
Expand All @@ -96,6 +121,13 @@ export class Typograph extends prefab<TypographData>() {
font: new Font(),
fontSize: 12,
color: Color.hsla(0, 0, 0, 1),
iosTextStyle: IOSTextStyle.Body,
shouldScale: true,
};

options = {
iosTextStyle: {targets: [Target.Ios]},
shouldScale: {targets: [Target.Ios, Target.Android]},
};
}

Expand Down
10 changes: 9 additions & 1 deletion packages/prefabs/test/typography.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import {Color} from '../src/color';
import {Font, Typograph} from '../src/typography';
import {Font, IOSTextStyle, Typograph} from '../src/typography';

describe('typograph', () => {
test('basic functionality', () => {
const typograph = new Typograph({
font: Font.fromFile('Bloop-MediumItalic.ttf'),
fontSize: 50,
color: Color.hsla(0, 0, 0, 0.5),
shouldScale: false,
iosTextStyle: IOSTextStyle.Title1,
});

expect(typograph.serialize()).toEqual({
Expand All @@ -19,12 +21,16 @@ describe('typograph', () => {
},
fontSize: 50,
color: {h: 0, s: 0, l: 0, a: 0.5},
shouldScale: false,
iosTextStyle: 'title1',
});

const typographWithSpecificName = new Typograph({
font: Font.fromFile('Bloop-MediumItalic.ttf', 'SomethingElse'),
fontSize: 50,
color: Color.hsla(0, 0, 0, 0.5),
shouldScale: true,
iosTextStyle: IOSTextStyle.Title2,
});

expect(typographWithSpecificName.serialize()).toEqual({
Expand All @@ -37,6 +43,8 @@ describe('typograph', () => {
},
fontSize: 50,
color: {h: 0, s: 0, l: 0, a: 0.5},
shouldScale: true,
iosTextStyle: 'title2',
});
});
});
2 changes: 1 addition & 1 deletion packages/sources/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export interface OAuthable {
/**
* Supported image formats for exporting.
*/
export const enum ImageFormats {
export enum ImageFormats {
png = 'png',
svg = 'svg',
jpg = 'jpg',
Expand Down
5 changes: 3 additions & 2 deletions packages/targets/sources/android/bindings/Typograph.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.widget.TextView
import java.io.BufferedInputStream
import java.io.FileOutputStream
import android.os.StrictMode
import android.util.TypedValue

{{> androidDataClassStart }}

Expand All @@ -31,7 +32,6 @@ import android.os.StrictMode
return typeface
}


return Typeface.create("", Typeface.NORMAL)
}

Expand All @@ -41,7 +41,8 @@ import android.os.StrictMode

fun TextView.apply(typograph: Typograph) {
this.typeface = typograph.typeface
this.textSize = typograph.fontSize
val unit = if (typograph.shouldScale) TypedValue.COMPLEX_UNIT_SP else TypedValue.COMPLEX_UNIT_DIP
this.setTextSize(unit, typograph.fontSize)
this.setTextColor(typograph.color.color)
}

Expand Down
60 changes: 58 additions & 2 deletions packages/targets/sources/ios/bindings/Typograph+Binding.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,24 @@ extension Typograph {
/**
The `UIFont` of the `Typograph`.
Iff `shouldScale` is `true`, the font will be scaled according to `UIFontMetric`s Dynamic Type scaling system with the `Typograph`s `iosTextStyle` value.
This uses the `UIFont(name:size)` initializer and may return nil as a result.
*/
@objc
public var uiFont: UIFont? {
registerFont(font)
return _uiFont(for: nil)
}

/**
The `UIFont` of the `Typograph`.
Iff `shouldScale` is `true`, the font will be scaled according to `UIFontMetric`s Dynamic Type scaling system with the `Typograph`s `iosTextStyle` value and the provided `UITraitCollection`.
return UIFont(name: font.name, size: fontSize)
This uses the `UIFont(name:size)` initializer and may return nil as a result.
*/
public func uiFont(for traitCollection: UITraitCollection) -> UIFont? {
return _uiFont(for: traitCollection)
}

/**
Expand All @@ -56,6 +67,48 @@ extension Typograph {
public func attributedString(decorating string: String) -> NSAttributedString {
return NSAttributedString(string: string, typograph: self)
}

/**
The `UIFont.TextStyle` for the `Typograph`.
*/
@objc
public var uiFontTextStyle: UIFont.TextStyle {
switch iosTextStyle {
case "body": return .body
case "callout": return .callout
case "caption1": return .caption1
case "caption2": return .caption2
case "footnote": return .footnote
case "headline": return .headline
case "subheadline": return .subheadline
case "largeTitle": return .largeTitle
case "title1": return .title1
case "title2": return .title2
case "title3": return .title3
default: return .body
}
}

private func _uiFont(for traitCollection: UITraitCollection?) -> UIFont? {
registerFont(font)

guard let uiFont = UIFont(name: font.name, size: fontSize) else {
return nil
}

guard shouldScale else {
return uiFont

}

let metrics = UIFontMetrics(forTextStyle: uiFontTextStyle)

guard let traitCollection = traitCollection else {
return metrics.scaledFont(for: uiFont)
}

return metrics.scaledFont(for: uiFont, compatibleWith: traitCollection)
}
}

extension NSAttributedString {
Expand All @@ -76,6 +129,7 @@ extension UILabel {
public func apply(_ typograph: Typograph) {
font = typograph.uiFont
textColor = typograph.color.uiColor
adjustsFontForContentSizeCategory = typograph.shouldScale
}
}

Expand All @@ -87,6 +141,7 @@ extension UITextView {
public func apply(_ typograph: Typograph) {
font = typograph.uiFont
textColor = typograph.color.uiColor
adjustsFontForContentSizeCategory = typograph.shouldScale
}
}

Expand All @@ -98,5 +153,6 @@ extension UITextField {
public func apply(_ typograph: Typograph) {
font = typograph.uiFont
textColor = typograph.color.uiColor
adjustsFontForContentSizeCategory = typograph.shouldScale
}
}
3 changes: 1 addition & 2 deletions packages/targets/sources/ios/core/Diez.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ public protocol StateBag: Decodable {
- Note: The presence of a `WKWebView` in hot mode and the need to provide a `UIView` will be removed in the future.
*/
public final class Diez<T>: NSObject where T: StateBag {
private var component: T

/**
- Parameter view: When in [hot mode](x-source-tag://Diez), this view will have a visually empty `WKWebView` added to it in order to communicate with the Diez server. When not in [hot mode] (x-source-tag://Diez) this value is unused.
Expand Down Expand Up @@ -119,6 +117,7 @@ public final class Diez<T>: NSObject where T: StateBag {
}
}

private var component: T
private let decoder = JSONDecoder()
private var subscribers: [AttachSubscription] = []
private let updateObserver: UpdateObserver<T>?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package org.diez.stub
data class Bindings(
val image: Image = Image(File("assets/image%20with%20spaces.jpg", "image"), File("assets/image%20with%20spaces@2x.jpg", "image"), File("assets/image%20with%20spaces@3x.jpg", "image"), File("assets/image%20with%20spaces@4x.jpg", "image"), Size2D(246F, 246F)),
val lottie: Lottie = Lottie(File("assets/lottie.json", "raw"), true, true),
val typograph: Typograph = Typograph(Font(File("assets/SomeFont.ttf", "font"), "SomeFont"), 50F, Color(0.16666666666666666F, 1F, 0.5F, 1F)),
val typograph: Typograph = Typograph(Font(File("assets/SomeFont.ttf", "font"), "SomeFont"), 50F, Color(0.16666666666666666F, 1F, 0.5F, 1F), true),
val linearGradient: LinearGradient = LinearGradient(arrayOf<GradientStop>(GradientStop(0F, Color(0F, 1F, 0.5F, 1F)), GradientStop(1F, Color(0.6666666666666666F, 1F, 0.5F, 1F))), Point2D(0F, 0.5F), Point2D(1F, 0.5F)),
val point: Point2D = Point2D(0.5F, 0.5F),
val size: Size2D = Size2D(400F, 300F),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import android.widget.TextView
import java.io.BufferedInputStream
import java.io.FileOutputStream
import android.os.StrictMode
import android.util.TypedValue

data class Typograph(
val font: Font,
val fontSize: Float,
val color: Color
val color: Color,
val shouldScale: Boolean
) {
companion object {}

Expand All @@ -36,7 +38,6 @@ data class Typograph(
return typeface
}


return Typeface.create("", Typeface.NORMAL)
}

Expand All @@ -46,7 +47,8 @@ data class Typograph(

fun TextView.apply(typograph: Typograph) {
this.typeface = typograph.typeface
this.textSize = typograph.fontSize
val unit = if (typograph.shouldScale) TypedValue.COMPLEX_UNIT_SP else TypedValue.COMPLEX_UNIT_DIP
this.setTextSize(unit, typograph.fontSize)
this.setTextColor(typograph.color.color)
}

Expand Down
Loading

0 comments on commit dba0f6a

Please sign in to comment.