Skip to content

Commit 413cd38

Browse files
committed
theme spreads
1 parent 1cec6ab commit 413cd38

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

src/components/themr.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,21 @@ export default (componentName, localTheme, options = {}) => (ThemedComponent) =>
152152
return Themed
153153
}
154154

155-
export function themeable(original = {}, mixin = {}) {
155+
/**
156+
* Merges passed themes by concatenating string keys and processing nested themes
157+
* @param {...TReactCSSThemrTheme} themes - Themes
158+
* @returns {TReactCSSThemrTheme} - Resulting theme
159+
*/
160+
export function themeable(...themes) {
161+
return themes.reduce((acc, theme) => merge(acc, theme), {})
162+
}
163+
164+
/**
165+
* @param {TReactCSSThemrTheme} [original] - Original theme
166+
* @param {TReactCSSThemrTheme} [mixin] - Mixin theme
167+
* @returns {TReactCSSThemrTheme} - resulting theme
168+
*/
169+
function merge(original = {}, mixin = {}) {
156170
//make a copy to avoid mutations of nested objects
157171
//also strip all functions injected by isomorphic-style-loader
158172
const result = Object.keys(original).reduce((acc, key) => {
@@ -175,7 +189,7 @@ export function themeable(original = {}, mixin = {}) {
175189
switch (typeof originalValue) {
176190
case 'object': {
177191
//exactly nested theme object - go recursive
178-
result[key] = themeable(originalValue, mixinValue)
192+
result[key] = merge(originalValue, mixinValue)
179193
break
180194
}
181195

test/components/themr.spec.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,4 +588,23 @@ describe('themeable function', () => {
588588
}
589589
expect(() => themeable(themeA, themeB)).toThrow()
590590
})
591+
592+
it('should support theme spreads', () => {
593+
const a = {
594+
test: 'a'
595+
}
596+
const b = {
597+
test: 'b'
598+
}
599+
const c = {
600+
test: 'foo',
601+
foo: 'foo'
602+
}
603+
const expected = {
604+
test: 'a b foo',
605+
foo: 'foo'
606+
}
607+
const result = themeable(a, b, c)
608+
expect(result).toEqual(expected)
609+
})
591610
})

0 commit comments

Comments
 (0)