Skip to content

Commit

Permalink
feat(prefabs): add Size2D prefab (#211)
Browse files Browse the repository at this point in the history
feat(targets): add iOS and web bindings for Size2D
tweak(prefabs): use Size2D for width/height on Image
tweak(examples): use Size2D for day part icons in PoodleSurf
tweak(examples): use Size2D in PoodleSurfObjC
fix(examples): expose Point2D to Objective-C
tweak(examples): use Point2D in PoodleSurfObjC
  • Loading branch information
n8chur committed Jul 31, 2019
1 parent e105c2e commit 6d95d8a
Show file tree
Hide file tree
Showing 38 changed files with 432 additions and 79 deletions.
2 changes: 1 addition & 1 deletion examples/lorem-ipsum/examples/web/src/App.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// Sass variables from `@diez/styles` provide a variety of directives. Here,
// we are using colors, URLs, and numbers.
background-image: $images-masthead-3x;
background-size: $images-masthead-width $images-masthead-height;
background-size: $images-masthead-size;
height: 194px;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,8 @@ class MainActivity : AppCompatActivity() {
time: TextView
) {
icon?.layoutParams = (icon?.layoutParams as LinearLayout.LayoutParams).apply {
width = cardDesign.dayPart.iconWidth.toPx()
height = cardDesign.dayPart.iconHeight.toPx()
width = cardDesign.dayPart.iconSize.width.toPx()
height = cardDesign.dayPart.iconSize.height.toPx()
}

valueUnit.setPadding(0, 0, 0, cardDesign.dayPartVerticalSpacing.toPx())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ - (void)viewDidLoad {
[self.stackView appendView:gradientView];
[gradientView.heightAnchor constraintEqualToAnchor:gradientView.widthAnchor multiplier:0.25].active = YES;

UILabel *pointLabel = [[UILabel alloc] init];
pointLabel.textAlignment = NSTextAlignmentCenter;
[self.stackView appendView:pointLabel];

UILabel *sizeLabel = [[UILabel alloc] init];
sizeLabel.textAlignment = NSTextAlignmentCenter;
[self.stackView appendView:sizeLabel];

self.diez = [[DEZDiezDesignSystem alloc] initWithView:self.view];
[self.diez attach:^(DEZDesignSystem * _Nullable component, NSError * _Nullable error) {
if (error != nil) {
Expand All @@ -82,6 +90,10 @@ - (void)viewDidLoad {
[gradientView.gradientLayer dez_applyLinearGradient:component.designs.report.waterTemperature.shared.gradient];

[animationView dez_loadLottie:component.designs.loading.animation completion:nil];

pointLabel.text = [NSString stringWithFormat:@"Point: %@", NSStringFromCGPoint(component.palette.contentBackground.end.cgPoint)];

sizeLabel.text = [NSString stringWithFormat:@"Size: %@", NSStringFromCGSize(component.designs.report.wind.dayPart.iconSize.cgSize)];
}];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,31 +52,19 @@ class DayPartView: UIView {
set { valueStackView.layoutMargins = newValue }
}

var iconWidth: CGFloat? {
var iconSize: CGSize? {
get {
let constraintValue = iconWidthConstraint.isActive ? iconWidthConstraint.constant : 0
if constraintValue > 0 {
return constraintValue
guard
let iconWidth = iconWidth,
let iconHeight = iconHeight else {
return nil
}

return iconView.image?.size.width
return CGSize(width: iconWidth, height: iconHeight)
}
set {
update(iconWidthConstraint, with: newValue)
}
}

var iconHeight: CGFloat? {
get {
let constraintValue = iconHeightConstraint.isActive ? iconHeightConstraint.constant : 0
if constraintValue > 0 {
return constraintValue
}

return iconView.image?.size.height
}
set {
update(iconHeightConstraint, with: newValue)
iconWidth = newValue?.width
iconHeight = newValue?.height
}
}

Expand Down Expand Up @@ -128,6 +116,16 @@ class DayPartView: UIView {
constraint.isActive = true
}

private var iconWidth: CGFloat? {
get { return iconWidthConstraint.isActive ? iconWidthConstraint.constant : iconView.image?.size.width }
set { update(iconWidthConstraint, with: newValue) }
}

private var iconHeight: CGFloat? {
get { return iconHeightConstraint.isActive ? iconHeightConstraint.constant : iconView.image?.size.height }
set { update(iconHeightConstraint, with: newValue) }
}

@available(*, unavailable)
required init?(coder aDecoder: NSCoder) { fatalError("\(#function) not implemented.") }
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ extension ReportViewController {
view.timeLabel.apply(design.timeTypograph)
view.valueUnitSpacing = design.valueUnitSpacing
view.layoutMargins = UIEdgeInsets(design.layoutMargins)
view.iconWidth = design.iconWidth
view.iconHeight = design.iconHeight
view.iconSize = design.iconSize.cgSize
}
}

Expand All @@ -97,11 +96,11 @@ extension ReportViewController {
func apply(_ design: NavigationTitleDesign, toView view: HorizontalImageLabelView, navigationBar: UINavigationBar) {
view.label.text = design.title
view.spacing = design.iconToTitleSpacing

// Using the UIKit class initializers for test coverage.
navigationBar.barTintColor = UIColor(design.barTintColor)
view.imageView.image = UIImage(design.icon)

// Applying the typograph manually to add test coverage for the .uiFont getter.
view.label.font = design.typograph.uiFont
view.label.textColor = design.typograph.color.uiColor
Expand Down
7 changes: 4 additions & 3 deletions examples/poodle-surf/examples/web/src/components/Column.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {DayPartDesign} from 'diez-poodle-surf';
import {DayPartDesign, Size2D} from 'diez-poodle-surf';
import * as React from 'react';

interface ColumnProps {
value: string;
name: string;
icon?: string;
iconSize?: Size2D;
ds: DayPartDesign;
style?: React.CSSProperties;
}
Expand All @@ -14,11 +15,11 @@ interface ColumnProps {
*/
export default class Column extends React.PureComponent<ColumnProps> {
render () {
const {name, value, icon, ds, style} = this.props;
const {name, value, icon, iconSize, ds, style} = this.props;

return (
<div style={{textAlign: 'center', ...style}}>
{icon && <img src={icon} alt="" style={{width: '67px', height: '67px'}} />}
{icon && iconSize && <img src={icon} alt="" style={iconSize.style} />}
<p style={{margin: 0, ...ds.valueTypograph.style}}>{value} <span style={ds.unitTypograph.style}>ft</span></p>
<span style={ds.timeTypograph.style}>{name}</span>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export default class ForecastCard extends React.PureComponent<ForecastCardProps>
key={dayPart.dayPart}
ds={ds.dayPart}
icon={dayPart.direction && dayPart.direction.url}
iconSize={ds.dayPart.iconSize}
name={dayPart.dayPart}
value={dayPart.value}
/>
Expand Down
5 changes: 2 additions & 3 deletions examples/poodle-surf/src/designs/ReportDesign.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Typograph, LinearGradient, Color} from '@diez/prefabs';
import {Color, LinearGradient, Size2D, Typograph} from '@diez/prefabs';
import {prefab} from '@diez/engine';
import {PoodleSurfSlices} from './PoodleSurf.sketch';
import {EdgeInsets} from './components/EdgeInsets';
Expand Down Expand Up @@ -81,8 +81,7 @@ class DayPartDesign {
timeTypograph = typographs.caption;
valueUnitSpacing = LayoutValues.CompactSpacing;
layoutMargins = new EdgeInsets();
iconWidth = DayPartIconSize;
iconHeight = DayPartIconSize;
iconSize = Size2D.make(DayPartIconSize, DayPartIconSize);
}

interface ForecastCardDesignData {
Expand Down
20 changes: 5 additions & 15 deletions packages/prefabs/src/image.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Integer, prefab, Target} from '@diez/engine';
import {prefab, Target} from '@diez/engine';
import {File, FileType} from './file';
import {Size2D} from './size2d';

/**
* Responsive image data.
Expand All @@ -9,8 +10,7 @@ export interface ImageData {
file2x: File;
file3x: File;
file4x: File;
width: Integer;
height: Integer;
size: Size2D;
}

/**
Expand Down Expand Up @@ -46,12 +46,11 @@ export class Image extends prefab<ImageData>() {
const name = filename.slice(0, extensionLocation);
const ext = filename.slice(extensionLocation);
return new Image({
width,
height,
file: new File({src, type: FileType.Image}),
file2x: new File({src: `${dir}/${name}@2x${ext}`, type: FileType.Image}),
file3x: new File({src: `${dir}/${name}@3x${ext}`, type: FileType.Image}),
file4x: new File({src: `${dir}/${name}@4x${ext}`, type: FileType.Image}),
size: Size2D.make(width, height),
});
}

Expand All @@ -60,21 +59,12 @@ export class Image extends prefab<ImageData>() {
file2x: new File({type: FileType.Image}),
file3x: new File({type: FileType.Image}),
file4x: new File({type: FileType.Image}),
width: 0,
height: 0,
size: Size2D.make(0, 0),
};

options = {
file4x: {
targets: [Target.Android],
},
};

protected sanitize (data: ImageData) {
return {
...data,
width: Math.round(data.width),
height: Math.round(data.height),
};
}
}
1 change: 1 addition & 0 deletions packages/prefabs/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export * from './image';
export * from './linear-gradient';
export * from './lottie';
export * from './point2d';
export * from './size2d';
export * from './typography';
36 changes: 36 additions & 0 deletions packages/prefabs/src/size2d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {prefab} from '@diez/engine';

/**
* Size data.
*/
export interface Size2DData {
/**
* The width value of the size.
*/
width: number;
/**
* The height value of the size.
*/
height: number;
}

/**
* Provides a two dimensional size.
*
* Usage: `size = Size2D.make(1920, 1080);`.
*
* @noinheritdoc
*/
export class Size2D extends prefab<Size2DData>() {
defaults = {
width: 0,
height: 0,
};

/**
* Creates a two dimensional size.
*/
static make (width: number, height: number) {
return new Size2D({width, height});
}
}
4 changes: 2 additions & 2 deletions packages/prefabs/test/image.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {Image} from '../src/image';
import {Size2D} from '../src/size2d';

describe('image', () => {
test('basic functionality', () => {
Expand All @@ -8,8 +9,7 @@ describe('image', () => {
file2x: {src: 'path/to/image@2x.png', type: 'image'},
file3x: {src: 'path/to/image@3x.png', type: 'image'},
file4x: {src: 'path/to/image@4x.png', type: 'image'},
width: 640,
height: 480,
size: Size2D.make(640, 480).serialize(),
});
});
});
8 changes: 8 additions & 0 deletions packages/prefabs/test/size2d.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {Size2D} from '../src/size2d';

describe('Size2D', () => {
test('basic functionality', () => {
const size = Size2D.make(400, 300);
expect(size.serialize()).toEqual({width: 400, height: 300});
});
});
5 changes: 5 additions & 0 deletions packages/targets/.diezrc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@
"android": "./lib/bindings/Point2D/android",
"web": "./lib/bindings/Point2D/web"
},
"@diez/prefabs:Size2D": {
"ios": "./lib/bindings/Size2D/ios",
"android": "./lib/bindings/Size2D/android",
"web": "./lib/bindings/Size2D/web"
},
"@diez/prefabs:Typograph": {
"ios": "./lib/bindings/Typograph/ios",
"android": "./lib/bindings/Typograph/android",
Expand Down
5 changes: 3 additions & 2 deletions packages/targets/sources/android/bindings/Image.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.bumptech.glide.request.transition.Transition
import com.bumptech.glide.signature.ObjectKey
import android.widget.ImageView
import android.widget.TextView
import kotlin.math.roundToInt

{{> androidDataClassStart }}

Expand Down Expand Up @@ -113,8 +114,8 @@ private val effectiveDensity: Int
}

private fun getFromNetwork(image: Image, view: View, callback: (BitmapDrawable) -> Unit) {
val width = (image.width * Environment.resources.displayMetrics.density.toDouble()).toInt()
val height = (image.height * Environment.resources.displayMetrics.density.toDouble()).toInt()
val width = (image.size.width * Environment.resources.displayMetrics.density.toDouble()).roundToInt()
val height = (image.size.height * Environment.resources.displayMetrics.density.toDouble()).roundToInt()
Glide
.with(view.context)
.load(image.correctDensityFile.url)
Expand Down
2 changes: 2 additions & 0 deletions packages/targets/sources/ios/bindings/Point2D+Binding.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Foundation
import CoreGraphics

extension Point2D {
@objc
public var cgPoint: CGPoint {
return CGPoint(x: x, y: y)
}
Expand Down
9 changes: 9 additions & 0 deletions packages/targets/sources/ios/bindings/Size2D+Binding.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Foundation
import CoreGraphics

extension Size2D {
@objc
public var cgSize: CGSize {
return CGSize(width: width, height: height)
}
}
36 changes: 36 additions & 0 deletions packages/targets/sources/web/bindings/Size2D.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export declare class Size2D {
/**
* The width of the size.
*/
width: number;
/**
* The height of the size.
*/
height: number;
/**
* The CSS `width` value.
* @example
* 400px
*/
widthCss: string;
/**
* The CSS `height` value.
* @example
* 300px
*/
heightCss: string;
/**
* CSS declarations for the `width` and `height` CSS properties.
*/
style: {width: string, height: string};
/**
* The CSS `background-size` value.
* @example
* 400px 300px
*/
backgroundSizeCss: string;
/**
* CSS declarations for the `background-size` CSS property.
*/
backgroundSizeStyle: {backgroundSize: string};
}
Loading

0 comments on commit 6d95d8a

Please sign in to comment.