susy 3.0.0.alpha.1 → 3.0.0.alpha.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fa2aa38b4ee8f4a92e3d6cecb470ebcdde3dbb29
4
- data.tar.gz: 74d57ae39653cb41f6d13d667b9205f0163eef35
3
+ metadata.gz: 8abe53f196f31e63a27a0457d54af4b1586a60b0
4
+ data.tar.gz: 084c64a7897e0b887078063b6ddbe410d8f46616
5
5
  SHA512:
6
- metadata.gz: 2b2b113cad8db26b6f4b10a73893f15339dfcddb4a2f35bfb36774faa85f46a294ee0667d271d75c56fdff104d085b6f98e352c8a5b3e4a46e3ae7e841741a97
7
- data.tar.gz: eb5cb812bcc15d7fbf1eb51d3d0246f2ab583e5ed32a155f4fb32b301f216afdf288875b7981c60538dec5806e3fd06a26cd0106e76249853999ccfbd3c99709
6
+ metadata.gz: 1164998a065a00be67b0b8253b4d0fd60f7e974d80f22a12dbb5b29b3cd09d9c2295c5a2580a79b987f4ab6fb9cade596d9d78fda428ab91df81eaa9dca64d7a
7
+ data.tar.gz: 73c1eddf36ad9161bdac645fe76db17cfd8227fbe50b8baddf392df75444625b72fc7e9076c2f1f72f7a3f8974ccbbd204e1b35586027afc5b8a60cd7dea81bb
data/README.md CHANGED
@@ -10,136 +10,189 @@ full of rules and restrictions —
10
10
  we wanted a power tool
11
11
  for building our own damn systems.
12
12
 
13
- Do It Yourself.
14
- Your Markup,
15
- Your Layout
16
- *Our Math*
13
+ Version Three is trimmed down to it's most basic components —
14
+ functions that can be used to build any grid system.
15
+ This is truely a grids-on-demand approach,
16
+ where you build your own system,
17
+ and we handle the math.
18
+
19
+ We're planning to build various output-modules
20
+ with mixins to help you get started.
21
+ We'll probably start with a float-based module,
22
+ and a flexbox module.
23
+ If you have ideas for another plugin,
24
+ or want to help move floats or flexbox along,
25
+ pull requests are welcome!
17
26
 
18
27
 
19
28
  Getting Started
20
29
  ---------------
21
30
 
22
- Susy v3 is trimmed down to it's most basic components —
23
- functions that can be used to build any grid system.
31
+ You can install Susy as a rubygem,
32
+ npm module, bower package, or git repo.
24
33
 
25
- There are four global settings to understand,
26
- and two of them are identical:
34
+ ```
35
+ npm install susy@pre
36
+ ```
27
37
 
38
+ There are two imports to choose from.
39
+ The default `sass/_susy.scss` comes with
40
+ un-prefixed versions of the core API functions.
41
+ If you want Susy to be name-spaced,
42
+ import `sass/_prefix.scss` instead.
28
43
 
29
- ### Columns
44
+ ```scss
45
+ @import '../node_modules/susy/sass/susy';
46
+ ```
30
47
 
31
- The `columns` setting describes the columns in your grid.
32
- The most basic syntax uses a list of numbers
33
- to describe the relative size of each column.
34
48
 
35
- ```scss
36
- // five equal columns
37
- $symmetrical: (1 1 1 1 1);
49
+ Spanning Columns & Gutters
50
+ --------------------------
38
51
 
39
- // six fibonacci columns
40
- $asymmetrical: (1 1 2 3 5 8);
52
+ There are two core funtions:
53
+ `span()` (or `susy-span()`),
54
+ and `gutter()` (or `susy-gutter()`).
55
+
56
+ The **gutter** function returns
57
+ the width of a single gutter on your grid —
58
+ to be applied as you see fit:
59
+
60
+ ```scss
61
+ .example {
62
+ margin: susy-gutter();
63
+ }
41
64
  ```
42
65
 
43
- If you want static grids,
44
- you can add units to the numbers
45
- as long as all the units are comparable.
66
+ The **span** function
67
+ describes a span of one or more columns,
68
+ and any relevant gutters along the way:
46
69
 
47
70
  ```scss
48
- // five equal static columns
49
- $symmetrical: (120px 120px 120px 120px 120px);
71
+ .example {
72
+ // the width of three columns, and the two intervening gutters
73
+ width: susy-span(3);
74
+ }
75
+ ```
76
+
77
+ When nesting fluid grids,
78
+ you can use the old `of $n` syntax
79
+ to describe changes in context —
80
+ e.g. `susy-span(3 of 6)`.
81
+ When using asymmetrical grids,
82
+ you can use the old `at $n`, `first`, or `last` syntax
83
+ to describe the specific columns you want to span —
84
+ e.g. `susy-span(3 at 2 of (1 2 3 4 5 6))`
85
+ to span across `(2 3 4)`.
86
+
87
+ You can use these two functions
88
+ to build all sorts of grids:
50
89
 
51
- // six not-fibonacci static columns
52
- $asymmetrical: (1in 1cm 2pt 3mm 5in 8cm);
90
+ ```scss
91
+ .float {
92
+ float: left;
93
+ width: span(3);
94
+ margin-right: gutter();
95
+ }
96
+
97
+ .flexbox {
98
+ flex-basis: span(3);
99
+ padding: gutter() / 2;
100
+ }
101
+
102
+ // Make your own class system!
103
+ .span {
104
+ float: left;
105
+ margin-right: gutter();
106
+
107
+ &.last {
108
+ margin-right: 0;
109
+ }
110
+ }
111
+
112
+ @for $span from 1 through susy-get('columns') {
113
+ .span-#{$i} {
114
+ width: span($i);
115
+ }
116
+ }
53
117
  ```
54
118
 
55
- That can get repetative
56
- when you are working with symmetrical grids,
57
- so we've provided a symmetrical shorthand.
119
+
120
+ Defining Grids
121
+ --------------
122
+
123
+ A grid is defined by a series of `columns`
124
+ with optional `gutters` between them.
125
+
126
+ **Columns** are described by a list of numbers,
127
+ representing the relative width of each column.
128
+ By default, a grid is fluid —
129
+ but you can add units to create a static layout:
58
130
 
59
131
  ```scss
60
- // five equal fluid columns (shorthand)
61
- $fluid: 5;
132
+ // six equal fluid columns
133
+ $equal: (1 1 1 1 1 1);
134
+
135
+ // six equal 5em columns
136
+ $static: (5em 5em 5em 5em 5em 5em);
137
+
138
+ // six unequal fluid columns
139
+ $asymmetrical: (1 1 2 3 5 8);
62
140
 
63
- // five equal static columns (shorthand)
64
- $static: 5 x 120px;
141
+ // six unequal fluid columns
142
+ // you can mix units, as long as they are comparable...
143
+ $strange: (1in 1cm 2pt 3mm 5in 8cm);
65
144
  ```
66
145
 
67
- That static-symmetrical shorthand
68
- is technically a list.
69
- The first value is a unitless number,
70
- representing the number of columns in the grid.
71
- The second value is the letter "x"
72
- (not a star or times symbol).
73
- The third value is the static width of your columns.
146
+ Since `(1 1 1 1 1 1)` is so repetative,
147
+ we've provided a shorthand syntax
148
+ for describung equal columns:
74
149
 
150
+ ```scss
151
+ // six equal fluid columns (shorthand)
152
+ $fluid: 6;
75
153
 
76
- ### Gutters
154
+ // six 120px static columns (shorthand)
155
+ // that's a lowercase 'x' — not a star or any other symbol...
156
+ $static: 6 x 120px;
157
+ ```
77
158
 
78
- The `gutters` setting describes the space between
79
- (and sometimes around)
80
- your columns.
81
- It is always defined in units
82
- comparable to the rest of your grid.
159
+ **Gutters**
160
+ are defined relative to columns,
161
+ in comparable units.
162
+ Both settings go together
163
+ in a single map variable:
83
164
 
84
165
  ```scss
85
- // fluid 4-column grid, with gutters 1/4 the size of a column
86
- $columns: (1 1 1 1);
87
- $gutters: 0.25;
88
-
89
- // Static em-based grid, with 0.25em gutters
90
- $columns: (1em 1em 2em 3em 5em 8em)
91
- $gutters: 0.25em;
166
+ // fluid 4-column grid
167
+ // with gutters 1/4 the size of a column
168
+ $fluid: (
169
+ 'columns': 4;
170
+ 'gutters': 0.25;
171
+ );
172
+
173
+ // Static un-equal grid
174
+ // with comparable gutters
175
+ $static: (
176
+ 'columns': (1em 1em 2em 3em 5em 8em)
177
+ 'gutters': 0.25em;
178
+ );
92
179
  ```
93
180
 
94
- There is a special case
95
- allowing you to use static gutters in a fluid grid,
96
- but that's too advanced for a quick-start guide.
97
-
98
-
99
- ### Spread & Container-Spread
100
-
101
- The concept of `spread`
102
- helps us describe what gutters to include
103
- in a grid span or container.
104
- There are three options:
105
- `narrow`, `wide`, and `wider`.
106
-
107
- Imagine a four-column grid.
108
- How many gutters are in that grid?
109
-
110
- - The most common answer is `3`.
111
- Gutters only exist between the columns —
112
- `c1 (g1) c2 (g2) c3 (g3) c4`.
113
- We call that option `narrow`,
114
- and it is the default value for both
115
- spans and containers.
116
-
117
- - The other common answer is `5`,
118
- if we want to include gutters on the outside edges —
119
- `(g1) c1 (g2) c2 (g3) c3 (g4) c4 (g5)`.
120
- We call that option `wider`.
121
-
122
- - Less commonly,
123
- you might want only one edge gutter
124
- either before or after —
125
- `c1 (g1) c2 (g2) c3 (g3) c4 (g4)` —
126
- leaving your with `4` gutters.
127
- We call that `wide`.
128
-
129
- Spread and container-spread work in the same way,
130
- but one applies to a span,
131
- and the other applies to the parent context
132
- when calculating relative widths.
133
- If you are using static grids,
134
- the `container-spread` isn't used.
135
-
136
- In most cases,
137
- you can set the default spread for a project,
138
- and never look back.
139
- Sometimes,
140
- when you are pushing and pulling
141
- elements around on the grid,
142
- it is helpful to add and remove gutters on the fly.
181
+ Anything you put in the root `$susy` variable map
182
+ will be treated as a global default
183
+ across your project.
184
+
185
+
186
+ Advanced Features
187
+ -----------------
188
+
189
+ Once you get used to the basics,
190
+ you can dig into the `spread` options —
191
+ allowing you to include extra gutters in a span —
192
+ and the `susy-slice()` function
193
+ that can help you handle nesting-context with asymmetrical grids.
194
+
195
+ Happy grid-building!
143
196
 
144
197
 
145
198
  Resources
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.0.0.alpha.0
1
+ 3.0.0.alpha.2
data/sass/_prefix.scss CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  $susy-version: 3;
5
5
 
6
+ @import 'susy/utilities';
6
7
  @import 'susy/grids';
7
8
  @import 'susy/settings';
8
9
  @import 'susy/validation';
@@ -0,0 +1,5 @@
1
+ // SVG Grid Background
2
+ // ===================
3
+
4
+ @import 'svg-grid/prefix';
5
+ @import 'svg-grid/svg-unprefix';
@@ -0,0 +1,7 @@
1
+ // Prefixed SVG Plugin
2
+ // ===================
3
+
4
+ @import 'svg-settings';
5
+ @import 'svg-utilities';
6
+ @import 'svg-grid-math';
7
+ @import 'svg-api';
@@ -0,0 +1,78 @@
1
+ // SVG API
2
+ // =======
3
+
4
+
5
+
6
+ // SVG Grid
7
+ // --------
8
+ /// Return inline svg-data in to display the grid
9
+ /// (import `plugins/svg-grid/prefix` to remove unprefixed alias)
10
+ ///
11
+ /// @group plugin_svg-grid
12
+ ///
13
+ /// @param {Map | List} $grid [$susy] -
14
+ /// Map or shorthand defining the current grid
15
+ /// @param {Color | List | null} $colors [null] -
16
+ /// Column color, or list of colors for column-gradient,
17
+ /// used to override the global `svg-grid-colors` setting
18
+ /// @param {Length | null} $offset [null] -
19
+ /// Manually override the default grid-image offset,
20
+ /// to account for grid edges
21
+ ///
22
+ /// @return {String} -
23
+ /// CSS inline-data SVG string, in `url(<svg>)` format,
24
+ /// for use in image or content properties
25
+ @function susy-svg-grid(
26
+ $grid: $susy,
27
+ $colors: null,
28
+ $offset: null
29
+ ) {
30
+ // Grid parsing & normalizing
31
+ @if (type-of($grid) != 'map') and (length($grid) > 0) {
32
+ @if (not index($grid, 'of')) {
33
+ @if su-valid-columns($grid, 'fail-silent') {
34
+ $grid: 'of' $grid;
35
+ } @else {
36
+ $grid: join('of', $grid);
37
+ }
38
+ }
39
+
40
+ $grid: susy-parse($grid);
41
+ }
42
+
43
+ $grid: susy-settings($grid);
44
+ $grid: susy-normalize($grid);
45
+
46
+
47
+ // Color and gradient handling
48
+ $gradient: '';
49
+
50
+ @if (not $colors) {
51
+ $colors: susy-get('svg-grid-colors');
52
+ }
53
+
54
+ @if length($colors) > 1 {
55
+ $gradient: _susy-svg-gradient($colors);
56
+ $colors: 'url(%23susy-svg-gradient)';
57
+ } @else {
58
+ $colors: _susy-svg-color($colors);
59
+ }
60
+
61
+
62
+ // SVG construction
63
+ $columns: map-get($grid, 'columns');
64
+ $offset: $offset or _susy-svg-offset($grid);
65
+
66
+ $svg: 'data:image/svg+xml,';
67
+ $svg: $svg + '%3Csvg xmlns="http://www.w3.org/2000/svg" fill="#{$colors}" %3E';
68
+ $svg: $svg + $gradient;
69
+
70
+ @for $column from 1 through length($columns) {
71
+ $width: susy-span(1 at $column, $grid);
72
+ $x: _susy-svg-column-position($column, $grid);
73
+
74
+ $svg: $svg + _susy-svg-rect($x, $width, $offset);
75
+ }
76
+
77
+ @return url('#{$svg}%3C/svg%3E');
78
+ }
@@ -0,0 +1,72 @@
1
+ // SVG Grid Math
2
+ // =============
3
+
4
+
5
+
6
+ // SVG Column Position
7
+ // -------------------
8
+ /// Determine the proper horizontal position
9
+ /// for a column rectangle
10
+ ///
11
+ /// @access private
12
+ ///
13
+ /// @param {Integer} $column -
14
+ /// 1-indexed column location on the grid
15
+ /// @param {Map} $grid -
16
+ /// Normalized settings map representing the current grid
17
+ ///
18
+ /// @return {Length} -
19
+ /// Horizontal position of svg column rectangle,
20
+ /// as distance from the grid edge
21
+ @function _susy-svg-column-position(
22
+ $column,
23
+ $grid
24
+ ) {
25
+ $x: $column - 1;
26
+
27
+ @if ($x > 0) {
28
+ $x: susy-span(first $x wide, $grid);
29
+ }
30
+
31
+ @return $x;
32
+ }
33
+
34
+
35
+
36
+ // SVG Offset
37
+ // ----------
38
+ /// Determine if a grid image needs to be offset,
39
+ /// to account for edge gutters.
40
+ ///
41
+ /// @access private
42
+ ///
43
+ /// @param {Map} $grid -
44
+ /// Normalized settings map representing the current grid
45
+ ///
46
+ /// @return {Length | null} -
47
+ /// Expected distance from container edge to first column,
48
+ /// based on spread values and gutter-widths
49
+ @function _susy-svg-offset(
50
+ $grid
51
+ ) {
52
+ $columns: su-valid-columns(map-get($grid, 'columns'));
53
+ $gutters: su-valid-gutters(map-get($grid, 'gutters'), $columns);
54
+ $first: nth($columns, 1);
55
+
56
+ @if (unitless($first)) and (not unitless($gutters)) {
57
+ @return null;
58
+ }
59
+
60
+ $container: map-get($grid, 'container-spread');
61
+ $span: map-get($grid, 'spread');
62
+ $extra: $container - $span;
63
+
64
+ @if $extra == 0 {
65
+ @return null;
66
+ }
67
+
68
+ @return $extra * susy-gutter($config: $grid) / 2;
69
+ }
70
+
71
+
72
+
@@ -0,0 +1,14 @@
1
+ // SVG Settings
2
+ // ============
3
+
4
+
5
+ // Susy SVG Defaults
6
+ // =================
7
+ /// This plugin adds the `svg-grid-colors` property
8
+ /// and default value to `$susy-defaults` —
9
+ /// you can override that value in `$susy`
10
+ /// or any other grid settings map.
11
+ /// @group plugin_svg-grid
12
+ $susy-defaults: map-merge((
13
+ 'svg-grid-colors': hsla(120, 50%, 50%, 0.5) hsla(120, 50%, 75%, 0.5),
14
+ ), $susy-defaults);
@@ -0,0 +1,18 @@
1
+ // Unprefix Susy SVG Grid
2
+ // ======================
3
+
4
+
5
+
6
+ // SVG Grid
7
+ // --------
8
+ /// Un-prefixed alias for `susy-svg-grid`
9
+ ///
10
+ /// @group plugin_svg-grid
11
+ /// @alias susy-svg-grid
12
+ @function svg-grid(
13
+ $grid: $susy,
14
+ $colors: susy-get('svg-grid-colors'),
15
+ $offset: null
16
+ ) {
17
+ @return susy-svg-grid($grid, $colors, $offset);
18
+ }
@@ -0,0 +1,127 @@
1
+ // SVG Utilities
2
+ // =============
3
+
4
+
5
+
6
+ // SVG Validate Units
7
+ // ------------------
8
+ /// Make sure a length is supported in svg
9
+ ///
10
+ /// @access private
11
+ ///
12
+ /// @param {Length} $length -
13
+ /// The length to validate
14
+ /// @param {String} $name [null] -
15
+ /// Optional name of length origin,
16
+ /// for error reporting
17
+ ///
18
+ /// @return {Length} -
19
+ /// An svg-validated length, or comparable valid length
20
+ @function _susy-svg-validate-units(
21
+ $length,
22
+ $name: null
23
+ ) {
24
+ $_svg-units: ('em', 'ex', 'px', 'pt', 'pc', 'cm', 'mm', 'in', '%');
25
+
26
+ @if ($length == 0) or index($_svg-units, unit($length)) {
27
+ @return $length;
28
+ }
29
+
30
+ @return _susy-error(
31
+ '`#{unit($length)}` #{$name} units are not supported in SVG',
32
+ '_susy-svg-validate-units');
33
+ }
34
+
35
+
36
+
37
+ // SVG Rect
38
+ // --------
39
+ /// Build a single svg rectangle
40
+ ///
41
+ /// @access private
42
+ ///
43
+ /// @param {Length} $x -
44
+ /// Horizontal position for the rectangle
45
+ /// @param {Length} $width -
46
+ /// Width of the rectangle
47
+ /// @param {Length} $offset [null] -
48
+ /// Offset the rectangle, to account for edge gutters
49
+ ///
50
+ /// @return {String} -
51
+ /// Escaped string representing one svg rectangle
52
+ @function _susy-svg-rect(
53
+ $x,
54
+ $width,
55
+ $offset: null
56
+ ) {
57
+ $x: _susy-svg-validate-units($x);
58
+ $width: _susy-svg-validate-units($width);
59
+ $offset: if($offset == 0, null, $offset);
60
+
61
+ @if $offset and comparable($x, $offset) {
62
+ $x: $x + $offset;
63
+ $offset: null;
64
+ } @else if $offset {
65
+ $offset: 'style="transform:translateX(#{$offset})"';
66
+ }
67
+
68
+ @return '%3Crect x="#{$x}" width="#{$width}" height="100%" #{$offset}/%3E';
69
+ }
70
+
71
+
72
+
73
+ // SVG Color
74
+ // ---------
75
+ /// Stringify colors, and escape hex symbol
76
+ ///
77
+ /// @access private
78
+ ///
79
+ /// @param {Color} $color -
80
+ /// Color to stringify and escape
81
+ ///
82
+ /// @return {String} -
83
+ /// Escaped string value of color
84
+ @function _susy-svg-color(
85
+ $color
86
+ ) {
87
+ $color: inspect($color); // convert to string
88
+
89
+ @if (str-index($color, '#') == 1) {
90
+ $color: '%23' + str-slice($color, 2);
91
+ }
92
+
93
+ @return $color;
94
+ }
95
+
96
+
97
+
98
+ // SVG Gradient
99
+ // ------------
100
+ /// Create a multi-color svg gradient
101
+ ///
102
+ /// @access private
103
+ ///
104
+ /// @param {List} $colors -
105
+ /// List of colors to be equally spaced from `0%` to `100%`
106
+ /// in each column rectangle
107
+ ///
108
+ /// @return {String} -
109
+ /// Escaped string representing one svg gradient
110
+ /// (`id="susy-svg-gradient"`)
111
+ @function _susy-svg-gradient(
112
+ $colors
113
+ ) {
114
+ $gradient: '%3Cdefs%3E%3ClinearGradient spreadMethod="pad"';
115
+ $gradient: '#{$gradient} id="susy-svg-gradient"';
116
+ $gradient: '#{$gradient} x1="0%" y1="0%" x2="100%" y2="0%"%3E';
117
+
118
+ @for $i from 1 through length($colors) {
119
+ $color: _susy-svg-color(nth($colors, $i));
120
+ $offset: percentage(($i - 1) / (length($colors) - 1));
121
+ $stop: '%3Cstop offset="#{$offset}" style="stop-color:#{$color};" /%3E';
122
+
123
+ $gradient: $gradient + $stop;
124
+ }
125
+
126
+ @return $gradient + '%3C/linearGradient%3E%3C/defs%3E';
127
+ }
data/sass/susy/_api.scss CHANGED
@@ -18,13 +18,15 @@
18
18
  /// @group api
19
19
  ///
20
20
  /// @param {List} $span -
21
- /// Shorthand expression to define the width of the span
22
- /// containing a unitless column-span;
23
- /// 'of $n' for available grid columns [optional];
24
- /// 'at $n', 'first', or 'last' for location on asymmetrical grids;
25
- /// and 'narrow', 'wide', or 'wider' for
26
- /// optionally spreading over adjacent gutters
27
- /// with either the `span` or `columns` value
21
+ /// Shorthand expression to define the width of the span,
22
+ /// optionally containing:
23
+ /// - a count, length, or column-list span;
24
+ /// - `at $n`, `first`, or `last` location on asymmetrical grids;
25
+ /// - `narrow`, `wide`, or `wider` for optionally spreading
26
+ /// across adjacent gutters;
27
+ /// - `of $n <spread>` for available grid columns
28
+ /// and spread of the container;
29
+ /// - and `set-gutters $n` to override global gutter settings
28
30
  /// @param {Map} $config [()] -
29
31
  /// Optional map of Susy grid configuration settings
30
32
  ///
@@ -48,7 +50,24 @@
48
50
  $input: susy-settings($config, susy-parse($span));
49
51
  $normal: susy-normalize($input);
50
52
 
51
- @return su-span($normal...);
53
+ @if map-get($normal, 'span') {
54
+ $args: (
55
+ 'span', 'columns', 'gutters', 'spread', 'container-spread', 'location'
56
+ );
57
+
58
+ @each $key in map-keys($normal) {
59
+ @if not (index($args, $key)) {
60
+ $normal: map-remove($normal, $key);
61
+ }
62
+ }
63
+
64
+ @return su-span($normal...);
65
+ }
66
+
67
+ $actual: '[#{type-of($span)}] `#{inspect($span)}`';
68
+ @return _susy-error(
69
+ 'Unable to determine span value from #{$actual}.',
70
+ 'susy-span');
52
71
  }
53
72
 
54
73
 
@@ -62,7 +81,10 @@
62
81
  /// @group api
63
82
  ///
64
83
  /// @param {Number | List} $context [null] -
65
- /// Optional columns in a nested context
84
+ /// Optional context for nested gutters,
85
+ /// including shorthand for
86
+ /// `columns`, `gutters`, and `container-spread`
87
+ /// (additional shorthand will be ignored)
66
88
  /// @param {Map} $config [()] -
67
89
  /// Optional map of Susy grid configuration settings
68
90
  ///
@@ -78,16 +100,25 @@
78
100
  $context: susy-get('columns'),
79
101
  $config: ()
80
102
  ) {
103
+ @if (not index($context, 'of')) {
104
+ @if su-valid-columns($context, 'fail-silent') {
105
+ $context: 'of' $context;
106
+ } @else {
107
+ $context: join('of', $context);
108
+ }
109
+ }
110
+
111
+ $parsed: susy-settings($config, susy-parse($context));
112
+ $normal: susy-normalize($parsed);
81
113
  $args: ('columns', 'gutters', 'container-spread');
82
- $input: susy-settings($config, ('columns': $context));
83
- $normal: susy-normalize($input);
84
- $output: ();
85
114
 
86
- @each $setting in $args {
87
- $output: map-merge($output, ($setting: map-get($normal, $setting)));
115
+ @each $key in map-keys($normal) {
116
+ @if not (index($args, $key)) {
117
+ $normal: map-remove($normal, $key);
118
+ }
88
119
  }
89
120
 
90
- @return su-gutter($output...);
121
+ @return su-gutter($normal...);
91
122
  }
92
123
 
93
124
 
@@ -38,18 +38,18 @@
38
38
  $container-spread: $spread,
39
39
  $location: 1
40
40
  ) {
41
+ $span: su-valid-span($span);
41
42
  $columns: su-valid-columns($columns);
42
43
  $gutters: su-valid-gutters($gutters, $columns);
43
44
  $spread: su-valid-spread($spread);
44
45
 
45
46
  @if (type-of($span) == 'number') {
46
- @if unitless($span) {
47
- $location: su-valid-location($span, $location, $columns);
48
- $span: su-slice($span, $columns, $location, $validate: false);
49
- } @else {
50
- // if you give us e.g. 3em, fine, we'll give it right back
47
+ @if (not unitless($span)) {
51
48
  @return $span;
52
49
  }
50
+
51
+ $location: su-valid-location($span, $location, $columns);
52
+ $span: su-slice($span, $columns, $location, $validate: false);
53
53
  }
54
54
 
55
55
  $span-width: su-sum($span, $gutters, $spread, $validate: false);
@@ -135,10 +135,8 @@
135
135
  $column-sum: $column-sum + $column;
136
136
  }
137
137
 
138
- // Gutters are removed from the math if they use non-comparable static units
139
- $not-comparable: not comparable($column-sum, $gutters);
140
- $is-mismatch: unitless($column-sum) and (not unitless($gutters));
141
- @if ($not-comparable or $is-mismatch) {
138
+ // Gutters are removed from the math if they are non-comparable
139
+ @if (unitless($column-sum)) and (not unitless($gutters)) {
142
140
  @return $column-sum;
143
141
  }
144
142
 
@@ -8,6 +8,7 @@
8
8
  // - susy-normalize-location [function]
9
9
 
10
10
 
11
+
11
12
  // Parse
12
13
  // -----
13
14
  /// Parse shorthand span expression
@@ -15,23 +16,27 @@
15
16
  /// @access private
16
17
  ///
17
18
  /// @param {List} $shorthand -
18
- /// Shorthand expression to define the width of the span
19
- /// containing a unitless column-span;
20
- /// 'of $n' for available grid columns [optional];
21
- /// 'at $n', 'first', or 'last' for location on asymmetrical grids;
22
- /// and 'narrow', 'wide', or 'wider' for
23
- /// optionally spreading over adjacent gutters
24
- /// with either the `span` or `columns` value
19
+ /// Shorthand expression to define the width of the span,
20
+ /// optionally containing:
21
+ /// - a count, length, or column-list span;
22
+ /// - `at $n`, `first`, or `last` location on asymmetrical grids;
23
+ /// - `narrow`, `wide`, or `wider` for optionally spreading
24
+ /// across adjacent gutters;
25
+ /// - `of $n <spread>` for available grid columns
26
+ /// and spread of the container;
27
+ /// - and `set-gutters $n` to override global gutter settings
28
+ /// @param {Bool} $context-only -
29
+ /// Allow the parser to ignore span and span-spread values,
30
+ /// only parsing context and container-spread
25
31
  ///
26
32
  /// @return {Map} -
27
33
  /// Map of span settings
28
- /// (`span`, `location`, `columns`, `spread`, `container-spread`)
34
+ /// (`span`, `location`, `columns`, `gutters`, `spread`, `container-spread`)
29
35
  /// parsed from shorthand input
30
36
  @function susy-parse(
31
37
  $shorthand
32
38
  ) {
33
- $span-error: 'Not able to determine column-span from `#{$shorthand}`';
34
- $parse-error: 'Unknown span property:';
39
+ $parse-error: 'Unknown shorthand property:';
35
40
  $options: (
36
41
  'first': 'location',
37
42
  'last': 'location',
@@ -46,80 +51,106 @@
46
51
  $span: null;
47
52
  $columns: null;
48
53
 
49
- $of: false;
54
+ $of: null;
50
55
  $next: false;
51
56
 
57
+ // loop through the shorthand list
52
58
  @for $i from 1 through length($shorthand) {
53
59
  $item: nth($shorthand, $i);
54
60
  $type: type-of($item);
61
+ $details: '[#{$type}] `#{$item}`';
55
62
 
63
+ // if we know what's supposed to be coming next…
56
64
  @if $next {
65
+ // If it's supposed to be a column width…
57
66
  @if ($next == 'column-width') {
67
+ // if it looks like a column width…
58
68
  @if ($type == 'number') and (not unitless($item)) {
59
- @if $columns {
69
+ // could be either span or context width…
70
+ @if $of {
60
71
  $columns: join($columns, ('x' $item));
61
72
  } @else {
62
73
  $span: join($span, ('x' $item));
63
74
  }
64
- } @else {
65
- @error '`#{item}` is not a valid column-width';
75
+
76
+ } @else { // Column-width error
77
+ @return _susy-error(
78
+ '`#{$item}` is not a valid column-width',
79
+ 'susy-parse');
66
80
  }
67
- } @else {
81
+
82
+ } @else { // For other values of next, we simply add to the return map
68
83
  $return: map-merge($return, ($next: $item));
69
84
  }
70
85
 
86
+ // Reset next to `false`
71
87
  $next: false;
72
- } @else {
88
+
89
+ } @else { // If we don't know what's supposed to be coming…
90
+ // Keywords…
73
91
  @if ($type == 'string') {
92
+ // Check the map for keywords…
74
93
  @if map-has-key($options, $item) {
75
94
  $setting: map-get($options, $item);
76
95
 
77
- @if ($setting == 'spread') and $of {
96
+ // Spread could be on the span or the container…
97
+ @if ($setting == 'spread') and ($of) {
78
98
  $return: map-merge($return, ('container-spread': $item));
79
99
  } @else {
80
100
  $return: map-merge($return, ($setting: $item));
81
101
  }
82
- } @else if $item == 'all' {
102
+
103
+ } @else if ($item == 'all') { // `All` is a span shortcut
83
104
  $span: 'all';
84
- } @else if not $span {
85
- @error $span-error;
86
- } @else if ($item == 'at') {
105
+
106
+ } @else if ($item == 'at') { // Some keywords setup what's next…
87
107
  $next: 'location';
88
108
  } @else if ($item == 'x') {
89
109
  $next: 'column-width';
110
+ } @else if ($item == 'set-gutters') {
111
+ $next: 'gutters';
90
112
  } @else if ($item == 'of') {
91
113
  $of: true;
92
- } @else {
93
- @error '#{$parse-error} `#{$item}`';
114
+
115
+ } @else { // Error if we're out of ideas
116
+ @return _susy-error('#{$parse-error} #{$details}', 'susy-parse');
94
117
  }
95
- } @else if ($type == 'number') or ($type == 'list') {
96
- @if not $span {
118
+
119
+ } @else if ($type == 'number') or ($type == 'list') { // Numbers & lists…
120
+
121
+ // We don't have a span, and we're not expecting context…
122
+ @if not ($span or $of) {
97
123
  $span: $item;
98
- } @else if $of {
124
+
125
+ } @else if ($of) and (not $columns) { // We are expecting context…
99
126
  $columns: $item;
100
- } @else {
101
- @error '#{$parse-error} `#{$item}`';
127
+
128
+ } @else { // Error if we don't understand…
129
+ @return _susy-error('#{$parse-error} #{$details}', 'susy-parse');
102
130
  }
103
- } @else {
104
- @error '#{$parse-error} `#{$item}`';
131
+
132
+ } @else { // Error if we don't know this type…
133
+ @return _susy-error('#{$parse-error} #{$details}', 'susy-parse');
105
134
  }
106
135
  }
107
136
  }
108
137
 
138
+ // If we have span, merge it in
109
139
  @if $span {
110
140
  $return: map-merge($return, ('span': $span));
111
- } @else {
112
- @error $span-error;
113
141
  }
114
142
 
143
+ // If we have columns, merge them in
115
144
  @if $columns {
116
145
  $return: map-merge($return, ('columns': $columns));
117
146
  }
118
147
 
148
+ // Return the map of settings…
119
149
  @return $return;
120
150
  }
121
151
 
122
152
 
153
+
123
154
  // Susy Normalize
124
155
  // --------------
125
156
  /// Normalize the values in a configuration map
@@ -139,6 +170,7 @@
139
170
 
140
171
  @if $value {
141
172
  $function: if(($setting == 'container-spread'), 'spread', $setting);
173
+ $function: _susy-get-function($function);
142
174
  $value: call('susy-normalize-#{$function}', $value);
143
175
  }
144
176
 
@@ -163,6 +195,7 @@
163
195
  }
164
196
 
165
197
 
198
+
166
199
  // Normalize Columns
167
200
  // -----------------
168
201
  /// Normalize `columns` shorthand for Su
@@ -199,6 +232,7 @@
199
232
  }
200
233
 
201
234
 
235
+
202
236
  // Normalize Span
203
237
  // --------------
204
238
  /// Normalize `span` shorthand for Su
@@ -226,6 +260,7 @@
226
260
  }
227
261
 
228
262
 
263
+
229
264
  // Normalize Spread
230
265
  // ----------------
231
266
  /// Normalize `spread` shorthand for Su
@@ -251,6 +286,7 @@
251
286
  }
252
287
 
253
288
 
289
+
254
290
  // Normalize Location
255
291
  // ------------------
256
292
  /// Normalize `location` shorthand for Su
@@ -6,6 +6,7 @@
6
6
  // - susy-get [function]
7
7
 
8
8
 
9
+
9
10
  // Susy
10
11
  // ----
11
12
  /// Custom user configuration map for Susy
@@ -40,6 +41,7 @@
40
41
  $susy: () !default;
41
42
 
42
43
 
44
+
43
45
  // Susy Defaults
44
46
  // -------------
45
47
  /// Configuration map of Susy factory defaults
@@ -95,6 +97,7 @@ $susy-defaults: (
95
97
  }
96
98
 
97
99
 
100
+
98
101
  // Susy Get
99
102
  // --------
100
103
  /// Return the current value of any Susy setting
@@ -113,7 +116,9 @@ $susy-defaults: (
113
116
  $settings: susy-settings();
114
117
 
115
118
  @if not map-has-key($settings, $key) {
116
- @error 'There is no Susy setting called `#{$key}`';
119
+ @return _susy-error(
120
+ 'There is no Susy setting called `#{$key}`',
121
+ 'susy-get');
117
122
  }
118
123
 
119
124
  @return map-get($settings, $key);
@@ -0,0 +1,60 @@
1
+ // Sass Utilities
2
+ // ==============
3
+ // - Susy Get Function [function]
4
+ // - Susy Error Output Override [variable]
5
+ // - Susy Error [function]
6
+
7
+
8
+
9
+ // Susy Get Function
10
+ // -----------------
11
+ /// Get a first-class function in Sass 3.5+,
12
+ /// or the function name string (unchanged)
13
+ /// in older Sass versions.
14
+ ///
15
+ /// @access private
16
+ ///
17
+ /// @param {String} $function -
18
+ /// The name (string) of a function to be called.
19
+ /// @return {String | Function} -
20
+ /// Returns a first-class function in Sass 3.5+,
21
+ /// or the function name string in older Sass versions.
22
+ @function _susy-get-function(
23
+ $function
24
+ ) {
25
+ $type: type-of($function);
26
+
27
+ @if ($type != 'string') {
28
+ @return _susy-error(
29
+ 'Invalid function-name [#{$type}] `#{$function}`, name must be a string.',
30
+ '_susy-get-function');
31
+ }
32
+
33
+ @if function-exists('get-function') {
34
+ @return get-function($function);
35
+ }
36
+
37
+ @return $function;
38
+ }
39
+
40
+
41
+
42
+ // Susy Error Output Override
43
+ // --------------------------
44
+ $_susy-error-output-override: false !default;
45
+
46
+
47
+
48
+ // Susy Error
49
+ // ----------
50
+ @function _susy-error(
51
+ $message,
52
+ $source,
53
+ $override: $_susy-error-output-override
54
+ ) {
55
+ @if $override {
56
+ @return 'ERROR [#{$source}] #{$message}';
57
+ }
58
+
59
+ @error '[#{$source}] #{$message}';
60
+ }
@@ -6,6 +6,37 @@
6
6
  // - su-valid-location [function]
7
7
 
8
8
 
9
+
10
+ // Valid Span
11
+ // ----------
12
+ /// Check that the `span` argument
13
+ /// is a number, length, or column-list
14
+ ///
15
+ /// @access private
16
+ ///
17
+ /// @param {Number | List} $span -
18
+ /// Number of columns, or length of span
19
+ ///
20
+ /// @return {Number | List} -
21
+ /// Validated `$span` number, length, or columns list
22
+ @function su-valid-span(
23
+ $span
24
+ ) {
25
+ $type: type-of($span);
26
+ @if ($type == 'number') {
27
+ @return $span;
28
+ } @else if ($type == 'list') and su-valid-columns($span, 'silent-failure') {
29
+ @return $span;
30
+ }
31
+
32
+ $actual: '[#{type-of($span)}] `#{inspect($span)}`';
33
+ @return _susy-error(
34
+ '#{$actual} is not a valid number, length, or column-list for $span.',
35
+ 'su-valid-span');
36
+ }
37
+
38
+
39
+
9
40
  // Valid Columns
10
41
  // -------------
11
42
  /// Check that the `columns` argument is a valid
@@ -15,25 +46,36 @@
15
46
  ///
16
47
  /// @param {List} $columns -
17
48
  /// List of column-lengths using comparable units
49
+ /// @param {Bool} $silent-failure [true] -
50
+ /// Set false to return null on failure
18
51
  ///
19
52
  /// @return {List} -
20
53
  /// Validated `$columns` list
21
54
  @function su-valid-columns(
22
- $columns
55
+ $columns,
56
+ $silent-failure: false
23
57
  ) {
24
58
  $first: nth($columns, 1);
25
59
 
26
60
  @each $col in $columns {
27
- @if (type-of($col) != 'number') or (not comparable($col, $first)) {
61
+ @if (type-of($col) != 'number') or (not comparable($col, $first)) or (unitless($col) and not unitless($first)) or (unitless($first) and not unitless($col)) {
62
+ @if $silent-failure {
63
+ @return null;
64
+ }
65
+
28
66
  $actual: '[#{type-of($columns)}] `#{inspect($columns)}`';
29
- @error '#{$actual} is not a value for $columns.';
67
+ @return _susy-error(
68
+ '#{$actual} is not a valid list of comparable lengths for $columns.',
69
+ 'su-valid-columns');
30
70
  }
71
+
31
72
  }
32
73
 
33
74
  @return $columns;
34
75
  }
35
76
 
36
77
 
78
+
37
79
  // Valid Gutters
38
80
  // -------------
39
81
  /// Check that the `gutters` argument is a valid number
@@ -54,18 +96,31 @@
54
96
  $type: type-of($gutters);
55
97
 
56
98
  @if ($type == 'number') {
57
- @if unitless($gutters) and (not unitless(nth($columns, 1))) {
58
- @error 'Gutters must have units for a static grid.';
99
+ $first: nth($columns, 1);
100
+
101
+ @if (unitless($gutters) and not unitless($first)) {
102
+ @return _susy-error(
103
+ 'Gutters must have units for a static grid.',
104
+ 'su-valid-gutters');
105
+ }
106
+
107
+ @if (not comparable($gutters, $first)) {
108
+ @return _susy-error(
109
+ 'Gutter and column units must be comparable.',
110
+ 'su-valid-gutters');
59
111
  }
60
112
 
61
113
  @return $gutters;
62
114
  }
63
115
 
64
116
  $actual: '[#{$type}] `#{inspect($gutters)}`';
65
- @error '#{$actual} is not a value for $gutters.';
117
+ @return _susy-error(
118
+ '#{$actual} is not a value for $gutters.',
119
+ 'su-valid-gutters');
66
120
  }
67
121
 
68
122
 
123
+
69
124
  // Valid Spread
70
125
  // ------------
71
126
  /// Check that the `spread` argument is a valid
@@ -87,10 +142,13 @@
87
142
  }
88
143
 
89
144
  $actual: '[#{type-of($spread)}] `#{inspect($spread)}`';
90
- @error '#{$actual} is not a value for $spread.';
145
+ @return _susy-error(
146
+ '#{$actual} is not a normalized [0 | 1 | -1] value for `$spread`.',
147
+ 'su-valid-spread');
91
148
  }
92
149
 
93
150
 
151
+
94
152
  // Valid Location
95
153
  // --------------
96
154
  /// Check that the `location` argument is a valid number,
@@ -117,14 +175,22 @@
117
175
  @if $location {
118
176
  @if (type-of($location) != 'number') or (not unitless($location)) {
119
177
  $actual: '[#{type-of($location)}] `#{$location}`';
120
- @error '#{$actual} is not a value for $location.';
178
+ @return _susy-error(
179
+ '#{$actual} is not a unitless number for $location.',
180
+ 'su-valid-location');
121
181
  } @else if (round($location) != $location) {
122
- @error 'Location (`#{$location}`) must be a 1-indexed intiger position.';
123
- } @else if ($location > $count) {
124
- @error 'Position `#{$location}` does not exist in grid `#{$columns}`.';
182
+ @return _susy-error(
183
+ 'Location (`#{$location}`) must be a 1-indexed intiger position.',
184
+ 'su-valid-location');
185
+ } @else if ($location > $count) or ($location < 1) {
186
+ @return _susy-error(
187
+ 'Position `#{$location}` does not exist in grid `#{$columns}`.',
188
+ 'su-valid-location');
125
189
  } @else if ($location + $span - 1 > $count) {
126
190
  $details: 'grid `#{$columns}` for span `#{$span}` at `#{$location}`';
127
- @error 'There are not enough columns in #{$details}';
191
+ @return _susy-error(
192
+ 'There are not enough columns in #{$details}.',
193
+ 'su-valid-location');
128
194
  }
129
195
  }
130
196
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: susy
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.alpha.1
4
+ version: 3.0.0.alpha.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miriam Eric Suzanne
@@ -46,11 +46,19 @@ files:
46
46
  - lib/susy.rb
47
47
  - sass/_prefix.scss
48
48
  - sass/_susy.scss
49
+ - sass/plugins/_svg-grid.scss
50
+ - sass/plugins/svg-grid/_prefix.scss
51
+ - sass/plugins/svg-grid/_svg-api.scss
52
+ - sass/plugins/svg-grid/_svg-grid-math.scss
53
+ - sass/plugins/svg-grid/_svg-settings.scss
54
+ - sass/plugins/svg-grid/_svg-unprefix.scss
55
+ - sass/plugins/svg-grid/_svg-utilities.scss
49
56
  - sass/susy/_api.scss
50
57
  - sass/susy/_grids.scss
51
58
  - sass/susy/_parser.scss
52
59
  - sass/susy/_settings.scss
53
60
  - sass/susy/_unprefix.scss
61
+ - sass/susy/_utilities.scss
54
62
  - sass/susy/_validation.scss
55
63
  - CHANGELOG.md
56
64
  - LICENSE.txt
@@ -77,9 +85,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
77
85
  version: '0'
78
86
  required_rubygems_version: !ruby/object:Gem::Requirement
79
87
  requirements:
80
- - - '>'
88
+ - - '>='
81
89
  - !ruby/object:Gem::Version
82
- version: 1.3.1
90
+ version: '1.2'
83
91
  requirements: []
84
92
  rubyforge_project: susy
85
93
  rubygems_version: 2.1.10