Skip to content

Commit

Permalink
feat: add style injection for modules in functional components (#92)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremyzahner authored and eddyerburgh committed May 22, 2018
1 parent e694fc7 commit 4c74e43
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 7 deletions.
25 changes: 20 additions & 5 deletions lib/process.js
Expand Up @@ -104,11 +104,26 @@ module.exports = function (src, filePath, jestConfig) {
.join('')

if (styleStr.length !== 0) {
output += '\n;(function() {' +
'\nvar beforeCreate = __vue__options__.beforeCreate' +
'\nvar styleFn = function () { ' + styleStr + ' }' +
'\n__vue__options__.beforeCreate = beforeCreate ? [].concat(beforeCreate, styleFn) : [styleFn]' +
'\n})()'
if (parts.template.attrs.functional) {
output += `
;(function() {
var originalRender = __vue__options__.render
var styleFn = function () { ${styleStr} }
__vue__options__.render = function renderWithStyleInjection (h, context) {
styleFn.call(context)
return originalRender(h, context)
}
})()
`
} else {
output += `
;(function() {
var beforeCreate = __vue__options__.beforeCreate
var styleFn = function () { ${styleStr} }
__vue__options__.beforeCreate = beforeCreate ? [].concat(beforeCreate, styleFn) : [styleFn]
})()
`
}
}
}

Expand Down
25 changes: 25 additions & 0 deletions test/resources/SassModuleFunctional.vue
@@ -0,0 +1,25 @@
<template functional>
<div>
<div :class="$style.testAFunctional"></div>
<div :class="[ $style.testAFunctional ]"></div>
<div :class="{[$style.testBFunctional]: true }"></div>
<div :class="[$style.testAFunctional, { [$style.testBFunctional]: true }]"></div>
<div :class="[$otherStyle.otherTestAFunctional, { [$otherStyle.otherTestBFunctional]: true }]"></div>
</div>
</template>

<style module lang="sass">
.testAFunctional
background-color: red
.testBFunctional
background-color: blue
</style>

<style module="$otherStyle" lang="scss">
.otherTestAFunctional {
background-color: red;
}
.otherTestBFunctional {
background-color: blue;
}
</style>
34 changes: 34 additions & 0 deletions test/resources/ScssModuleFunctional.vue
@@ -0,0 +1,34 @@
<script>
export default {
name: 'ScssModuleFunctional',
functional: true,
}
</script>

<template functional>
<div>
<div :class="$style.testAFunctional"></div>
<div :class="[ $style.testAFunctional ]"></div>
<div :class="{[$style.testBFunctional]: true }"></div>
<div :class="[$style.testAFunctional, { [$style.testBFunctional]: true }]"></div>
<div :class="[$otherStyle.otherTestAFunctional, { [$otherStyle.otherTestBFunctional]: true }]"></div>
</div>
</template>

<style module lang="scss">
.testAFunctional {
background-color: red;
}
.testBFunctional {
background-color: blue;
}
</style>

<style module="$otherStyle" lang="scss">
.otherTestAFunctional {
background-color: red;
}
.otherTestBFunctional {
background-color: blue;
}
</style>
17 changes: 16 additions & 1 deletion test/sass.spec.js
@@ -1,6 +1,7 @@
import { shallow } from 'vue-test-utils'
import { shallow, mount } from 'vue-test-utils'
import Sass from './resources/Sass.vue'
import SassModule from './resources/SassModule.vue'
import SassModuleFunctional from './resources/SassModuleFunctional.vue'

describe('processes .vue file with sass style', () => {
it('does not error on sass', () => {
Expand All @@ -9,13 +10,20 @@ describe('processes .vue file with sass style', () => {
it('does not error on sass module', () => {
expect(() => shallow(SassModule)).not.toThrow()
})
it('does not error on sass module when functional', () => {
expect(() => mount(SassModuleFunctional)).not.toThrow()
})
})

describe('processes .vue files which combine sass and modules', () => {
let wrapper
let functionalWrapper

beforeEach(() => {
wrapper = shallow(SassModule)
functionalWrapper = mount(SassModuleFunctional)
})

it('does inject classes to $style', () => {
expect(wrapper.vm.$style).toBeDefined()
expect(wrapper.vm.$style.testA).toBeDefined()
Expand All @@ -24,6 +32,13 @@ describe('processes .vue files which combine sass and modules', () => {
expect(wrapper.vm.$style.testB).toEqual('testB')
})

it('does inject classes to $style for functional components', () => {
expect(functionalWrapper.findAll('.testAFunctional')).toHaveLength(3)
expect(functionalWrapper.findAll('.testBFunctional')).toHaveLength(2)
expect(functionalWrapper.findAll('.otherTestAFunctional')).toHaveLength(1)
expect(functionalWrapper.findAll('.otherTestBFunctional')).toHaveLength(1)
})

describe('entrypoint: direct import in SFC', () => {
let wrapper
beforeEach(() => {
Expand Down
17 changes: 16 additions & 1 deletion test/scss.spec.js
@@ -1,6 +1,7 @@
import { shallow } from 'vue-test-utils'
import { shallow, mount } from 'vue-test-utils'
import Scss from './resources/Scss.vue'
import ScssModule from './resources/ScssModule.vue'
import ScssModuleFunctional from './resources/ScssModuleFunctional.vue'

describe('processes .vue file with scss style', () => {
it('does not error on scss', () => {
Expand All @@ -9,13 +10,20 @@ describe('processes .vue file with scss style', () => {
it('does not error on scss module', () => {
expect(() => shallow(ScssModule)).not.toThrow()
})
it('does not error on scss module when functional', () => {
expect(() => mount(ScssModuleFunctional)).not.toThrow()
})
})

describe('processes .vue files which combine scss and modules', () => {
let wrapper
let functionalWrapper

beforeEach(() => {
wrapper = shallow(ScssModule)
functionalWrapper = mount(ScssModuleFunctional)
})

it('does inject classes to $style', () => {
expect(wrapper.vm.$style).toBeDefined()
expect(wrapper.vm.$style.testA).toBeDefined()
Expand All @@ -24,6 +32,13 @@ describe('processes .vue files which combine scss and modules', () => {
expect(wrapper.vm.$style.testB).toEqual('testB')
})

it('does inject classes to $style for functional components', () => {
expect(functionalWrapper.findAll('.testAFunctional')).toHaveLength(3)
expect(functionalWrapper.findAll('.testBFunctional')).toHaveLength(2)
expect(functionalWrapper.findAll('.otherTestAFunctional')).toHaveLength(1)
expect(functionalWrapper.findAll('.otherTestBFunctional')).toHaveLength(1)
})

describe('entrypoint: direct import in SFC', () => {
let wrapper
beforeEach(() => {
Expand Down

0 comments on commit 4c74e43

Please sign in to comment.