@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.
package/README.md ADDED
@@ -0,0 +1,106 @@
1
+ # @octaviaflow/grid
2
+
3
+ > Grid for digital and software products using the Carbon Design System
4
+
5
+ ## Getting started
6
+
7
+ To install `@octaviaflow/grid` in your project, you will need to run the following
8
+ command using [npm](https://www.npmjs.com/):
9
+
10
+ ```bash
11
+ npm install -S @octaviaflow/grid
12
+ ```
13
+
14
+ If you prefer [Yarn](https://yarnpkg.com/en/), use the following command
15
+ instead:
16
+
17
+ ```bash
18
+ yarn add @octaviaflow/grid
19
+ ```
20
+
21
+ You can then include the grid by doing the following in your Sass files:
22
+
23
+ ```
24
+ @use '@octaviaflow/grid';
25
+
26
+ // Emit the flex-grid styles
27
+ @include grid.flex-grid();
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ _More examples and documentation can be found on this
33
+ [live demo website](https://carbon-elements.netlify.app/grid/examples/preview/)._
34
+
35
+ `@octaviaflow/grid` has three primitive class types to use in order to structure your
36
+ application. They include:
37
+
38
+ - `cds--grid`, defines the overall grid context and sets some useful attributes
39
+ like width and margin
40
+ - `cds--row`, defines a row of items in a grid
41
+ - `cds--col`, used to define individual columns
42
+
43
+ You can use a combination of these classes to build a layout. For example, if we
44
+ wanted a 4 column layout for a small breakpoint we could use the following
45
+ markup:
46
+
47
+ ```html
48
+ <div class="cds--grid">
49
+ <div class="cds--row">
50
+ <div class="cds--col">1/4</div>
51
+ <div class="cds--col">1/4</div>
52
+ <div class="cds--col">1/4</div>
53
+ <div class="cds--col">1/4</div>
54
+ </div>
55
+ </div>
56
+ ```
57
+
58
+ While this layout can work for some grid usage scenarios, we probably will want
59
+ more control over how many columns our layout will span at each given
60
+ breakpoint.
61
+
62
+ By default, `@octaviaflow/grid` uses the breakpoints defined in `@octaviaflow/layout`.
63
+ There are five breakpoints: `sm`, `md`, `lg`, `xlg`, and `max`. You can use each
64
+ one in combination with a column to specify the number of columns to span at a
65
+ given breakpoint. For example, we could rewrite the above example to be:
66
+
67
+ ```html
68
+ <div class="cds--grid">
69
+ <div class="cds--row">
70
+ <div class="cds--col-sm-1">1/4</div>
71
+ <div class="cds--col-sm-1">1/4</div>
72
+ <div class="cds--col-sm-1">1/4</div>
73
+ <div class="cds--col-sm-1">1/4</div>
74
+ </div>
75
+ </div>
76
+ ```
77
+
78
+ The `.cds--col-sm-1` class names tells us that this `<div>` should only span one
79
+ column at our `sm` breakpoint. By default, as we scale beyond the breakpoint the
80
+ layout will still take up a percentage of the overall width.
81
+
82
+ ## 📚 Examples
83
+
84
+ If you're looking for more examples on how to use `@octaviaflow/grid`, we have some
85
+ examples that you can check out:
86
+
87
+ - [css-grid](./examples/css-grid)
88
+
89
+ ## 🙌 Contributing
90
+
91
+ We're always looking for contributors to help us fix bugs, build new features,
92
+ or help us improve the project documentation. If you're interested, definitely
93
+ check out our [Contributing Guide](/.github/CONTRIBUTING.md)! 👀
94
+
95
+ ## 📝 License
96
+
97
+ Licensed under the [Apache 2.0 License](/LICENSE).
98
+
99
+ ## <picture><source height="20" width="20" media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/ibm-telemetry/telemetry-js/main/docs/images/ibm-telemetry-dark.svg"><source height="20" width="20" media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/ibm-telemetry/telemetry-js/main/docs/images/ibm-telemetry-light.svg"><img height="20" width="20" alt="IBM Telemetry" src="https://raw.githubusercontent.com/ibm-telemetry/telemetry-js/main/docs/images/ibm-telemetry-light.svg"></picture> IBM Telemetry
100
+
101
+ This package uses IBM Telemetry to collect de-identified and anonymized metrics
102
+ data. By installing this package as a dependency you are agreeing to telemetry
103
+ collection. To opt out, see
104
+ [Opting out of IBM Telemetry data collection](https://github.com/ibm-telemetry/telemetry-js/tree/main#opting-out-of-ibm-telemetry-data-collection).
105
+ For more information on the data being collected, please see the
106
+ [IBM Telemetry documentation](https://github.com/ibm-telemetry/telemetry-js/tree/main#ibm-telemetry-collection-basics).
package/index.scss ADDED
@@ -0,0 +1,11 @@
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
+ @forward 'scss/config';
9
+ @forward 'scss/breakpoint';
10
+ @forward 'scss/css-grid';
11
+ @forward 'scss/flex-grid';
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@octaviaflow/grid",
3
+ "description": "Grid for digital and software products using the OctaviaFlow Design System",
4
+ "version": "1.0.0",
5
+ "license": "Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/octaviaflow-design-system.git",
9
+ "directory": "packages/grid"
10
+ },
11
+ "bugs": "https://github.com/octaviaflow-design-system/issues",
12
+ "files": [
13
+ "css",
14
+ "scss",
15
+ "index.scss",
16
+ "telemetry.yml"
17
+ ],
18
+ "keywords": [
19
+ "octaviaflow",
20
+ "octaviaflow-design-system",
21
+ "grid",
22
+ "react",
23
+ "components",
24
+ "react"
25
+ ],
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "scripts": {
30
+ "build": "bun run clean && octaviaflow-cli inline && octaviaflow-cli check \"scss/*.scss\"",
31
+ "clean": "rimraf scss/_inlined scss/vendor"
32
+ },
33
+ "dependencies": {
34
+ "@octaviaflow/layout": "^1.0.0"
35
+ },
36
+ "devDependencies": {
37
+ "@octaviaflow/cli": "^1.0.0",
38
+ "rimraf": "^6.0.0"
39
+ },
40
+ "eyeglass": {
41
+ "exports": false,
42
+ "name": "@octaviaflow/grid",
43
+ "sassDir": "scss",
44
+ "needs": "^1.3.0"
45
+ }
46
+ }
@@ -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
+ }