Skip to content

Commit 92b30b6

Browse files
committed
v1.0.0
0 parents  commit 92b30b6

File tree

4 files changed

+339
-0
lines changed

4 files changed

+339
-0
lines changed

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2017 Zsolt Pentz
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.

README.md

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
# sass-recursive-map-merge
2+
3+
A lightweight Sass function that merges multidimensional maps recursively.
4+
5+
## Motivation
6+
7+
[Sass](http://sass-lang.com/) introduced the [map data type](http://sass-lang.com/documentation/file.SASS_REFERENCE.html#Maps) in [version 3.3.0](https://github.com/sass/sass/releases/tag/3.3.0) and _it is awesome_. Maps come with a [wide variety of functions](http://sass-lang.com/documentation/Sass/Script/Functions.html#map-functions) and they help developers store data in a more maintainable and perhaps more meaningful way as opposed to simple variables.
8+
9+
I find though that the built-in functions fall short when working with multidimensional maps. Consider you have the following maps and you want to merge them.
10+
11+
```scss
12+
$colors1: (
13+
primary: (
14+
light: #f66124,
15+
dark: #ad3707
16+
)
17+
);
18+
19+
$colors2: (
20+
primary: (
21+
base: #de4709
22+
)
23+
);
24+
```
25+
26+
Using [`map-merge()`](http://sass-lang.com/documentation/Sass/Script/Functions.html#map_merge-instance_method), the result depends on the order of the parameters. According to the specification:
27+
28+
>Keys in `$map2` will take precedence over keys in `$map1`.
29+
30+
`$map1` is the first and `$map2` is the second parameter. This means that we can merge our previous maps in two different ways using `map-merge()`.
31+
32+
```scss
33+
$colors1: (
34+
primary: (
35+
light: #f66124,
36+
dark: #ad3707
37+
)
38+
);
39+
40+
$colors2: (
41+
primary: (
42+
base: #de4709
43+
)
44+
);
45+
46+
$mergedcolors1: map-merge($colors1, $colors2);
47+
48+
//$mergedcolors1: (
49+
// primary: (
50+
// base: #de4709
51+
// )
52+
//);
53+
54+
$mergedcolors2: map-merge($colors2, $colors1);
55+
56+
//$mergedcolors2: (
57+
// primary: (
58+
// light: #f66124,
59+
// dark: #ad3707
60+
// )
61+
//);
62+
```
63+
64+
Either way, we get back one of the original maps, which is the expected behavior. `map-merge()` goes through the keys of each map, checks whether they exist in both maps or not. Unique keys are added to the returned map, and in cases where the key exists in both maps, the key from the second map is added to the returned map.
65+
66+
However, I wanted to get this result:
67+
68+
```scss
69+
$colors1: (
70+
primary: (
71+
light: #f66124,
72+
dark: #ad3707
73+
)
74+
);
75+
76+
$colors2: (
77+
primary: (
78+
base: #de4709
79+
)
80+
);
81+
82+
$colors: recursive-map-merge($colors1, $colors2);
83+
84+
//$colors: (
85+
// primary: (
86+
// light: #f66124,
87+
// dark: #ad3707,
88+
// base: #de4709
89+
// )
90+
//);
91+
```
92+
93+
I created `recursive-map-merge()` to merge multidimensional maps in a way that map data types contained within the merging maps also get merged.
94+
95+
## Getting Started
96+
97+
### Prerequisites
98+
99+
This Sass function runs on Sass version 3.3.0 or higher. It has no dependencies and can be used in any kind of Sass code.
100+
101+
The code is currently published on [npm](https://www.npmjs.com/), a package manager for [Node.js](https://nodejs.org/en/), so make sure both of them are installed on your computer for easy use. You can download an installer for your operating system on the [Downloads page of Node.js](https://nodejs.org/en/download/).
102+
103+
### Installing
104+
105+
#### Via [npm](https://www.npmjs.com/)
106+
107+
In order to get a copy, all you need to do is install the package in your own [npm](https://www.npmjs.com/) project.
108+
109+
```
110+
npm install sass-recursive-map-merge
111+
```
112+
113+
After this, the source will be downloaded into the project's `node_modules` folder. From there, you can simply include the code in your own codebase using Sass' `@import` directive.
114+
115+
If your project depends on Sass to create CSS code, it is recommended to save this package in your project's `package.json` file.
116+
117+
```
118+
npm install sass-recursive-map-merge --save-dev
119+
```
120+
121+
However, if you happen to use this code in a project which is for instance a Sass framework and you want to include this work in that framework, save the package as a dependency.
122+
123+
```
124+
npm install sass-recursive-map-merge --save
125+
```
126+
127+
#### Copying the source
128+
129+
Although I personally do not recommend doing this, but you can simply download the source file from this repository and use it in your project that way. Note however, that [npm](https://www.npmjs.com/) makes updating packages a breeze and you should probably use it anyway.
130+
131+
## Usage
132+
133+
### Parameters
134+
135+
`recursive-map-merge()` expects two parameters:
136+
137+
* `$map1` (map)
138+
* `$map2` (map)
139+
140+
### Return value
141+
142+
* `$result` (map)
143+
144+
### Raises
145+
146+
* Warning, if the type of one of the parameters is not map.
147+
148+
### Example
149+
150+
This function works best in a scenario where you have some sort of base variables and want to extend that collection in different cases. If you maintain style sheets of multiple sites that are similar in how they look, but have their own brand as well, and you want to share those base variables between multiple style sheets and want to extend them with the specific ones, `recursive-map-merge()` can prove to be very useful.
151+
152+
In the following scenario, we have three different shades of neutral colors and a success color in our base colors and we want to extend the neutral colors with a new shade for the specific colors and also add the primary colors to the final colors.
153+
154+
```scss
155+
$base-colors: (
156+
neutral: (
157+
light: white,
158+
base: gray,
159+
dark: black
160+
),
161+
success: (
162+
base: #007b39
163+
)
164+
);
165+
166+
$specific-colors: (
167+
neutral: (
168+
mid-light: lightgray
169+
),
170+
primary: (
171+
light: lightblue,
172+
base: blue,
173+
dark: darkblue
174+
)
175+
);
176+
177+
$colors: recursive-map-merge($base-colors, $specific-colors);
178+
179+
//$colors: (
180+
// neutral: (
181+
// light: white,
182+
// mid-light: lightgray
183+
// base: gray,
184+
// dark: black
185+
// ),
186+
// success: (
187+
// base: #007b39
188+
// ),
189+
// primary: (
190+
// light: lightblue,
191+
// base: blue,
192+
// dark: darkblue
193+
// )
194+
//);
195+
```
196+
197+
`recursive-map-merge()` is capable of dealing with maps that are more than two dimensional. The following example deals with sizes in a similar scenario than with colors before, but with three dimensional maps.
198+
199+
200+
```scss
201+
$base-sizes: (
202+
gutter: (
203+
mobile: (
204+
small: 10px,
205+
base: 20px,
206+
large: 30px
207+
),
208+
desktop: (
209+
small: 15px,
210+
base: 30px,
211+
large: 45px
212+
)
213+
)
214+
);
215+
216+
$specific-sizes: (
217+
gutter: (
218+
mobile: (
219+
x-large: 40px
220+
),
221+
tablet: (
222+
small: 12px,
223+
base: 24px,
224+
large: 36px,
225+
x-large: 48px
226+
),
227+
desktop: (
228+
x-large: 60px
229+
)
230+
)
231+
);
232+
233+
$sizes: recursive-map-merge($base-sizes, $specific-sizes);
234+
235+
//$sizes: (
236+
// gutter: (
237+
// mobile: (
238+
// small: 10px,
239+
// base: 20px,
240+
// large: 30px,
241+
// x-large: 40px
242+
// ),
243+
// tablet: (
244+
// small: 12px,
245+
// base: 24px,
246+
// large: 36px,
247+
// x-large: 48px
248+
// ),
249+
// desktop: (
250+
// small: 15px,
251+
// base: 30px,
252+
// large: 45px,
253+
// x-large: 60px
254+
// )
255+
// )
256+
//);
257+
```
258+
259+
## Contributing
260+
261+
Questions and feedback are welcome. If you have anything to add, found a bug or a spelling error, or just want to start a discussion about this project, feel free to [open an issue on GitHub](https://github.com/pentzzsolt/sass-recursive-map-merge/issues).
262+
263+
## Versioning
264+
265+
We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/pentzzsolt/sass-recursive-map-merge/tags).
266+
267+
## Authors
268+
269+
* **Zsolt Pentz** - *Initial work* - [pentzzsolt](https://github.com/pentzzsolt)
270+
271+
## License
272+
273+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details
274+
275+
## Acknowledgments
276+
277+
* Big thank you to [PurpleBooth](https://github.com/PurpleBooth) for [this lovely README template](https://gist.github.com/PurpleBooth/109311bb0361f32d87a2)!

_recursive-map-merge.scss

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
@function recursive-map-merge($map1, $map2) {
2+
@if (type-of($map1) == map and type-of($map2) == map) {
3+
$result: $map1;
4+
@each $key, $value in $map2 {
5+
@if (type-of(map-get($result, $key)) == map and type-of($value) == map) {
6+
$result: map-merge($result, ($key: recursive-map-merge(map-get($result, $key), $value)));
7+
}
8+
@else {
9+
$result: map-merge($result, ($key: $value));
10+
}
11+
}
12+
@return $result;
13+
}
14+
@else {
15+
@warn 'recursive-map-merge() expects it\'s parameters to be map types!';
16+
@return null;
17+
}
18+
}

package.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "sass-recursive-map-merge",
3+
"version": "1.0.0",
4+
"description": "A lightweight Sass function that merges multidimensional maps recursively.",
5+
"repository": {
6+
"type": "git",
7+
"url": "git+https://github.com/pentzzsolt/sass-recursive-map-merge.git"
8+
},
9+
"keywords": [
10+
"sass",
11+
"sass-functions",
12+
"sass-function",
13+
"scss",
14+
"scss-functions",
15+
"scss-function"
16+
],
17+
"author": "Zsolt Pentz <[email protected]> (https://pentzzsolt.github.io)",
18+
"license": "MIT",
19+
"bugs": {
20+
"url": "https://github.com/pentzzsolt/sass-recursive-map-merge/issues"
21+
},
22+
"homepage": "https://github.com/pentzzsolt/sass-recursive-map-merge#readme"
23+
}

0 commit comments

Comments
 (0)