feat(core): RootLayout with api to fluidly handle dynamic layers (#8980)

This commit is contained in:
William Tjondrosuharto
2021-01-30 02:49:32 +07:00
committed by Nathan Walker
parent a6b1bde655
commit a90609a670
10 changed files with 821 additions and 41 deletions

View File

@@ -3,49 +3,84 @@
<ActionBar title="Dev Toolbox" icon="" class="action-bar">
</ActionBar>
</Page.actionBar>
<ScrollView>
<StackLayout class="p-t-20 p-x-20">
<!-- <Button text="Button with html boxShadow" tap="{{ onTap }}" height="50" class="btn btn-primary btn-active" boxShadow="5 5 10 navy"/>
<Button text="Button with css boxShadow (rgba)" tap="{{ onTap }}" height="50" marginTop="50" class="btn btn-primary btn-active"/>
<Button text="Button with boxShadow 3 props" tap="{{ onTap }}" height="50" marginTop="50" boxShadow="5 5 navy" class="btn btn-primary btn-active"/>
<Button text="Button with boxShadow 4 props" tap="{{ onTap }}" height="50" marginTop="50" boxShadow="5 5 10 navy" class="btn btn-primary btn-active"/>
<Button text="Button with boxShadow 5 props" tap="{{ onTap }}" height="50" marginTop="50" boxShadow="5 5 10 10 navy" class="btn btn-primary btn-active"/>
<StackLayout boxShadow="10 10 rgba(0,0,0,1)" marginTop="50">
<Button text="Button with css boxShadow" tap="{{ onTap }}" height="50" borderRadius="10"/>
</StackLayout> -->
<!-- TODO: if backgroundColor is not set, it won't call background.ios.ts hence not applying the boxShadow -->
<!-- <StackLayout boxShadow="5 5 10 10 red" height="100" backgroundColor="transparent" padding="10" margin="20">
<Label text="StackLayout with transparent background"></Label>
</StackLayout> -->
<GridLayout boxShadow="10 -10 10 10 rgba(0,0,0,0.5)" height="100" backgroundColor="lightblue" padding="10" margin="20" tap="{{ toggleAnimation }}">
<Label text="GridLayout"></Label>
<GridLayout rows="2*, *">
<!-- background color transparent here to hide children overflow -->
<AbsoluteLayout row="0" backgroundColor="transparent">
<!-- Root layout demo -->
<RootLayout height="100%" width="100%">
<GridLayout height="100%" backgroundColor="#232652">
<Label verticalAlignment="center" textAlignment="center" fontWeight="bold" color="#fff" text="ROOT LAYOUT CONTENT"></Label>
</GridLayout>
</RootLayout>
</AbsoluteLayout>
<StackLayout boxShadow="5 10 10 20 #000" height="100" backgroundColor="lightblue" padding="10" margin="20" tap="{{ toggleAnimation }}">
<Label text="StackLayout"></Label>
</StackLayout>
<!-- Root layout controls -->
<StackLayout row="1">
<ScrollView height="100%">
<StackLayout class="p-15">
<Label color="#b4b6b9" fontSize="25" fontWeight="bold" text="ORANGE"></Label>
<FlexboxLayout flexDirection="row" justifyContent="space-between">
<Button flexGrow="1" text="open" tap="{{ open }}" popupIndex="0" class="btn btn-primary btn-active"/>
<Button flexGrow="1" text="front" tap="{{ bringToFront }}" popupIndex="0" class="btn btn-primary btn-active"/>
<Button flexGrow="1" text="close" tap="{{ close }}" popupIndex="0" class="btn btn-primary btn-active"/>
</FlexboxLayout>
<AbsoluteLayout boxShadow="5 15 10 20 green" height="100" backgroundColor="lightblue" padding="10" margin="20" tap="{{ toggleAnimation }}">
<Label text="AbsoluteLayout"></Label>
</AbsoluteLayout>
<Label color="#b4b6b9" fontSize="25" fontWeight="bold" text="NAVY"></Label>
<FlexboxLayout flexDirection="row">
<Button flexGrow="1" text="open" tap="{{ open }}" popupIndex="1" class="btn btn-primary btn-active"/>
<Button flexGrow="1" text="front" tap="{{ bringToFront }}" popupIndex="1" class="btn btn-primary btn-active"/>
<Button flexGrow="1" text="close" tap="{{ close }}" popupIndex="1" class="btn btn-primary btn-active"/>
</FlexboxLayout>
<!-- note: the 3rd number in box shadow is currently being ignored, only the 1st, 2nd, and 4th, and color are being used-->
<FlexboxLayout boxShadow="0 0 10 25 red" height="100" backgroundColor="lightblue" padding="10" margin="20" tap="{{ toggleAnimation }}">
<Label text="FlexboxLayout"></Label>
</FlexboxLayout>
<Label color="#b4b6b9" fontSize="25" fontWeight="bold" text="GRAY"></Label>
<FlexboxLayout flexDirection="row">
<Button flexGrow="1" text="open" tap="{{ open }}" popupIndex="2" class="btn btn-primary btn-active"/>
<Button flexGrow="1" text="front" tap="{{ bringToFront }}" popupIndex="2" class="btn btn-primary btn-active"/>
<Button flexGrow="1" text="close" tap="{{ close }}" popupIndex="2" class="btn btn-primary btn-active"/>
</FlexboxLayout>
<!-- <Button text="Button with html boxShadow" tap="{{ onTap }}" height="50" class="btn btn-primary btn-active" boxShadow="5 5 10 navy"/>
<FlexboxLayout boxShadow="15 10 10 20 #000" height="100" backgroundColor="transparent" padding="10" margin="20" tap="{{ toggleAnimation }}">
<Label text="FlexboxLayout (transparent background)"></Label>
</FlexboxLayout>
<Button text="Button with css boxShadow (rgba)" tap="{{ onTap }}" height="50" marginTop="50" class="btn btn-primary btn-active"/>
<Button marginTop="30" boxShadow="0 0 10 8 #000" backgroundColor="transparent" text="button" padding="20"></Button>
</StackLayout>
</ScrollView>
<Button text="Button with boxShadow 3 props" tap="{{ onTap }}" height="50" marginTop="50" boxShadow="5 5 navy" class="btn btn-primary btn-active"/>
<Button text="Button with boxShadow 4 props" tap="{{ onTap }}" height="50" marginTop="50" boxShadow="5 5 10 navy" class="btn btn-primary btn-active"/>
<Button text="Button with boxShadow 5 props" tap="{{ onTap }}" height="50" marginTop="50" boxShadow="5 5 10 10 navy" class="btn btn-primary btn-active"/>
<StackLayout boxShadow="10 10 rgba(0,0,0,1)" marginTop="50">
<Button text="Button with css boxShadow" tap="{{ onTap }}" height="50" borderRadius="10"/>
</StackLayout> -->
<!-- TODO: if backgroundColor is not set, it won't call background.ios.ts hence not applying the boxShadow -->
<!-- <StackLayout boxShadow="5 5 10 10 red" height="100" backgroundColor="transparent" padding="10" margin="20">
<Label text="StackLayout with transparent background"></Label>
</StackLayout> -->
<GridLayout boxShadow="10 -10 10 10 rgba(0,0,0,0.5)" height="100" backgroundColor="lightblue" padding="10" margin="20" tap="{{ toggleAnimation }}">
<Label text="GridLayout"></Label>
</GridLayout>
<StackLayout boxShadow="5 10 10 20 #000" height="100" backgroundColor="lightblue" padding="10" margin="20" tap="{{ toggleAnimation }}">
<Label text="StackLayout"></Label>
</StackLayout>
<AbsoluteLayout boxShadow="5 15 10 20 green" height="100" backgroundColor="lightblue" padding="10" margin="20" tap="{{ toggleAnimation }}">
<Label text="AbsoluteLayout"></Label>
</AbsoluteLayout>
<!-- note: the 3rd number in box shadow is currently being ignored, only the 1st, 2nd, and 4th, and color are being used-->
<FlexboxLayout boxShadow="0 0 10 25 red" height="100" backgroundColor="lightblue" padding="10" margin="20" tap="{{ toggleAnimation }}">
<Label text="FlexboxLayout"></Label>
</FlexboxLayout>
<FlexboxLayout boxShadow="15 10 10 20 #000" height="100" backgroundColor="transparent" padding="10" margin="20" tap="{{ toggleAnimation }}">
<Label text="FlexboxLayout (transparent background)"></Label>
</FlexboxLayout>
<Button marginTop="30" boxShadow="0 0 10 8 #000" backgroundColor="transparent" text="button" padding="20"></Button>
</StackLayout>
</ScrollView>
</StackLayout>
</GridLayout>
</Page>

View File

@@ -1,4 +1,5 @@
import { Observable, Frame, StackLayout } from '@nativescript/core';
import { Observable, Frame, View, StackLayout, getRootLayout, EventData, RootLayout, RootLayoutOptions } from '@nativescript/core';
import { AnimationCurve } from '@nativescript/core/ui/enums';
export class HelloWorldModel extends Observable {
private _counter: number;
@@ -37,6 +38,123 @@ export class HelloWorldModel extends Observable {
this.updateMessage();
}
popupViews: { view: View; options: RootLayoutOptions; extra?: any }[] = [
{
view: this.getPopup('#EA5936', 110, -30),
options: {
shadeCover: {
color: '#FFF',
opacity: 0.7,
tapToClose: true,
},
animation: {
enterFrom: {
opacity: 0,
translateY: 500,
duration: 500,
},
exitTo: {
opacity: 0,
duration: 300,
},
},
},
extra: {
customExitAnimation: {
opacity: 0,
translate: { x: 0, y: -500 },
},
},
},
{
view: this.getPopup('#232652', 110, 0),
options: {
shadeCover: {
color: 'pink',
opacity: 0.7,
tapToClose: false,
animation: {
exitTo: {
scaleX: 0,
},
},
},
},
},
{
view: this.getPopup('#E1E4E8', 110, 30),
options: {
shadeCover: {
color: '#ffffdd',
opacity: 0.5,
tapToClose: true,
ignoreShadeRestore: true,
animation: {
enterFrom: {
translateX: -1000,
duration: 500,
},
exitTo: {
rotate: -180,
duration: 500,
},
},
},
animation: {
enterFrom: {
rotate: 180,
duration: 300,
},
exitTo: {
rotate: 180,
opacity: 0,
duration: 300,
curve: AnimationCurve.spring,
},
},
},
},
];
open(args: EventData): void {
getRootLayout()
.open(this.popupViews[(<any>args.object).popupIndex].view, this.popupViews[(<any>args.object).popupIndex].options)
.then(() => console.log('opened'))
.catch((ex) => console.error(ex));
}
bringToFront(args: EventData): void {
getRootLayout()
.bringToFront(this.popupViews[(<any>args.object).popupIndex].view, true)
.then(() => console.log('brought to front'))
.catch((ex) => console.error(ex));
}
close(args: EventData): void {
if (this.popupViews[(<any>args.object).popupIndex]?.extra?.customExitAnimation) {
getRootLayout()
.close(this.popupViews[(<any>args.object).popupIndex].view, this.popupViews[(<any>args.object).popupIndex].extra.customExitAnimation)
.then(() => console.log('closed with custom exit animation'))
.catch((ex) => console.error(ex));
} else {
getRootLayout()
.close(this.popupViews[(<any>args.object).popupIndex].view)
.then(() => console.log('closed'))
.catch((ex) => console.error(ex));
}
}
getPopup(color: string, size: number, offset: number): View {
const layout = new StackLayout();
layout.height = size;
layout.width = size;
layout.marginTop = offset;
layout.marginLeft = offset;
layout.backgroundColor = color;
layout.borderRadius = 10;
return layout;
}
viewList() {
Frame.topmost().navigate({
moduleName: 'list-page',