-
Notifications
You must be signed in to change notification settings - Fork 248
[103] First attempt at notched corner text fields and all other 103 features #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 56 commits
1fadce5
a772890
af4cab3
adef0e7
7ee8838
2a45e8f
ec6cefe
d11cb4d
766e330
81153d5
1da2372
a749a22
bad42d9
64ffef9
fe8e68b
bbf5536
dc4b5f5
2a2760b
a02c671
f1dc58a
99bbede
b4cf2c6
d09d2a0
cde618f
6002376
f4ec6d4
0325b00
534e59d
58bebc0
6067eda
c3d4d10
61490a0
cef3036
454e1de
45095f1
225183f
5f67986
1d4da81
ee57229
ea1b39f
b1eceda
a1f0473
8ad2aa1
f2ee410
e183611
d9e0b8c
18fdc36
c99f350
38d6c0d
71a46ca
e92ffe7
b69ca4b
786516d
b9ea25e
3840981
7d17497
ccddf26
7bf5092
1b4c4d5
f362843
922eda3
cae18fe
87f030e
9285a58
59c8de1
a15c3a3
44cee9f
6d8ccb1
5d1f717
faf5834
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter/services.dart'; | ||
|
||
import 'home.dart'; | ||
import 'login.dart'; | ||
import 'notched_corner_border.dart'; | ||
import 'supplemental/theming.dart'; | ||
|
||
class ShrineApp extends StatelessWidget { | ||
ThemeData _customTheme(BuildContext context) { | ||
final ThemeData theme = Theme.of(context); | ||
return theme.copyWith( | ||
accentColor: kShrineBrown900, | ||
primaryColor: kShrinePink100, | ||
buttonColor: kShrinePink100, | ||
scaffoldBackgroundColor: kShrineBackgroundWhite, | ||
cardColor: kShrineBackgroundWhite, | ||
textSelectionColor: kShrinePink100, | ||
errorColor: kShrineErrorRed, | ||
buttonTheme: const ButtonThemeData( | ||
textTheme: ButtonTextTheme.accent, | ||
), | ||
textTheme: _customTextTheme(theme.textTheme), | ||
primaryTextTheme: _customTextTheme(theme.primaryTextTheme), | ||
primaryIconTheme: _customIconTheme(theme.primaryIconTheme), | ||
inputDecorationTheme: | ||
new InputDecorationTheme(border: new NotchedCornerBorder()), | ||
); | ||
} | ||
|
||
IconThemeData _customIconTheme(IconThemeData original) { | ||
return original.copyWith(color: kShrineBrown900); | ||
} | ||
|
||
TextTheme _customTextTheme(TextTheme original) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a reasonable approach to take however I think we'd prefer to start with a const ThemeData value. Will follow up with proposal for how to do that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a reasonable way to handle creating such a TextTheme but I think we'd prefer to define the entire Theme with a ThemeData value. Will follow up about how to do that |
||
const String rubik = 'Rubik'; | ||
|
||
return original | ||
.copyWith( | ||
display4: original.display4.copyWith(fontFamily: rubik), | ||
display3: original.display3.copyWith(fontFamily: rubik), | ||
display2: original.display2.copyWith(fontFamily: rubik), | ||
display1: original.display1.copyWith(fontFamily: rubik), | ||
headline: original.headline.copyWith( | ||
fontFamily: rubik, | ||
fontWeight: FontWeight.w500, | ||
), | ||
title: original.title.copyWith(fontFamily: rubik, fontSize: 18.0), | ||
subhead: original.subhead.copyWith(fontFamily: rubik), | ||
caption: original.caption.copyWith( | ||
fontFamily: rubik, | ||
fontWeight: FontWeight.w400, | ||
fontSize: 14.0, | ||
), | ||
button: original.button.copyWith(fontFamily: rubik), | ||
) | ||
.apply( | ||
displayColor: kShrineBrown900, | ||
bodyColor: kShrineBrown900, | ||
); | ||
} | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark); | ||
|
||
return MaterialApp( | ||
title: 'Shrine', | ||
home: new HomePage(), | ||
initialRoute: '/login', | ||
onGenerateRoute: _getRoute, | ||
theme: _customTheme(context), | ||
); | ||
} | ||
|
||
Route<dynamic> _getRoute(RouteSettings settings) { | ||
if (settings.name == '/login') { | ||
return new MaterialPageRoute<void>( | ||
settings: settings, | ||
builder: (BuildContext context) => new LoginPage(), | ||
fullscreenDialog: true, | ||
); | ||
} | ||
|
||
return null; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import 'package:flutter/material.dart'; | ||
|
||
import 'supplemental/asymmetric_grid.dart'; | ||
|
||
class HomePage extends StatefulWidget { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There doesn't appear to be any reason to make this widget stateful. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
@override | ||
_HomePageState createState() => new _HomePageState(); | ||
} | ||
|
||
class _HomePageState extends State<HomePage> { | ||
@override | ||
Widget build(BuildContext context) { | ||
return new Scaffold( | ||
appBar: new AppBar( | ||
brightness: Brightness.light, | ||
leading: new IconButton( | ||
icon: const Icon(Icons.menu), | ||
onPressed: () { | ||
print('Menu button'); | ||
}, | ||
), | ||
title: const Text('SHRINE'), | ||
actions: <Widget>[ | ||
new IconButton( | ||
icon: const Icon(Icons.search), | ||
onPressed: () { | ||
print('Search button'); | ||
}, | ||
), | ||
new IconButton( | ||
icon: const Icon(Icons.tune), | ||
onPressed: () { | ||
print('Filter button'); | ||
}, | ||
), | ||
], | ||
), | ||
body: new ListView( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
scrollDirection: Axis.horizontal, | ||
padding: const EdgeInsets.fromLTRB(0.0, 34.0, 16.0, 44.0), | ||
children: buildGridCardsAsymmetric(context), | ||
), | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import 'package:flutter/material.dart'; | ||
|
||
import 'supplemental/theming.dart'; | ||
|
||
class LoginPage extends StatefulWidget { | ||
@override | ||
LoginPageState createState() { | ||
return new LoginPageState(); | ||
} | ||
} | ||
|
||
class LoginPageState extends State<LoginPage> { | ||
final _usernameController = new TextEditingController(); | ||
final _passwordController = new TextEditingController(); | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return new Scaffold( | ||
backgroundColor: kShrineSurfaceWhite, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Already defined by the Shrine theme. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
body: new SafeArea( | ||
child: new ListView( | ||
padding: const EdgeInsets.symmetric(horizontal: 24.0), | ||
children: <Widget>[ | ||
const SizedBox(height: 80.0), | ||
new Column( | ||
children: <Widget>[ | ||
new Image.asset('assets/diamond.png'), | ||
const SizedBox(height: 16.0), | ||
new Text( | ||
'SHRINE', | ||
style: Theme.of(context).textTheme.headline, | ||
), | ||
], | ||
), | ||
const SizedBox(height: 120.0), | ||
new TextField( | ||
controller: _usernameController, | ||
decoration: const InputDecoration( | ||
labelText: 'Username', | ||
), | ||
), | ||
const SizedBox(height: 12.0), | ||
new TextField( | ||
controller: _passwordController, | ||
decoration: const InputDecoration( | ||
labelText: 'Password', | ||
), | ||
obscureText: true, | ||
), | ||
new ButtonBar( | ||
children: <Widget>[ | ||
new FlatButton( | ||
child: const Text('CANCEL'), | ||
onPressed: () { | ||
_usernameController.clear(); | ||
_passwordController.clear(); | ||
}, | ||
), | ||
new RaisedButton( | ||
child: const Text('NEXT'), | ||
elevation: 8.0, | ||
onPressed: () { | ||
Navigator.pop(context); | ||
}, | ||
), | ||
], | ||
), | ||
], | ||
), | ||
), | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import 'package:flutter/material.dart'; | ||
|
||
import 'app.dart'; | ||
|
||
void main() => runApp(new ShrineApp()); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import 'product.dart'; | ||
|
||
List<Product> getAllProducts() { | ||
return const <Product>[ | ||
Product( | ||
category: Category.home, | ||
id: 0, | ||
isFeatured: true, | ||
name: 'Tab Can', | ||
price: 35, | ||
), | ||
Product( | ||
category: Category.accessories, | ||
id: 1, | ||
isFeatured: false, | ||
name: 'Pineapple Wall', | ||
price: 80, | ||
), | ||
Product( | ||
category: Category.clothing, | ||
id: 2, | ||
isFeatured: false, | ||
name: 'Tab & Fresca Cold', | ||
price: 100, | ||
), | ||
Product( | ||
category: Category.home, | ||
id: 3, | ||
isFeatured: false, | ||
name: 'Capris', | ||
price: 5, | ||
), | ||
Product( | ||
category: Category.home, | ||
id: 0, | ||
isFeatured: true, | ||
name: 'Tab Can', | ||
price: 35, | ||
), | ||
Product( | ||
category: Category.accessories, | ||
id: 1, | ||
isFeatured: false, | ||
name: 'Pineapple Wall', | ||
price: 80, | ||
), | ||
Product( | ||
category: Category.clothing, | ||
id: 2, | ||
isFeatured: false, | ||
name: 'Tab & Fresca Cold', | ||
price: 100, | ||
), | ||
Product( | ||
category: Category.home, | ||
id: 3, | ||
isFeatured: false, | ||
name: 'Capris', | ||
price: 5, | ||
), | ||
Product( | ||
category: Category.home, | ||
id: 0, | ||
isFeatured: true, | ||
name: 'Tab Can', | ||
price: 35, | ||
), | ||
Product( | ||
category: Category.accessories, | ||
id: 1, | ||
isFeatured: false, | ||
name: 'Pineapple Wall', | ||
price: 80, | ||
), | ||
Product( | ||
category: Category.clothing, | ||
id: 2, | ||
isFeatured: false, | ||
name: 'Tab & Fresca Cold', | ||
price: 100, | ||
), | ||
Product( | ||
category: Category.home, | ||
id: 3, | ||
isFeatured: false, | ||
name: 'Capris', | ||
price: 5, | ||
), | ||
]; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import 'package:flutter/foundation.dart'; | ||
|
||
enum Category { none, accessories, clothing, home } | ||
|
||
class Product { | ||
const Product({ | ||
@required this.category, | ||
@required this.id, | ||
@required this.isFeatured, | ||
@required this.name, | ||
@required this.price, | ||
}) : assert(category != null), | ||
assert(id != null), | ||
assert(isFeatured != null), | ||
assert(name != null), | ||
assert(price != null); | ||
|
||
final Category category; | ||
final int id; | ||
final bool isFeatured; | ||
final String name; | ||
final int price; | ||
|
||
@override | ||
String toString() => "$name (id=$id)"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Single quotes There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shrine's custom theme can be defined in terms of a ThemeData value; it shouldn't be necessary to compute anything vis
Theme.of()
. Here's how I'd suggest coding it.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.