├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── baseplate.iml
├── example
└── basic_example_page.dart
├── lib
└── baseplate.dart
├── pubspec.lock
├── pubspec.yaml
└── test
└── baseplate_test.dart
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .dart_tool/
3 |
4 | .packages
5 | .pub/
6 |
7 | build/
8 | ios/.generated/
9 | ios/Flutter/Generated.xcconfig
10 | ios/Runner/GeneratedPluginRegistrant.*
11 |
12 | \.idea/
13 |
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 5391447fae6209bb21a89e6a5a6583cac1af9b4b
8 | channel: stable
9 |
10 | project_type: package
11 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [0.1.4] - 29/05/2019
2 |
3 | * Removed deprecated Baseplate class. Please now use bpRow and bpCol instead.
4 | * Support for max screen size added
5 |
6 | ## [0.1.3] - 13/05/2019
7 |
8 | * Added Support for `BoxConstraints` for when the widget will be less than the screen width on responsive layouts
9 |
10 | ## [0.1.2] - 06/02/2019
11 |
12 | * Added deprecation notice to Baseplate.row and Baseplate.col methods. Calling via bpRow and bpCol is preferred as these widgets _do_ appear in the inspector.
13 | * Updated example.
14 |
15 | ## [0.1.1] - 06/02/2019
16 |
17 | * Fixed logical error causing padding to display incorrectly when wrapping onto two rows.
18 |
19 | ## [0.1.0] - 06/02/2019
20 |
21 | * Switched to FractionallySizedBoxes to enable nesting of rows. Could break layouts on some devices hence the version increase.
22 |
23 | ## [0.0.3] - 06/02/2019
24 |
25 | * Removed unnecessary named parameters on the row constructor.
26 | * License added.
27 |
28 | ## [0.0.1] - 06/02/2019.
29 |
30 | * Initial Release. See readme.md
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) [year] [fullname]
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # baseplate
2 |
3 | A responsive frontend material framework designed to emulate the behaviour of Bootstrap.
4 |
5 | ## Getting Started
6 |
7 | [Full documentation on the Wiki](https://github.com/HJBDev/flutter-baseplate/wiki)
8 |
9 | Import the Baseplate class. You can then use the widgets to build responsive layouts easily.
10 |
11 | I've included lots of breakpoints to give as much freedom as possible. You don't have to use all. Baseplate operates on a "up to" principle. If the screen width is less than or equal to your breakpoint (and there isn't one smaller) that's the one that will be used.
12 |
13 | It's a 12 column layout, similar to Bootstrap on the web.
14 |
15 | 
16 |
17 | 
18 |
--------------------------------------------------------------------------------
/baseplate.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/example/basic_example_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:baseplate/baseplate.dart';
3 |
4 | class BasicExamplePage extends StatelessWidget {
5 | BasicExamplePage();
6 |
7 | @override
8 | Widget build(BuildContext context) {
9 | return LayoutBuilder(
10 | builder: (_, constraints) => Scaffold(
11 | appBar: AppBar(
12 | title: Text('flutter-baseplate Example'),
13 | ),
14 | body: Container(
15 | child: bpRow(
16 | runSpacing: 8,
17 | padding: 8,
18 | gutter: 8,
19 | constraints: constraints,
20 | children: [
21 | bpCol(
22 | w1200: 6,
23 | constraints: constraints,
24 | child: Container(
25 | color: Colors.red,
26 | height: 100,
27 | ),
28 | ),
29 | bpCol(
30 | w1200: 6,
31 | constraints: constraints,
32 | child: bpRow(
33 | children: [
34 | bpCol(
35 | w1200: 6,
36 | constraints: constraints,
37 | child: Container(
38 | color: Colors.pink,
39 | height: 100,
40 | ),
41 | ),
42 | bpCol(
43 | w1200: 6,
44 | constraints: constraints,
45 | child: Container(
46 | color: Colors.blue,
47 | height: 100,
48 | ),
49 | )
50 | ],
51 | )),
52 | bpCol(
53 | w1200: 6,
54 | constraints: constraints,
55 | child: Container(
56 | color: Colors.yellow,
57 | height: 100,
58 | ))
59 | ],
60 | ))));
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/lib/baseplate.dart:
--------------------------------------------------------------------------------
1 | library baseplate;
2 |
3 | import 'package:flutter/material.dart';
4 |
5 | /// Senses Baseplate
6 | /// ----------------------------------------------------------
7 | /// A responsive frontend framework for creating rich flutter
8 | /// user interfaces with a more web-oriented syntax. Influenced
9 | /// by the likes of Bootstrap and Materialize
10 |
11 | class bpCol extends StatelessWidget {
12 | int w360;
13 | int w540;
14 | int w720;
15 | int w1024;
16 | int w1200;
17 | int w1500;
18 | int w2000;
19 | int w2500;
20 | Widget child;
21 | int colCount;
22 | double gutter = 0.0;
23 | int colWidth = 0;
24 | double leftPadding = 0;
25 | double rightPadding = 0;
26 | final BoxConstraints constraints;
27 |
28 | bpCol({
29 | this.w360,
30 | this.w540,
31 | this.w720,
32 | this.w1024,
33 | this.w1200,
34 | this.w1500,
35 | this.w2000,
36 | this.w2500,
37 | this.child,
38 | this.colCount,
39 | this.gutter,
40 | this.constraints,
41 | });
42 |
43 | @override
44 | build(BuildContext context) {
45 | colWidth = Baseplate.calculateColWidth(
46 | context, w360, w540, w720, w1024, w1200, w1500, w2000, w2500,
47 | constraints: constraints);
48 |
49 | // calculate padding
50 | // int gutterCount = 2 + (colCount - 1);
51 | // double totalGutter = gutterCount * gutter;
52 | double width = Baseplate.calculateWidth(context, colWidth);
53 |
54 | return FractionallySizedBox(
55 | widthFactor: width,
56 | child: Container(
57 | child: Padding(
58 | padding: EdgeInsets.only(left: leftPadding, right: rightPadding),
59 | child: child),
60 | ));
61 | }
62 |
63 | setColCount(int count) {
64 | colCount = count;
65 | }
66 |
67 | getColWidth(context, BoxConstraints constraints) {
68 | return Baseplate.calculateColWidth(
69 | context, w360, w540, w720, w1024, w1200, w1500, w2000, w2500,
70 | constraints: constraints);
71 | }
72 |
73 | setRightPadding(double right) {
74 | rightPadding = right;
75 | }
76 |
77 | setLeftPadding(double left) {
78 | leftPadding = left;
79 | }
80 |
81 | setGutter(double theGutter) {
82 | gutter = theGutter;
83 | }
84 | }
85 |
86 | class bpRow extends StatelessWidget {
87 | final double gutter;
88 | final double padding;
89 | final double runSpacing;
90 | final List children;
91 | final BoxConstraints constraints;
92 |
93 | bpRow({
94 | this.gutter = 0,
95 | this.runSpacing = 0,
96 | @required this.children,
97 | this.padding = 0,
98 | this.constraints,
99 | });
100 |
101 | @override
102 | build(BuildContext context) {
103 | int colCount = 0;
104 | // what row am I on?
105 | // (tempColCount / 12).floor()
106 | Map rowColCounts = new Map();
107 |
108 | int i = 0;
109 | children.forEach((col) {
110 | i++;
111 | // if the total count is a multiple of 12 (or 0) BEFORE the column width is added, it is at the start of the row
112 | // if there is only 1 child, the padding needs to be on both sides.
113 |
114 | if (children.length > 1) {
115 | if (colCount % 12 == 0 || colCount == 0) {
116 | col.setLeftPadding(padding);
117 | } else {
118 | col.setLeftPadding(gutter / 2);
119 | }
120 | }
121 |
122 | var initialColCount = colCount;
123 | colCount += col.getColWidth(context, constraints);
124 |
125 | // if the total count is a multiple of 12 AFTER the column width is added, it is at the END of the row.
126 | if (children.length > 1) {
127 | if (colCount % 12 == 0) {
128 | col.setRightPadding(padding);
129 | } else {
130 | col.setRightPadding(gutter / 2);
131 | }
132 | }
133 |
134 | if (children.length == 1) {
135 | col.setLeftPadding(padding);
136 | col.setRightPadding(padding);
137 | }
138 |
139 | if (children.length != 1 &&
140 | colCount % 12 != 0 &&
141 | initialColCount % 12 != 0 &&
142 | initialColCount != 0) {
143 | col.setLeftPadding(gutter / 2);
144 | col.setRightPadding(gutter / 2);
145 | }
146 |
147 | // the row it's on
148 | int whatRow = (colCount / 12).floor();
149 |
150 | // if it's a number with no remainder, then it's on the row below
151 | if (colCount % 12 == 0) {
152 | whatRow = whatRow - 1;
153 | }
154 |
155 | // build up the column counts per row
156 | if (rowColCounts[whatRow] == null) {
157 | rowColCounts[whatRow] = 1;
158 | } else {
159 | rowColCounts[whatRow]++;
160 | }
161 |
162 | // what do I need?
163 | // an array of the column counts per row
164 | // how am I getting it?
165 | // loop through all the children /
166 | // work out which row they are on /
167 | // count how many are on each row /
168 | });
169 |
170 | colCount = 0;
171 | for (var i = 0; i < children.length; i++) {
172 | var col = children[i];
173 | colCount += col.getColWidth(context, constraints);
174 |
175 | int whatRow = (colCount / 12).floor();
176 |
177 | if (colCount % 12 == 0) {
178 | whatRow = whatRow - 1;
179 | }
180 |
181 | col.setColCount(rowColCounts[whatRow]);
182 | col.setGutter(gutter);
183 | }
184 |
185 | return Container(
186 | child: FractionallySizedBox(
187 | widthFactor: 1,
188 | child: Wrap(
189 | // spacing: gutter,
190 | runSpacing: runSpacing,
191 | children: children,
192 | )));
193 | }
194 | }
195 |
196 | class Baseplate {
197 | static calculateColWidth(BuildContext context, int w360, int w540, int w720,
198 | int w1024, int w1200, int w1500, int w2000, int w2500,
199 | {BoxConstraints constraints}) {
200 | final _width = constraints?.maxWidth ?? MediaQuery.of(context).size.width;
201 | if (w360 != null && _width <= 360) {
202 | return w360;
203 | } else if (w540 != null && _width <= 540) {
204 | return w540;
205 | } else if (w720 != null && _width <= 720) {
206 | return w720;
207 | } else if (w1024 != null && _width <= 1024) {
208 | return w1024;
209 | } else if (w1200 != null && _width <= 1200) {
210 | return w1200;
211 | } else if (w1500 != null && _width <= 1500) {
212 | return w1500;
213 | } else if (w2000 != null && _width <= 2000) {
214 | return w2000;
215 | } else if (w2500 != null && _width > 2000) {
216 | return w2500;
217 | } else {
218 | return 12;
219 | }
220 | }
221 |
222 | static calculateWidth(BuildContext context, int colWidth,
223 | [BoxConstraints constraints, double padding = 0]) {
224 | final _width = constraints?.maxWidth ?? MediaQuery.of(context).size.width;
225 | var screenWidth = _width;
226 | var fraction = colWidth / 12;
227 | return fraction;
228 | // return (screenWidth - padding) * fraction;
229 | }
230 | }
231 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://www.dartlang.org/tools/pub/glossary#lockfile
3 | packages:
4 | async:
5 | dependency: transitive
6 | description:
7 | name: async
8 | url: "https://pub.dartlang.org"
9 | source: hosted
10 | version: "2.2.0"
11 | boolean_selector:
12 | dependency: transitive
13 | description:
14 | name: boolean_selector
15 | url: "https://pub.dartlang.org"
16 | source: hosted
17 | version: "1.0.4"
18 | charcode:
19 | dependency: transitive
20 | description:
21 | name: charcode
22 | url: "https://pub.dartlang.org"
23 | source: hosted
24 | version: "1.1.2"
25 | collection:
26 | dependency: transitive
27 | description:
28 | name: collection
29 | url: "https://pub.dartlang.org"
30 | source: hosted
31 | version: "1.14.11"
32 | flutter:
33 | dependency: "direct main"
34 | description: flutter
35 | source: sdk
36 | version: "0.0.0"
37 | flutter_test:
38 | dependency: "direct dev"
39 | description: flutter
40 | source: sdk
41 | version: "0.0.0"
42 | matcher:
43 | dependency: transitive
44 | description:
45 | name: matcher
46 | url: "https://pub.dartlang.org"
47 | source: hosted
48 | version: "0.12.5"
49 | meta:
50 | dependency: transitive
51 | description:
52 | name: meta
53 | url: "https://pub.dartlang.org"
54 | source: hosted
55 | version: "1.1.6"
56 | path:
57 | dependency: transitive
58 | description:
59 | name: path
60 | url: "https://pub.dartlang.org"
61 | source: hosted
62 | version: "1.6.2"
63 | pedantic:
64 | dependency: transitive
65 | description:
66 | name: pedantic
67 | url: "https://pub.dartlang.org"
68 | source: hosted
69 | version: "1.5.0"
70 | quiver:
71 | dependency: transitive
72 | description:
73 | name: quiver
74 | url: "https://pub.dartlang.org"
75 | source: hosted
76 | version: "2.0.3"
77 | sky_engine:
78 | dependency: transitive
79 | description: flutter
80 | source: sdk
81 | version: "0.0.99"
82 | source_span:
83 | dependency: transitive
84 | description:
85 | name: source_span
86 | url: "https://pub.dartlang.org"
87 | source: hosted
88 | version: "1.5.5"
89 | stack_trace:
90 | dependency: transitive
91 | description:
92 | name: stack_trace
93 | url: "https://pub.dartlang.org"
94 | source: hosted
95 | version: "1.9.3"
96 | stream_channel:
97 | dependency: transitive
98 | description:
99 | name: stream_channel
100 | url: "https://pub.dartlang.org"
101 | source: hosted
102 | version: "2.0.0"
103 | string_scanner:
104 | dependency: transitive
105 | description:
106 | name: string_scanner
107 | url: "https://pub.dartlang.org"
108 | source: hosted
109 | version: "1.0.4"
110 | term_glyph:
111 | dependency: transitive
112 | description:
113 | name: term_glyph
114 | url: "https://pub.dartlang.org"
115 | source: hosted
116 | version: "1.1.0"
117 | test_api:
118 | dependency: transitive
119 | description:
120 | name: test_api
121 | url: "https://pub.dartlang.org"
122 | source: hosted
123 | version: "0.2.5"
124 | typed_data:
125 | dependency: transitive
126 | description:
127 | name: typed_data
128 | url: "https://pub.dartlang.org"
129 | source: hosted
130 | version: "1.1.6"
131 | vector_math:
132 | dependency: transitive
133 | description:
134 | name: vector_math
135 | url: "https://pub.dartlang.org"
136 | source: hosted
137 | version: "2.0.8"
138 | sdks:
139 | dart: ">=2.2.0 <3.0.0"
140 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: baseplate
2 | description: A responsive frontend material framework designed to emulate the behaviour of Bootstrap on web.
3 | version: 0.1.4
4 | authors:
5 | - Harry
6 | - Rody Davis Jr
7 | homepage: https://github.com/HJBDev/flutter-baseplate
8 |
9 | environment:
10 | sdk: ">=2.0.0-dev.68.0 <3.0.0"
11 |
12 | dependencies:
13 | flutter:
14 | sdk: flutter
15 |
16 | dev_dependencies:
17 | flutter_test:
18 | sdk: flutter
19 |
20 | # For information on the generic Dart part of this file, see the
21 | # following page: https://www.dartlang.org/tools/pub/pubspec
22 |
23 | # The following section is specific to Flutter.
24 | flutter:
25 |
26 | # To add assets to your package, add an assets section, like this:
27 | # assets:
28 | # - images/a_dot_burr.jpeg
29 | # - images/a_dot_ham.jpeg
30 | #
31 | # For details regarding assets in packages, see
32 | # https://flutter.io/assets-and-images/#from-packages
33 | #
34 | # An image asset can refer to one or more resolution-specific "variants", see
35 | # https://flutter.io/assets-and-images/#resolution-aware.
36 |
37 | # To add custom fonts to your package, add a fonts section here,
38 | # in this "flutter" section. Each entry in this list should have a
39 | # "family" key with the font family name, and a "fonts" key with a
40 | # list giving the asset and other descriptors for the font. For
41 | # example:
42 | # fonts:
43 | # - family: Schyler
44 | # fonts:
45 | # - asset: fonts/Schyler-Regular.ttf
46 | # - asset: fonts/Schyler-Italic.ttf
47 | # style: italic
48 | # - family: Trajan Pro
49 | # fonts:
50 | # - asset: fonts/TrajanPro.ttf
51 | # - asset: fonts/TrajanPro_Bold.ttf
52 | # weight: 700
53 | #
54 | # For details regarding fonts in packages, see
55 | # https://flutter.io/custom-fonts/#from-packages
56 |
--------------------------------------------------------------------------------
/test/baseplate_test.dart:
--------------------------------------------------------------------------------
1 | void main() {
2 | }
3 |
--------------------------------------------------------------------------------