Wrapper properties are an easy way to wrap any widget with another one, so instead of writting this:
<Opacity opacity=".5">
<Container>
<Text text="'Hello!'"/>
</Container>
</Opacity>
You write this:
<Container :opacity=".5">
<Text text="'Hello!'"/>
</Container>
Or even this:
<Container :opacity=".5" :text="'Hello1'" />
All wrapper properties start with :
to avoid ambiguity with the real properties which might have the same name so you can write the both of previous examples.
<Text :margin="4" text="'Hello!'" />
<Text :margin="1 2" text="'Hello!'" />
<Text :margin="1 2 3" text="'Hello!'" />
<Text :margin="1 2 3 4" text="'Hello!'" />
Result:
Padding(
padding: const EdgeInsets.all(4),
child: Text('Hello!')
)
Padding(
padding: const symmetric(vertical: 1, horizontal: 2),
child: Text('Hello!')
)
Padding(
padding: const EdgeInsets.fromLTRB(2, 1, 2, 3),
child: Text('Hello!')
)
Padding(
padding: const EdgeInsets.fromLTRB(4, 1, 2, 3),
child: Text('Hello!')
)
The value formatting follows Web standards (top right bottom left).
<Text :opacity="0.5" text="'Hello!'" />
Result:
Opacity(
opacity: 0.5,
child: Text('Hello!')
)
<Text text="'Hello world!'" :visible="false" />
Result:
Visibility(
visible: false,
child: Text('Hello world!')
)
This is actualy a child-wrapper that wrap the child widget:
<Card :padding="4">
<Text text="'Hello!'"/>
</Card>
Result:
Card(
child: Padding(
padding: const EdgeInsets.all(4),
child: Text(
'Hello!'
)
)
);
The target widget must have a child
property. and for this reason the Text
can't have a :padding
but can have a :margin
.
This also behaves as a child-wrapper but doesn't wrap the child, instead it adds a Text
child to the target widget:
<RaisedButton :text="'Hello!'" />
Result:
RaisedButton(
child: Text(
'Hello!'
)
);
Its like :text
but for icons:
<RaisedButton :icon="home" />
Result:
RaisedButton(
child: Icon(
Icons.home
)
);
Adding one or both of these properties will wrap the target widget with SizedBox:
<Card :width="100">
<Text text="'Width only'"/>
</Card>
<Card :height="200">
<Text text="'Height only'"/>
</Card>
<Card :width="100" :height="200">
<Text text="'Width and height'"/>
</Card>
Result:
SizedBox(
width: 100,
child: Card(
child: Text(
'Width only'
)
)
),
SizedBox(
height: 200,
child: Card(
child: Text(
'Height only'
)
)
),
SizedBox(
height: 200,
width: 100,
child: Card(
child: Text(
'Width and height'
)
)
)
Wraps the target widget with GestureDetector
and maps each event to its function:
<Column :onTap="ctrl.doSomthing"></Column>
Result:
GestureDetector(
onTap: ctrl.doSomthing,
child: Column(
children: [
]
)
)
Wraps the target widget with Theme
:
<Text text="'Hello'" :theme="ctrl.myTheme" />
Result:
Theme(
data: ctrl.myTheme,
child: Text(
'Hello'
)
)
Or you could create a custom pipe which provides the themes:
<Text text="'Hello'" :theme="'my_theme_name' | customTheme" />
Result:
Theme(
data: _pipeProvider.transform(context, 'customTheme', 'my_theme_name', []),
child: Text(
'Hello'
)
)
Wraps the target widget with Hero
:
<Image :use="asset" source="'assets/images/image_name.png'" :hero="'image-cover'" />
Result:
Hero(
tag: 'image-cover',
child: Image.asset(
'assets/images/image_name.png'
)
)
Wraps the target widget with AspectRatio
:
<Image :use="asset" source="'assets/images/image_name.png'" :aspectRatio="16.0/9.0" />
Result:
AspectRatio(
aspectRatio: 16.0/9.0,
child: Image.asset(
'assets/images/image_name.png'
)
)
Wraps the target widget with Center
:
<Text text="'Hello'" :center />
Result:
Center(
child: Text(
'Hello'
)
)
Wraps the target widget with Align
:
<Text text="'Hello'" :align="Alignment.center" />
Result:
Align(
alignment: Alignment.center,
child: Text(
'Hello'
)
)
Wraps the target widget with Expanded
:
<Text text="'Hello'" :flex="2" />
Result:
Expanded(
flex: 2,
child: Text(
'Hello'
)
)
Wraps any widget has an event handler (e.g.: onPressed, onChange), the target widget will be disabled according to the :disable
's value.
<RaisedButton onPressed="ctrl.login" :disable="statusStream | stream:true">
<Text text="'Login'" />
</RaisedButton>
Result:
StreamBuilder(
initialData: true,
stream: statusStream,
builder: (BuildContext context, statusStreamSnapshot) {
final statusStreamValue = statusStreamSnapshot.data;
return Disable(
event: ctrl.login,
value: statusStreamValue,
builder: (BuildContext context, event) {
return RaisedButton(
onPressed: event,
child: Text(
'Login'
)
);
}
);
}
)
:consumer
wraps the target widget with a Consumer
widget (which is part of provider
package), this can be used instead of injecting the provider at the top level of the current Widget's State to avoid rebuilding the whole widget when the provider changes.
<MyWidget :consumer="MyProvider myProvider" title="myProvider.title">
<Text text="myProvider.greatingText" />
</MyWidget>
Result:
Consumer<MyProvider>(
builder: (BuildContext context, MyProvider myProvider, Widget child) {
return MyWidget(
title: myProvider.title,
child: Text(
myProvider.greatingText
)
);
}
)