@octaviaflow/grid 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,324 @@
1
+ //
2
+ // Copyright OctaviaFlow. 2025
3
+ //
4
+ // This source code is licensed under the Apache-2.0 license found in the
5
+ // LICENSE file in the root directory of this source tree.
6
+ //
7
+
8
+ // Helpers for defining columns, rows, and containers are heavily inspired by,
9
+ // and often derived from, bootstrap:
10
+ // https://github.com/twbs/bootstrap/blob/v4-dev/scss/mixins/_grid.scss
11
+
12
+ @use 'sass:list';
13
+ @use 'sass:meta';
14
+ @use 'sass:math';
15
+ @use 'sass:map';
16
+
17
+ @use 'config' as *;
18
+ @use 'breakpoint' as *;
19
+
20
+ // -----------------------------------------------------------------------------
21
+ // Columns
22
+ // -----------------------------------------------------------------------------
23
+
24
+ /// Used to initialize the default properties for a column class, most notably
25
+ /// for setting width and default gutters when a column's breakpoint has not been
26
+ /// hit yet.
27
+ /// @param {Number} $gutter [$grid-gutter] - The gutter for the grid system
28
+ /// @param {Number} $collapsed-gutter [$grid-gutter-condensed] - The condensed mode gutter
29
+ /// @access private
30
+ /// @group @octaviaflow/grid
31
+ @mixin -make-col-ready(
32
+ $gutter: $grid-gutter,
33
+ $condensed-gutter: $grid-gutter-condensed
34
+ ) {
35
+ // Prevent columns from becoming too narrow when at smaller grid tiers by
36
+ // always setting `width: 100%;`. This works because we use `flex` values
37
+ // later on to override this initial width.
38
+ inline-size: 100%;
39
+ padding-inline: $gutter * 0.5;
40
+
41
+ // For our condensed use-case, our gutters collapse to 2px solid, 1px on each
42
+ // side.
43
+ .#{$prefix}--row--condensed &,
44
+ .#{$prefix}--grid--condensed & {
45
+ padding-inline: $condensed-gutter * 0.5;
46
+ }
47
+
48
+ // For our narrow use-case, our container hangs 16px into the gutter
49
+ .#{$prefix}--row--narrow &,
50
+ .#{$prefix}--grid--narrow & {
51
+ padding-inline: 0 $gutter * 0.5;
52
+ }
53
+ }
54
+
55
+ /// Define the width of the column for a given span and column count.
56
+ /// A width of 0 will hide the column entirely.
57
+ /// @param {Number} $span - The number of columns covered
58
+ /// @param {Number} $columns - The total number of columns available
59
+ /// @access private
60
+ /// @group @octaviaflow/grid
61
+ @mixin -make-col($span, $columns) {
62
+ @if $span == 0 {
63
+ display: none;
64
+ } @else {
65
+ // Explicitly include `display: block` to override
66
+ display: block;
67
+ // Add a `max-width` to ensure content within each column does not blow out
68
+ // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari
69
+ // do not appear to require this.
70
+ flex: 0 0 math.percentage(math.div($span, $columns));
71
+ max-inline-size: math.percentage(math.div($span, $columns));
72
+ }
73
+ }
74
+
75
+ /// Create a column offset for a given span and column count.
76
+ /// @param {Number} $span - The number of columns the offset should cover
77
+ /// @param {Number} $columns - The total number of columns available
78
+ /// @access private
79
+ /// @group @octaviaflow/grid
80
+ @mixin -make-col-offset($span, $columns) {
81
+ $offset: 0;
82
+ $offset: math.div($span, $columns);
83
+ @if $offset == 0 {
84
+ margin-inline-start: 0;
85
+ } @else {
86
+ margin-inline-start: math.percentage($offset);
87
+ }
88
+ }
89
+
90
+ /// Output the CSS required for all the columns in a given grid system.
91
+ /// @param {Map} $breakpoints [$grid-breakpoints] - The breakpoints in the grid system
92
+ /// @param {Number} $gutter [$grid-gutter] - The gutter for the grid system
93
+ /// @access private
94
+ /// @group @octaviaflow/grid
95
+ @mixin -make-grid-columns(
96
+ $breakpoints: $grid-breakpoints,
97
+ $gutter: $grid-gutter
98
+ ) {
99
+ .#{$prefix}--col {
100
+ @include -make-col-ready($gutter);
101
+ }
102
+
103
+ @each $breakpoint in map-keys($breakpoints) {
104
+ $infix: breakpoint-infix($breakpoint);
105
+ $columns: map.get(map.get($breakpoints, $breakpoint), columns);
106
+
107
+ // Allow columns to stretch full width below their breakpoints
108
+ @for $i from 0 through $columns {
109
+ .#{$prefix}--col#{$infix}-#{$i} {
110
+ @include -make-col-ready($gutter);
111
+ }
112
+ }
113
+
114
+ .#{$prefix}--col#{$infix},
115
+ .#{$prefix}--col#{$infix}--auto {
116
+ @include -make-col-ready($gutter);
117
+ }
118
+
119
+ @include breakpoint($breakpoint, $breakpoints) {
120
+ // Provide basic `.col-{bp}` classes for equal-width flexbox columns
121
+ .#{$prefix}--col,
122
+ .#{$prefix}--col#{$infix} {
123
+ flex-basis: 0;
124
+ flex-grow: 1;
125
+ max-inline-size: 100%;
126
+ }
127
+
128
+ .#{$prefix}--col--auto,
129
+ .#{$prefix}--col#{$infix}--auto {
130
+ flex: 1 0 0%;
131
+ inline-size: auto;
132
+ // Reset earlier grid tiers
133
+ max-inline-size: 100%;
134
+ }
135
+
136
+ @for $i from 0 through $columns {
137
+ .#{$prefix}--col#{$infix}-#{$i} {
138
+ @include -make-col($i, $columns);
139
+ }
140
+ }
141
+
142
+ @for $i from 0 through ($columns - 1) {
143
+ @if not($infix == '') {
144
+ .#{$prefix}--offset#{$infix}-#{$i} {
145
+ @include -make-col-offset($i, $columns);
146
+ }
147
+ }
148
+ }
149
+ }
150
+ }
151
+ }
152
+
153
+ // -----------------------------------------------------------------------------
154
+ // Rows
155
+ // -----------------------------------------------------------------------------
156
+
157
+ /// Define the properties for a selector assigned to a row in the grid system.
158
+ /// @param {Number} $gutter [$grid-gutter] - The gutter in the grid system
159
+ /// @access private
160
+ /// @group @octaviaflow/grid
161
+ @mixin -make-row($gutter: $grid-gutter) {
162
+ display: flex;
163
+ flex-wrap: wrap;
164
+ margin-inline: -1 * $gutter * 0.5;
165
+ }
166
+
167
+ // -----------------------------------------------------------------------------
168
+ // No gutter
169
+ // -----------------------------------------------------------------------------
170
+
171
+ /// Add `no-gutter` and `no-gutter--{start,end}` classes to the output CSS. These
172
+ /// classes are useful for dropping the gutter in fluid situations.
173
+ /// @access private
174
+ /// @group @octaviaflow/grid
175
+ @mixin -no-gutter {
176
+ .#{$prefix}--no-gutter,
177
+ .#{$prefix}--row.#{$prefix}--no-gutter [class*='#{$prefix}--col'] {
178
+ padding-inline: 0;
179
+ }
180
+
181
+ .#{$prefix}--no-gutter--start,
182
+ .#{$prefix}--row.#{$prefix}--no-gutter--start [class*='#{$prefix}--col'] {
183
+ padding-inline-start: 0;
184
+ }
185
+
186
+ .#{$prefix}--no-gutter--end,
187
+ .#{$prefix}--row.#{$prefix}--no-gutter--end [class*='#{$prefix}--col'] {
188
+ padding-inline-end: 0;
189
+ }
190
+ }
191
+
192
+ // -----------------------------------------------------------------------------
193
+ // Hang
194
+ // -----------------------------------------------------------------------------
195
+
196
+ /// Add `hang--start` and `hang--end` classes for a given gutter. These classes are
197
+ /// used alongside `no-gutter--start` and `no-gutter--end` to "hang" type.
198
+ /// @param {Number} $gutter [$grid-gutter] - The gutter in the grid system
199
+ /// @access private
200
+ /// @group @octaviaflow/grid
201
+ @mixin -hang($gutter: $grid-gutter) {
202
+ .#{$prefix}--hang--start {
203
+ padding-inline-start: $gutter * 0.5;
204
+ }
205
+
206
+ .#{$prefix}--hang--end {
207
+ padding-inline-end: $gutter * 0.5;
208
+ }
209
+ }
210
+
211
+ // -----------------------------------------------------------------------------
212
+ // Grid
213
+ // -----------------------------------------------------------------------------
214
+
215
+ /// Create the container for a grid. Will cause full-bleed for the grid unless
216
+ /// max-width properties are added with `make-container-max-widths`
217
+ /// @param {Map} $breakpoints [$grid-breakpoints] - A map of breakpoints where the key is the name
218
+ /// @access private
219
+ /// @group @octaviaflow/grid
220
+ @mixin -make-container($breakpoints: $grid-breakpoints) {
221
+ margin-inline: auto;
222
+
223
+ @include -set-largest-breakpoint($breakpoints);
224
+
225
+ @each $name, $value in $breakpoints {
226
+ $prev-breakpoint: map.get($breakpoints, breakpoint-prev($name));
227
+ $margin: map.get($value, margin);
228
+
229
+ @if $prev-breakpoint {
230
+ $prev-margin: map.get($prev-breakpoint, margin);
231
+ @if $prev-margin != $margin {
232
+ @include breakpoint($name) {
233
+ padding-inline: #{($grid-gutter * 0.5) + $margin};
234
+ }
235
+ }
236
+ } @else {
237
+ @include breakpoint($name) {
238
+ padding-inline: #{($grid-gutter * 0.5) + $margin};
239
+ }
240
+ }
241
+ }
242
+ }
243
+
244
+ /// Get the last breakpoint width and set max-width to its value
245
+ /// @param {Map} $breakpoints [$grid-breakpoints] - A map of breakpoints where the key is the name
246
+ /// @access private
247
+ /// @group @octaviaflow/grid
248
+ @mixin -set-largest-breakpoint($breakpoints: $grid-breakpoints) {
249
+ $largest-breakpoint: -last-map-item($breakpoints);
250
+
251
+ max-inline-size: map.get($largest-breakpoint, 'width');
252
+ }
253
+
254
+ /// Add in the max-widths for each breakpoint to the container
255
+ /// @param {Map} $breakpoints [$grid-breakpoints] - A map of breakpoints where the key is the name
256
+ /// @access private
257
+ /// @group @octaviaflow/grid
258
+ @mixin -make-container-max-widths($breakpoints: $grid-breakpoints) {
259
+ @each $name, $value in $breakpoints {
260
+ @include breakpoint($name) {
261
+ max-inline-size: map.get($value, width);
262
+ }
263
+ }
264
+ }
265
+
266
+ /// Pass in a map, and get the last one in the list back
267
+ /// @access public
268
+ /// @param {Map} $map - Map
269
+ /// @return {*} Desired value
270
+ /// @group @octaviaflow/layout
271
+ @function -last-map-item($map) {
272
+ $total-length: list.length($map);
273
+ @return map-get($map, -key-by-index($map, $total-length));
274
+ }
275
+
276
+ /// Provide a map and index, and get back the relevant key value
277
+ /// @access public
278
+ /// @param {Map} $map - Map
279
+ /// @param {Integer} $index - Key chain
280
+ /// @return {String} Desired value
281
+ /// @group @octaviaflow/layout
282
+ @function -key-by-index($map, $index) {
283
+ $keys: map.keys($map);
284
+ @return nth($keys, $index);
285
+ }
286
+
287
+ /// Generate the CSS for a grid for the given breakpoints and gutters
288
+ /// @param {Map} $breakpoints [$grid-breakpoints] - The default breakpoints
289
+ /// @param {Number} $grid-gutter [$grid-gutter] - The default gutters
290
+ /// @param {Number} $condensed-gutter [$grid-gutter-condensed] - The condensed mode gutter
291
+ /// @access public
292
+ /// @group @octaviaflow/grid
293
+ @mixin flex-grid(
294
+ $breakpoints: $grid-breakpoints,
295
+ $grid-gutter: $grid-gutter,
296
+ $condensed-gutter: $grid-gutter-condensed
297
+ ) {
298
+ .#{$prefix}--grid {
299
+ @include -make-container($breakpoints);
300
+ }
301
+
302
+ @include largest-breakpoint($breakpoints) {
303
+ .#{$prefix}--grid--full-width {
304
+ max-inline-size: 100%;
305
+ }
306
+ }
307
+
308
+ .#{$prefix}--row {
309
+ @include -make-row();
310
+ }
311
+
312
+ .#{$prefix}--row-padding [class*='#{$prefix}--col'],
313
+ .#{$prefix}--col-padding {
314
+ padding-block: $grid-gutter * 0.5;
315
+ }
316
+
317
+ .#{$prefix}--grid--condensed [class*='#{$prefix}--col'] {
318
+ padding-block: $condensed-gutter * 0.5;
319
+ }
320
+
321
+ @include -make-grid-columns($breakpoints, $grid-gutter);
322
+ @include -no-gutter();
323
+ @include -hang($grid-gutter);
324
+ }
@@ -0,0 +1,222 @@
1
+ //
2
+ // Copyright OctaviaFlow. 2025
3
+ //
4
+ // This source code is licensed under the Apache-2.0 license found in the
5
+ // LICENSE file in the root directory of this source tree.
6
+ //
7
+
8
+ @use 'sass:list';
9
+ @use 'sass:map';
10
+ @use 'sass:meta';
11
+ @use '@octaviaflow/layout/scss/convert';
12
+ @use 'config' as *;
13
+
14
+ /// Provide a map and index, and get back the relevant key value
15
+ /// @access public
16
+ /// @param {Map} $map - Map
17
+ /// @param {Integer} $index - Key chain
18
+ /// @return {String} Desired value
19
+ /// @group @octaviaflow/layout
20
+ @function -key-by-index($map, $index) {
21
+ $keys: map.keys($map);
22
+ @return list.nth($keys, $index);
23
+ }
24
+
25
+ /// Get the value of the next breakpoint, or null for the last breakpoint
26
+ /// @param {String} $name - The name of the breakpoint
27
+ /// @param {Map} $breakpoints [$grid-breakpoints] - A map of breakpoints where the key is the name of the breakpoint and the value is the values for the breakpoint
28
+ /// @param {List} $breakpoint-names [map-keys($breakpoints)] - A list of names from the `$breakpoints` map
29
+ /// @return {String}
30
+ /// @access public
31
+ /// @group @octaviaflow/layout
32
+ @function breakpoint-next(
33
+ $name,
34
+ $breakpoints: $grid-breakpoints,
35
+ $breakpoint-names: map.keys($breakpoints)
36
+ ) {
37
+ $n: list.index($breakpoint-names, $name);
38
+ @if $n != null and $n < list.length($breakpoint-names) {
39
+ @return list.nth($breakpoint-names, $n + 1);
40
+ }
41
+ @return null;
42
+ }
43
+
44
+ /// Get the value of the previous breakpoint, or null for the first breakpoint
45
+ /// @param {String} $name - The name of the breakpoint
46
+ /// @param {Map} $breakpoints [$grid-breakpoints] - A map of breakpoints where the key is the name of the breakpoint and the value is the values for the breakpoint
47
+ /// @param {List} $breakpoint-names [map-keys($breakpoints)] - A list of names from the `$breakpoints` map
48
+ /// @return {String}
49
+ /// @access public
50
+ /// @group @octaviaflow/layout
51
+ @function breakpoint-prev(
52
+ $name,
53
+ $breakpoints: $grid-breakpoints,
54
+ $breakpoint-names: map.keys($breakpoints)
55
+ ) {
56
+ $n: list.index($breakpoint-names, $name);
57
+ @if $n != null and $n > 1 {
58
+ @return list.nth($breakpoint-names, $n - 1);
59
+ }
60
+ @return null;
61
+ }
62
+
63
+ /// Check to see if the given breakpoint name
64
+ /// @param {String} $name - The name of the breakpoint
65
+ /// @param {Map} $breakpoints [$grid-breakpoints] - A map of breakpoints where the key is the name of the breakpoint and the value is the values for the breakpoint
66
+ /// @return {Bool}
67
+ /// @access public
68
+ /// @group @octaviaflow/layout
69
+ @function is-smallest-breakpoint($name, $breakpoints: $grid-breakpoints) {
70
+ @return list.index(map.keys($breakpoints), $name) == 1;
71
+ }
72
+
73
+ /// Returns the largest breakpoint name
74
+ /// @param {Map} $breakpoints [$grid-breakpoints] - A map of breakpoints where the key is the name
75
+ /// @return {String}
76
+ /// @access public
77
+ /// @group @octaviaflow/layout
78
+ @function largest-breakpoint-name($breakpoints: $grid-breakpoints) {
79
+ $total-breakpoints: list.length($breakpoints);
80
+ @return -key-by-index($breakpoints, $total-breakpoints);
81
+ }
82
+
83
+ /// Get the infix for a given breakpoint in a list of breakpoints. Useful for generating the size part in a selector, for example: `.prefix--col-sm-2`.
84
+ /// @param {String} $name - The name of the breakpoint
85
+ /// @return {String}
86
+ /// @access public
87
+ /// @group @octaviaflow/layout
88
+ @function breakpoint-infix($name) {
89
+ @return '-#{$name}';
90
+ }
91
+
92
+ /// Generate a media query from the width of the given breakpoint to infinity
93
+ /// @param {String | Number} $name
94
+ /// @param {Map} $breakpoints [$grid-breakpoints] - A map of breakpoints where the key is the name
95
+ /// @content
96
+ /// @access public
97
+ /// @group @octaviaflow/layout
98
+ @mixin breakpoint-up($name, $breakpoints: $grid-breakpoints) {
99
+ @if meta.type-of($name) == 'number' {
100
+ @media (min-width: $name) {
101
+ @content;
102
+ }
103
+ } @else if map.has-key($breakpoints, $name) {
104
+ $breakpoint: map.get($breakpoints, $name);
105
+ $width: map.get($breakpoint, width);
106
+ @if is-smallest-breakpoint($name, $breakpoints) {
107
+ @content;
108
+ } @else {
109
+ @media (min-width: $width) {
110
+ @content;
111
+ }
112
+ }
113
+ } @else {
114
+ @error 'Unable to find a breakpoint with name `#{$name}`. Expected one of: (#{map.keys($breakpoints)})';
115
+ }
116
+ }
117
+
118
+ /// Generate a media query for the maximum width of the given styles
119
+ /// @param {String | Number} $name
120
+ /// @param {Map} $breakpoints [$grid-breakpoints] - A map of breakpoints where the key is the name
121
+ /// @content
122
+ /// @access public
123
+ /// @group @octaviaflow/layout
124
+ @mixin breakpoint-down($name, $breakpoints: $grid-breakpoints) {
125
+ @if meta.type-of($name) == 'number' {
126
+ @media (max-width: $name) {
127
+ @content;
128
+ }
129
+ } @else if map.has-key($breakpoints, $name) {
130
+ // We borrow this logic from bootstrap for specifying the value of the
131
+ // max-width. The maximum width is calculated by finding the breakpoint and
132
+ // subtracting .02 from its value. This value is used instead of .01 to
133
+ // avoid rounding issues in Safari
134
+ // https://github.com/twbs/bootstrap/blob/c5b1919deaf5393fcca9e9b9d7ce9c338160d99d/scss/mixins/_breakpoints.scss#L34-L46
135
+ $breakpoint: map.get($breakpoints, $name);
136
+ $width: map.get($breakpoint, width) - 0.02;
137
+ @media (max-width: $width) {
138
+ @content;
139
+ }
140
+ } @else {
141
+ @error 'Unable to find a breakpoint with name `#{$name}`. Expected one of: (#{map.keys($breakpoints)})';
142
+ }
143
+ }
144
+
145
+ /// Generate a media query for the range between the lower and upper breakpoints
146
+ /// @param {String | Number} $lower
147
+ /// @param {String | Number} $upper
148
+ /// @param {Map} $breakpoints [$grid-breakpoints] - A map of breakpoints where the key is the name
149
+ /// @content
150
+ /// @access public
151
+ /// @group @octaviaflow/layout
152
+ @mixin breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {
153
+ $is-number-lower: meta.type-of($lower) == 'number';
154
+ $is-number-upper: meta.type-of($upper) == 'number';
155
+ $min: null;
156
+ $max: null;
157
+
158
+ @if $is-number-lower {
159
+ $min: $lower;
160
+ } @else {
161
+ $min: map.get($breakpoints, $lower);
162
+ }
163
+
164
+ @if $is-number-upper {
165
+ $max: $upper;
166
+ } @else {
167
+ $max: map.get($breakpoints, $upper);
168
+ }
169
+
170
+ @if $min and $max {
171
+ $min-width: null;
172
+ $max-width: null;
173
+
174
+ @if not $is-number-lower and $min {
175
+ $min-width: map.get($min, width);
176
+ } @else {
177
+ $min-width: $min;
178
+ }
179
+
180
+ @if not $is-number-upper and $max {
181
+ $max-width: map.get($max, width);
182
+ } @else {
183
+ $max-width: $max;
184
+ }
185
+ @media (min-width: $min-width) and (max-width: $max-width) {
186
+ @content;
187
+ }
188
+ } @else if $min != null and $max == null {
189
+ @include breakpoint-up($lower) {
190
+ @content;
191
+ }
192
+ } @else if $min == null and $max != null {
193
+ @include breakpoint-down($upper) {
194
+ @content;
195
+ }
196
+ } @else {
197
+ @error 'Unable to find a breakpoint to satisfy: (#{$lower},#{$upper}). Expected both to be one of (#{map.keys($breakpoints)}).';
198
+ }
199
+ }
200
+
201
+ /// Generate media query for the largest breakpoint
202
+ /// @param {Map} $breakpoints [$grid-breakpoints] - A map of breakpoints where the key is the name
203
+ /// @content
204
+ /// @access public
205
+ /// @group @octaviaflow/layout
206
+ @mixin largest-breakpoint($breakpoints: $grid-breakpoints) {
207
+ @include breakpoint(largest-breakpoint-name()) {
208
+ @content;
209
+ }
210
+ }
211
+
212
+ /// Generate a media query for a given breakpoint
213
+ /// @param {String | Number} $name
214
+ /// @param {Map} $breakpoints [$grid-breakpoints] - A map of breakpoints where the key is the name
215
+ /// @content
216
+ /// @access public
217
+ /// @group @octaviaflow/layout
218
+ @mixin breakpoint($name, $breakpoints: $grid-breakpoints) {
219
+ @include breakpoint-up($name, $breakpoints) {
220
+ @content;
221
+ }
222
+ }
@@ -0,0 +1,94 @@
1
+ //
2
+ // Copyright OctaviaFlow. 2025
3
+ //
4
+ // This source code is licensed under the Apache-2.0 license found in the
5
+ // LICENSE file in the root directory of this source tree.
6
+ //
7
+
8
+ @use 'sass:map';
9
+ @use '@octaviaflow/layout/scss/convert';
10
+
11
+ /// Namespace prefix
12
+ /// @type String
13
+ /// @access public
14
+ /// @group @octaviaflow/grid
15
+ $prefix: 'cds' !default;
16
+
17
+ /// Total columns used in the flex grid
18
+ /// @type Number
19
+ /// @access public
20
+ /// @group @octaviaflow/grid
21
+ $flex-grid-columns: 16 !default;
22
+
23
+ /// Carbon gutter size in rem
24
+ /// @type Number
25
+ /// @access public
26
+ /// @group @octaviaflow/layout
27
+ $grid-gutter: convert.to-rem(32px) !default;
28
+
29
+ /// Carbon condensed gutter size in rem
30
+ /// @type Number
31
+ /// @access public
32
+ /// @group @octaviaflow/layout
33
+ $grid-gutter-condensed: convert.to-rem(1px) !default;
34
+
35
+ // Initial map of our breakpoints and their values
36
+ /// @type Map
37
+ /// @access public
38
+ /// @group @octaviaflow/layout
39
+ $grid-breakpoints: (
40
+ sm: (
41
+ columns: 4,
42
+ margin: 0,
43
+ width: convert.to-rem(320px),
44
+ ),
45
+ md: (
46
+ columns: 8,
47
+ margin: convert.to-rem(16px),
48
+ width: convert.to-rem(672px),
49
+ ),
50
+ lg: (
51
+ columns: 16,
52
+ margin: convert.to-rem(16px),
53
+ width: convert.to-rem(1056px),
54
+ ),
55
+ xlg: (
56
+ columns: 16,
57
+ margin: convert.to-rem(16px),
58
+ width: convert.to-rem(1312px),
59
+ ),
60
+ max: (
61
+ columns: 16,
62
+ margin: convert.to-rem(24px),
63
+ width: convert.to-rem(1584px),
64
+ ),
65
+ ) !default;
66
+
67
+ @if $flex-grid-columns == 12 {
68
+ $grid-breakpoints: map.merge(
69
+ $grid-breakpoints,
70
+ (
71
+ lg:
72
+ map.merge(
73
+ map.get($grid-breakpoints, lg),
74
+ (
75
+ columns: 12,
76
+ )
77
+ ),
78
+ xlg:
79
+ map.merge(
80
+ map.get($grid-breakpoints, xlg),
81
+ (
82
+ columns: 12,
83
+ )
84
+ ),
85
+ max:
86
+ map.merge(
87
+ map.get($grid-breakpoints, max),
88
+ (
89
+ columns: 12,
90
+ )
91
+ ),
92
+ )
93
+ );
94
+ }