diff --git a/apps/app/ui-tests-app/flexbox/flexbox.css b/apps/app/ui-tests-app/flexbox/flexbox.css
new file mode 100644
index 000000000..0be39be0f
--- /dev/null
+++ b/apps/app/ui-tests-app/flexbox/flexbox.css
@@ -0,0 +1,28 @@
+@keyframes select {
+ 0%, 100% {
+ transform: scale(1, 1);
+ }
+ 50% {
+ transform: scale(1.4, 1.4);
+ }
+}
+#container>Label {
+ border-width: 1;
+ border-color: black;
+ border-radius: 5;
+}
+#container>Label[selected="yes"] {
+ border-color: yellow;
+ /* animation-name: select;
+ animation-duration: 0.2s;
+ animation-fill-mode: forwards;
+ animation-iteration-count: 1;*/
+}
+
+.control {
+ font-size: 11;
+}
+.control Button {
+ padding: 2;
+ margin: 2;
+}
\ No newline at end of file
diff --git a/apps/app/ui-tests-app/flexbox/flexbox.ts b/apps/app/ui-tests-app/flexbox/flexbox.ts
new file mode 100644
index 000000000..592b855dd
--- /dev/null
+++ b/apps/app/ui-tests-app/flexbox/flexbox.ts
@@ -0,0 +1,55 @@
+import {isAndroid} from "platform";
+import * as flexbox from "ui/layouts/flexbox-layout";
+
+function set(what: string) {
+ return function(args) {
+ args.object.page.getViewById("container")[what] = args.object.text;
+ }
+}
+
+export const flexDirection = set("flexDirection");
+export const flexWrap = set("flexWrap");
+export const justifyContent = set("justifyContent");
+export const alignItems = set("alignItems");
+export const alignContent = set("alignContent");
+
+let lastSelection = null;
+export function select(args) {
+ console.log("Select: " + args.object);
+ lastSelection = args.object;
+
+ if (isAndroid) {
+ let layoutParams = lastSelection.android.getLayoutParams();
+ console.log("Selection: " + lastSelection + ": " + layoutParams);
+ console.log(" - margin: " + layoutParams.topMargin + " " + layoutParams.rightMargin + " " + layoutParams.bottomMargin + " " + layoutParams.leftMargin);
+ }
+}
+
+export function order({object}) {
+ if (!lastSelection) {
+ return;
+ }
+ let value = object.text;
+ console.log("Set order " + value + " " + lastSelection);
+ flexbox.FlexboxLayout.setOrder(lastSelection, object.text);
+}
+
+export function flexGrow({object}) {
+ if (!lastSelection) {
+ return;
+ }
+ let value = object.text;
+ console.log("Set flexGrow " + value + " " + lastSelection);
+ flexbox.FlexboxLayout.setFlexGrow(lastSelection, object.text);
+}
+
+export function flexShrink({object}) {
+ if (!lastSelection) {
+ return;
+ }
+ let value = object.text;
+ console.log("Set flexShrink " + value + " " + lastSelection);
+ flexbox.FlexboxLayout.setFlexShrink(lastSelection, object.text);
+}
+
+// TODO: Align self
\ No newline at end of file
diff --git a/apps/app/ui-tests-app/flexbox/flexbox.xml b/apps/app/ui-tests-app/flexbox/flexbox.xml
new file mode 100644
index 000000000..407a04343
--- /dev/null
+++ b/apps/app/ui-tests-app/flexbox/flexbox.xml
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/apps/app/ui-tests-app/mainPage.ts b/apps/app/ui-tests-app/mainPage.ts
index 844ce05bf..544db3f7d 100644
--- a/apps/app/ui-tests-app/mainPage.ts
+++ b/apps/app/ui-tests-app/mainPage.ts
@@ -35,6 +35,7 @@ export function pageLoaded(args: EventData) {
examples.set("animeBG", "animations/background");
examples.set("transitions", "transitions/page0");
examples.set("segStyle", "segmented-bar/all");
+ examples.set("flexBox", "flexbox/flexbox");
//examples.set("listview_binding", "pages/listview_binding");
//examples.set("textfield", "text-field/text-field");
diff --git a/tns-core-modules/tns-core-modules.base.d.ts b/tns-core-modules/tns-core-modules.base.d.ts
index c0b7917cf..3f22bd059 100644
--- a/tns-core-modules/tns-core-modules.base.d.ts
+++ b/tns-core-modules/tns-core-modules.base.d.ts
@@ -59,6 +59,7 @@
///
///
///
+///
///
///
///
diff --git a/tns-core-modules/ui/layouts/flexbox-layout/flexbox-layout-common.ts b/tns-core-modules/ui/layouts/flexbox-layout/flexbox-layout-common.ts
new file mode 100644
index 000000000..1d82b43db
--- /dev/null
+++ b/tns-core-modules/ui/layouts/flexbox-layout/flexbox-layout-common.ts
@@ -0,0 +1,263 @@
+import {LayoutBase} from "ui/layouts/layout-base";
+import {View} from "ui/core/view";
+import {PropertyMetadata} from "ui/core/proxy";
+import {Property, PropertyMetadataSettings, PropertyChangeData} from "ui/core/dependency-observable";
+import {registerSpecialProperty} from "ui/builder/special-properties";
+import * as platform from "platform";
+
+export type Basis = "auto" | number;
+
+// on Android we explicitly set propertySettings to None because android will invalidate its layout (skip unnecessary native call).
+var AffectsLayout = platform.device.os === platform.platformNames.android ? PropertyMetadataSettings.None : PropertyMetadataSettings.AffectsLayout;
+
+export type FlexDirection = "row" | "row-reverse" | "column" | "column-reverse";
+export namespace FlexDirection {
+ export const ROW: "row" = "row";
+ export const ROW_REVERSE: "row-reverse" = "row-reverse";
+ export const COLUMN: "column" = "column";
+ export const COLUMN_REVERSE: "column-reverse" = "column-reverse";
+}
+
+let validFlexDirection = {
+ "row": true,
+ "row-reverse": true,
+ "column": true,
+ "column-reverse": true
+};
+
+function validateFlexDirection(value: any): boolean {
+ return value in validFlexDirection;
+}
+
+export type FlexWrap = "nowrap" | "wrap" | "wrap-reverse";
+export namespace FlexWrap {
+ export const NOWRAP: "nowrap" = "nowrap";
+ export const WRAP: "wrap" = "wrap";
+ export const WRAP_REVERSE: "wrap-reverse" = "wrap-reverse";
+}
+
+let validFlexWrap = {
+ "nowrap": true,
+ "wrap": true,
+ "wrap-reverse": true
+};
+
+function validateFlexWrap(value: any): boolean {
+ return value in validFlexWrap;
+}
+
+export type JustifyContent = "flex-start" | "flex-end" | "center" | "space-between" | "space-around";
+export namespace JustifyContent {
+ export const FLEX_START: "flex-start" = "flex-start";
+ export const FLEX_END: "flex-end" = "flex-end";
+ export const CENTER: "center" = "center";
+ export const SPACE_BETWEEN: "space-between" = "space-between";
+ export const SPACE_AROUND: "space-around" = "space-around";
+}
+
+let validJustifyContent = {
+ "flex-start": true,
+ "flex-end": true,
+ "center": true,
+ "space-between": true,
+ "space-around": true
+}
+
+function validateJustifyContent(value: any): boolean {
+ return value in validJustifyContent;
+}
+
+export type AlignItems = "flex-start" | "flex-end" | "center" | "baseline" | "stretch";
+export namespace AlignItems {
+ export const FLEX_START: "flex-start" = "flex-start";
+ export const FLEX_END: "flex-end" = "flex-end";
+ export const CENTER: "center" = "center";
+ export const BASELINE: "baseline" = "baseline";
+ export const STRETCH: "stretch" = "stretch";
+}
+
+let validAlignItems = {
+ "flex-start": true,
+ "flex-end": true,
+ "center": true,
+ "baseline": true,
+ "stretch": true
+};
+
+function validateAlignItems(value: any): boolean {
+ return value in validAlignItems;
+}
+
+export type AlignContent = "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "stretch";
+export namespace AlignContent {
+ export const FLEX_START: "flex-start" = "flex-start";
+ export const FLEX_END: "flex-end" = "flex-end";
+ export const CENTER: "center" = "center";
+ export const SPACE_BETWEEN: "space-between" = "space-between";
+ export const SPACE_AROUND: "space-around" = "space-around";
+ export const STRETCH: "stretch" = "stretch";
+}
+
+let validAlignContent = {
+ "flex-start": true,
+ "flex-end": true,
+ "center": true,
+ "space-between": true,
+ "space-around": true,
+ "stretch": true
+};
+
+function validateAlignContent(value: any): boolean {
+ return value in validAlignContent;
+}
+
+export type AlignSelf = "auto" | AlignItems;
+export namespace AlignSelf {
+ export const AUTO: "auto" = "auto";
+ export const FLEX_START: "flex-start" = "flex-start";
+ export const FLEX_END: "flex-end" = "flex-end";
+ export const CENTER: "center" = "center";
+ export const BASELINE: "baseline" = "baseline";
+ export const STRETCH: "stretch" = "stretch";
+}
+
+function validateArgs(element: View): View {
+ if (!element) {
+ throw new Error("element cannot be null or undefinied.");
+ }
+ return element;
+}
+
+/**
+ * A common base class for all cross platform flexbox layout implementations.
+ */
+export abstract class FlexboxLayoutBase extends LayoutBase {
+
+ public static flexDirectionProperty = new Property("flexDirection", "FlexboxLayout", new PropertyMetadata("row", AffectsLayout, undefined, validateFlexDirection, (args: any) => args.object.setNativeFlexDirection(args.newValue)));
+ public static flexWrapProperty = new Property("flexWrap", "FlexboxLayout", new PropertyMetadata("nowrap", AffectsLayout, undefined, validateFlexWrap, (args: any) => args.object.setNativeFlexWrap(args.newValue)));
+ public static justifyContentProperty = new Property("justifyContent", "FlexboxLayout", new PropertyMetadata("flex-start", AffectsLayout, undefined, validateJustifyContent, (args: any) => args.object.setNativeJustifyContent(args.newValue)));
+ public static alignItemsProperty = new Property("alignItems", "FlexboxLayout", new PropertyMetadata("stretch", AffectsLayout, undefined, validateAlignItems, (args: any) => args.object.setNativeAlignItems(args.newValue)));
+ public static alignContentProperty = new Property("alignContent", "FlexboxLayout", new PropertyMetadata("stretch", AffectsLayout, undefined, validateAlignContent, (args: any) => args.object.setNativeAlignContent(args.newValue)));
+
+ // TODO: Validation:
+ public static orderProperty = new Property("order", "FlexboxLayout", new PropertyMetadata(1, PropertyMetadataSettings.None, FlexboxLayoutBase.childHandler((flexbox, element, oldValue, newValue) => flexbox.onOrderPropertyChanged(element, oldValue, newValue))));
+ public static flexGrowProperty = new Property("flexGrow", "FlexboxLayout", new PropertyMetadata(0, PropertyMetadataSettings.None, FlexboxLayoutBase.childHandler((flexbox, element, oldValue, newValue) => flexbox.onFlexGrowPropertyChanged(element, oldValue, newValue))));
+ public static flexShrinkProperty = new Property("flexShrink", "FlexboxLayout", new PropertyMetadata(1, PropertyMetadataSettings.None, FlexboxLayoutBase.childHandler((flexbox, element, oldValue, newValue) => flexbox.onFlexShrinkPropertyChanged(element, oldValue, newValue))));
+ public static alignSelfProperty = new Property("alignSelf", "FlexboxLayout", new PropertyMetadata(-1, PropertyMetadataSettings.None, FlexboxLayoutBase.childHandler((flexbox, element, oldValue, newValue) => flexbox.onAlignSelfPropertyChanged(element, oldValue, newValue))));
+
+ constructor() {
+ super();
+ }
+
+ get flexDirection(): FlexDirection {
+ return this._getValue(FlexboxLayoutBase.flexDirectionProperty);
+ }
+ set flexDirection(value: FlexDirection) {
+ this._setValue(FlexboxLayoutBase.flexDirectionProperty, value);
+ }
+
+ get flexWrap(): FlexWrap {
+ return this._getValue(FlexboxLayoutBase.flexWrapProperty);
+ }
+ set flexWrap(value: FlexWrap) {
+ this._setValue(FlexboxLayoutBase.flexWrapProperty, value);
+ }
+
+ get justifyContent(): JustifyContent {
+ return this._getValue(FlexboxLayoutBase.justifyContentProperty);
+ }
+ set justifyContent(value: JustifyContent) {
+ this._setValue(FlexboxLayoutBase.justifyContentProperty, value);
+ }
+
+ get alignItems(): AlignItems {
+ return this._getValue(FlexboxLayoutBase.alignItemsProperty);
+ }
+ set alignItems(value: AlignItems) {
+ this._setValue(FlexboxLayoutBase.alignItemsProperty, value);
+ }
+
+ get alignContent(): AlignItems {
+ return this._getValue(FlexboxLayoutBase.alignContentProperty);
+ }
+ set alignContent(value: AlignItems) {
+ this._setValue(FlexboxLayoutBase.alignContentProperty, value);
+ }
+
+ public static setOrder(view: View, order: number) {
+ validateArgs(view)._setValue(FlexboxLayoutBase.orderProperty, order);
+ }
+ public static getOrder(view: View): number {
+ return validateArgs(view)._getValue(FlexboxLayoutBase.orderProperty);
+ }
+
+ public static setFlexGrow(view: View, grow: number) {
+ validateArgs(view)._setValue(FlexboxLayoutBase.flexGrowProperty, grow);
+ }
+ public static getFlexGrow(view: View) {
+ return validateArgs(view)._getValue(FlexboxLayoutBase.flexGrowProperty);
+ }
+
+ public static setFlexShrink(view: View, shrink: number) {
+ validateArgs(view)._setValue(FlexboxLayoutBase.flexShrinkProperty, shrink);
+ }
+ public static getFlexShrink(view: View): number {
+ return validateArgs(view)._getValue(FlexboxLayoutBase.flexShrinkProperty);
+ }
+
+ public static setAlignSelf(view: View, align: AlignSelf) {
+ validateArgs(view)._setValue(FlexboxLayoutBase.alignSelfProperty, align);
+ }
+ public static getAlignSelf(view: View): AlignSelf {
+ return validateArgs(view)._getValue(FlexboxLayoutBase.alignSelfProperty);
+ }
+
+ protected onOrderPropertyChanged(element: View, oldValue: number, newValue: number): void {
+ console.log("order changed: " + newValue + " " + element);
+ }
+
+ protected abstract setNativeFlexDirection(flexDirection: FlexDirection);
+ protected abstract setNativeFlexWrap(flexWrap: FlexWrap);
+ protected abstract setNativeJustifyContent(justifyContent: JustifyContent);
+ protected abstract setNativeAlignItems(alignItems: AlignItems);
+ protected abstract setNativeAlignContent(alignContent: AlignContent);
+
+ protected onFlexGrowPropertyChanged(element: View, oldValue: number, newValue: number): void {
+ console.log("flex-grow changed: " + newValue + " " + element);
+ }
+
+ protected onFlexShrinkPropertyChanged(element: View, oldValue: number, newValue: number): void {
+ console.log("flex-shrink changed: " + newValue + " " + element);
+ }
+
+ protected onAlignSelfPropertyChanged(element: View, oldValue: AlignSelf, newValue: AlignSelf): void {
+ console.log("align-self changed: " + newValue + " " + element);
+ }
+
+ private static childHandler(handler: (flexbox: FlexboxLayoutBase, element: View, oldValue: V, newValue: V) => void) {
+ return (data: PropertyChangeData) => {
+ let element = data.object as View;
+ if (!(element instanceof View)) {
+ throw new Error("Element is not View or its descendant.");
+ }
+ let flexbox = element.parent;
+ if (flexbox instanceof FlexboxLayoutBase) {
+ handler(flexbox, element, data.oldValue, data.newValue);
+ }
+ }
+ }
+}
+
+registerSpecialProperty("order", (instance, propertyValue) => {
+ FlexboxLayoutBase.setOrder(instance, !isNaN(+propertyValue) && +propertyValue);
+});
+registerSpecialProperty("flexGrow", (instance, propertyValue) => {
+ FlexboxLayoutBase.setFlexGrow(instance, !isNaN(+propertyValue) && +propertyValue);
+});
+registerSpecialProperty("flexShrink", (instance, propertyValue) => {
+ FlexboxLayoutBase.setFlexShrink(instance, !isNaN(+propertyValue) && +propertyValue);
+});
+registerSpecialProperty("alignSelf", (instance, propertyValue) => {
+ FlexboxLayoutBase.setAlignSelf(instance, propertyValue);
+});
+// No flex-basis in our implementation.
\ No newline at end of file
diff --git a/tns-core-modules/ui/layouts/flexbox-layout/flexbox-layout.android.ts b/tns-core-modules/ui/layouts/flexbox-layout/flexbox-layout.android.ts
new file mode 100644
index 000000000..bdf0572dd
--- /dev/null
+++ b/tns-core-modules/ui/layouts/flexbox-layout/flexbox-layout.android.ts
@@ -0,0 +1,124 @@
+import {View} from "ui/core/view";
+import {
+ FlexDirection,
+ FlexWrap,
+ JustifyContent,
+ AlignItems,
+ AlignContent,
+ AlignSelf,
+ FlexboxLayoutBase
+} from "./flexbox-layout-common";
+
+export * from "./flexbox-layout-common";
+
+import FlexboxLayoutWidget = org.nativescript.widgets.FlexboxLayout;
+
+const flexDirectionMap = {
+ [FlexDirection.ROW]: FlexboxLayoutWidget.FLEX_DIRECTION_ROW,
+ [FlexDirection.ROW_REVERSE]: FlexboxLayoutWidget.FLEX_DIRECTION_ROW_REVERSE,
+ [FlexDirection.COLUMN]: FlexboxLayoutWidget.FLEX_DIRECTION_COLUMN,
+ [FlexDirection.COLUMN_REVERSE]: FlexboxLayoutWidget.FLEX_DIRECTION_COLUMN_REVERSE
+}
+
+const flexWrapMap = {
+ [FlexWrap.NOWRAP]: FlexboxLayoutWidget.FLEX_WRAP_NOWRAP,
+ [FlexWrap.WRAP]: FlexboxLayoutWidget.FLEX_WRAP_WRAP,
+ [FlexWrap.WRAP_REVERSE]: FlexboxLayoutWidget.FLEX_WRAP_WRAP_REVERSE
+}
+
+const justifyContentMap = {
+ [JustifyContent.CENTER]: FlexboxLayoutWidget.JUSTIFY_CONTENT_CENTER,
+ [JustifyContent.FLEX_END]: FlexboxLayoutWidget.JUSTIFY_CONTENT_FLEX_END,
+ [JustifyContent.FLEX_START]: FlexboxLayoutWidget.JUSTIFY_CONTENT_FLEX_START,
+ [JustifyContent.SPACE_AROUND]: FlexboxLayoutWidget.JUSTIFY_CONTENT_SPACE_AROUND,
+ [JustifyContent.SPACE_BETWEEN]: FlexboxLayoutWidget.JUSTIFY_CONTENT_SPACE_BETWEEN
+}
+
+const alignItemsMap = {
+ [AlignItems.BASELINE]: FlexboxLayoutWidget.ALIGN_ITEMS_BASELINE,
+ [AlignItems.CENTER]: FlexboxLayoutWidget.ALIGN_ITEMS_CENTER,
+ [AlignItems.FLEX_END]: FlexboxLayoutWidget.ALIGN_ITEMS_FLEX_END,
+ [AlignItems.FLEX_START]: FlexboxLayoutWidget.ALIGN_ITEMS_FLEX_START,
+ [AlignItems.STRETCH]: FlexboxLayoutWidget.ALIGN_ITEMS_STRETCH
+}
+
+const alignContentMap = {
+ [AlignContent.CENTER]: FlexboxLayoutWidget.ALIGN_CONTENT_CENTER,
+ [AlignContent.FLEX_END]: FlexboxLayoutWidget.ALIGN_CONTENT_FLEX_END,
+ [AlignContent.FLEX_START]: FlexboxLayoutWidget.ALIGN_CONTENT_FLEX_START,
+ [AlignContent.SPACE_AROUND]: FlexboxLayoutWidget.ALIGN_CONTENT_SPACE_AROUND,
+ [AlignContent.SPACE_BETWEEN]: FlexboxLayoutWidget.ALIGN_CONTENT_SPACE_BETWEEN,
+ [AlignContent.STRETCH]: FlexboxLayoutWidget.ALIGN_CONTENT_STRETCH
+}
+
+export class FlexboxLayout extends FlexboxLayoutBase {
+ private _layout: FlexboxLayoutWidget;
+
+ constructor() {
+ super();
+ console.log("New FlexBoxLayout!");
+ }
+
+ get android(): FlexboxLayoutWidget { return this._layout; }
+ get _nativeView(): FlexboxLayoutWidget { return this._layout; }
+
+ public _createUI() {
+ this._layout = new org.nativescript.widgets.FlexboxLayout(this._context);
+ }
+
+ protected setNativeFlexDirection(flexDirection: FlexDirection) {
+ let value = flexDirectionMap[flexDirection];
+ console.log("setNativeFlexDirection: " + flexDirection + " -> " + value);
+ this.android.setFlexDirection(value);
+ }
+
+ protected setNativeFlexWrap(flexWrap: FlexWrap) {
+ console.log("flexWrap: " + flexWrap);
+ this.android.setFlexWrap(flexWrapMap[flexWrap]);
+ }
+
+ protected setNativeJustifyContent(justifyContent: JustifyContent) {
+ console.log("setNativeJustifyContent: " + justifyContent);
+ this.android.setJustifyContent(justifyContentMap[justifyContent]);
+ }
+
+ protected setNativeAlignItems(alignItems: AlignItems) {
+ console.log("setNativeAlignItems: " + alignItems);
+ this.android.setAlignItems(alignItemsMap[alignItems]);
+ }
+
+ protected setNativeAlignContent(alignContent: AlignContent) {
+ console.log("setNativeAlignContent: " + alignContent);
+ this.android.setAlignContent(alignContentMap[alignContent]);
+ }
+
+ protected onOrderPropertyChanged(view: View, oldValue: number, newValue: number): void {
+ console.log("order changed: " + newValue + " " + view);
+ this.setLayoutParamsProperty(view, lp => lp.order = newValue);
+ }
+
+ protected onFlexGrowPropertyChanged(view: View, oldValue: number, newValue: number): void {
+ console.log("flex-grow changed: " + newValue + " " + view);
+ this.setLayoutParamsProperty(view, lp => lp.flexGrow = newValue);
+ }
+
+ protected onFlexShrinkPropertyChanged(view: View, oldValue: number, newValue: number): void {
+ console.log("flex-shrink changed: " + newValue + " " + view);
+ this.setLayoutParamsProperty(view, lp => lp.flexShrink = newValue);
+ }
+
+ protected onAlignSelfPropertyChanged(view: View, oldValue: AlignSelf, newValue: AlignSelf): void {
+ console.log("align-self changed: " + newValue + " " + view);
+ // TODO: Map the align self enum:
+ // this.setLayoutParamsProperty(view, lp => lp.alignSelf = newValue);
+ }
+
+ private setLayoutParamsProperty(view: View, setter: (lp: org.nativescript.widgets.FlexboxLayout.LayoutParams) => void) {
+ let nativeView: android.view.View = view._nativeView;
+ var lp = nativeView.getLayoutParams() || new org.nativescript.widgets.FlexboxLayout.LayoutParams();
+ if (lp instanceof org.nativescript.widgets.FlexboxLayout.LayoutParams) {
+ setter(lp);
+ nativeView.setLayoutParams(lp);
+ }
+ }
+}
diff --git a/tns-core-modules/ui/layouts/flexbox-layout/flexbox-layout.d.ts b/tns-core-modules/ui/layouts/flexbox-layout/flexbox-layout.d.ts
new file mode 100644
index 000000000..7dea7b4f8
--- /dev/null
+++ b/tns-core-modules/ui/layouts/flexbox-layout/flexbox-layout.d.ts
@@ -0,0 +1,71 @@
+declare module "ui/layouts/flexbox-layout" {
+
+ import {View} from "ui/core/view";
+
+ export type FlexDirection = "row" | "row-reverse" | "column" | "column-reverse";
+ export namespace FlexDirection {
+ export const ROW: "row";
+ export const ROW_REVERSE: "row-reverse";
+ export const COLUMN: "column";
+ export const COLUMN_REVERSE: "column-reverse";
+ }
+
+ export type FlexWrap = "nowrap" | "wrap" | "wrap-reverse";
+ export namespace FlexWrap {
+ export const NOWRAP: "nowrap";
+ export const WRAP: "wrap";
+ export const WRAP_REVERSE: "wrap-reverse";
+ }
+
+ export type JustifyContent = "flex-start" | "flex-end" | "center" | "space-between" | "space-around";
+ export namespace JustifyContent {
+ export const FLEX_START: "flex-start";
+ export const FLEX_END: "flex-end";
+ export const CENTER: "center";
+ export const SPACE_BETWEEN: "space-between";
+ export const SPACE_AROUND: "space-around";
+ }
+
+ export type AlignItems = "flex-start" | "flex-end" | "center" | "baseline" | "stretch";
+ export namespace AlignItems {
+ export const FLEX_START: "flex-start";
+ export const FLEX_END: "flex-end";
+ export const CENTER: "center";
+ export const BASELINE: "baseline";
+ export const STRETCH: "stretch";
+ }
+
+ export type AlignContent = "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "stretch";
+ export namespace AlignContent {
+ export const FLEX_START: "flex-start";
+ export const FLEX_END: "flex-end";
+ export const CENTER: "center";
+ export const SPACE_BETWEEN: "space-between";
+ export const SPACE_AROUND: "space-around";
+ export const STRETCH: "stretch";
+ }
+
+ export type AlignSelf = "auto" | AlignItems;
+ export namespace AlignSelf {
+ export const AUTO: "auto";
+ export const FLEX_START: "flex-start";
+ export const FLEX_END: "flex-end";
+ export const CENTER: "center";
+ export const BASELINE: "baseline";
+ export const STRETCH: "stretch";
+ }
+
+ export class FlexboxLayout {
+ public static setOrder(view: View, order: number);
+ public static getOrder(view: View): number;
+
+ public static setFlexGrow(view: View, grow: number);
+ public static getFlexGrow(view: View);
+
+ public static setFlexShrink(view: View, shrink: number);
+ public static getFlexShrink(view: View): number;
+
+ public static setAlignSelf(view: View, align: AlignSelf);
+ public static getAlignSelf(view: View): AlignSelf;
+ }
+}
\ No newline at end of file
diff --git a/tns-core-modules/ui/layouts/flexbox-layout/package.json b/tns-core-modules/ui/layouts/flexbox-layout/package.json
new file mode 100644
index 000000000..f03245948
--- /dev/null
+++ b/tns-core-modules/ui/layouts/flexbox-layout/package.json
@@ -0,0 +1,2 @@
+{ "name" : "flexbox-layout",
+ "main" : "flexbox-layout" }
diff --git a/tns-platform-declarations/android/org.nativescript.widgets.d.ts b/tns-platform-declarations/android/org.nativescript.widgets.d.ts
index a69d53943..4fe693f0b 100644
--- a/tns-platform-declarations/android/org.nativescript.widgets.d.ts
+++ b/tns-platform-declarations/android/org.nativescript.widgets.d.ts
@@ -202,6 +202,68 @@
public getRows(): Array;
}
+ export class FlexboxLayout extends LayoutBase {
+ constructor(context: android.content.Context);
+
+ public getFlexDirection(): number;
+ public setFlexDirection(value: number);
+
+ public getFlexWrap(): number;
+ public setFlexWrap(value: number);
+
+ public getJustifyContent(): number;
+ public setJustifyContent(value: number);
+
+ public getAlignItems(): number;
+ public setAlignItems(value: number);
+
+ public getAlignContent(): number;
+ public setAlignContent(value: number);
+
+ public static FLEX_DIRECTION_ROW: number;
+ public static FLEX_DIRECTION_ROW_REVERSE: number;
+ public static FLEX_DIRECTION_COLUMN: number;
+ public static FLEX_DIRECTION_COLUMN_REVERSE: number;
+
+ public static FLEX_WRAP_NOWRAP: number;
+ public static FLEX_WRAP_WRAP: number;
+ public static FLEX_WRAP_WRAP_REVERSE: number;
+
+ public static JUSTIFY_CONTENT_FLEX_START: number;
+ public static JUSTIFY_CONTENT_FLEX_END: number;
+ public static JUSTIFY_CONTENT_CENTER: number;
+ public static JUSTIFY_CONTENT_SPACE_BETWEEN: number;
+ public static JUSTIFY_CONTENT_SPACE_AROUND: number;
+
+ public static ALIGN_ITEMS_FLEX_START: number;
+ public static ALIGN_ITEMS_FLEX_END: number;
+ public static ALIGN_ITEMS_CENTER: number;
+ public static ALIGN_ITEMS_BASELINE: number;
+ public static ALIGN_ITEMS_STRETCH: number;
+
+ public static ALIGN_CONTENT_FLEX_START: number;
+ public static ALIGN_CONTENT_FLEX_END: number;
+ public static ALIGN_CONTENT_CENTER: number;
+ public static ALIGN_CONTENT_SPACE_BETWEEN: number;
+ public static ALIGN_CONTENT_SPACE_AROUND: number;
+ public static ALIGN_CONTENT_STRETCH: number;
+ }
+ export namespace FlexboxLayout {
+ export class LayoutParams extends org.nativescript.widgets.CommonLayoutParams {
+ public static ALIGN_SELF_AUTO: number;
+ public static ALIGN_SELF_FLEX_START: number;
+ public static ALIGN_SELF_FLEX_END: number;
+ public static ALIGN_SELF_CENTER: number;
+ public static ALIGN_SELF_BASELINE: number;
+ public static ALIGN_SELF_STRETCH: number;
+
+ public order: number;
+ public flexGrow: number;
+ public flexShrink: number;
+ public alignSelf: number;
+ }
+ }
+
export class ContentLayout extends LayoutBase {
constructor(context: android.content.Context);
}