-
-
Notifications
You must be signed in to change notification settings - Fork 392
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(components): add textarea (#440)
closes #435
- Loading branch information
1 parent
1409c41
commit d104951
Showing
3 changed files
with
453 additions
and
0 deletions.
There are no files selected for viewing
118 changes: 118 additions & 0 deletions
118
src/app/shared/components/VueTextarea/VueTextarea.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import { createLocalVue, mount } from '@vue/test-utils'; | ||
import VueTextarea from './VueTextarea.vue'; | ||
|
||
const localVue = createLocalVue(); | ||
|
||
describe('VueTextarea.vue', () => { | ||
test('renders component', () => { | ||
const wrapper = mount<any>(VueTextarea, { | ||
localVue, | ||
propsData: { | ||
message: 'MESSAGE!', | ||
name: 'name', | ||
id: 'id', | ||
}, | ||
mocks: { | ||
errors: null, | ||
}, | ||
}); | ||
|
||
expect(wrapper.findAll(`.vueTextarea`)).toHaveLength(1); | ||
expect(wrapper.find(`.message`).text()).toBe('MESSAGE!'); | ||
}); | ||
|
||
test('renders disabled component', () => { | ||
const wrapper = mount<any>(VueTextarea, { | ||
localVue, | ||
propsData: { | ||
disabled: true, | ||
name: 'name', | ||
id: 'id', | ||
}, | ||
}); | ||
|
||
expect(wrapper.findAll(`.disabled`)).toHaveLength(1); | ||
}); | ||
|
||
test('should emit input', () => { | ||
const wrapper = mount<any>(VueTextarea, { | ||
localVue, | ||
propsData: { | ||
name: 'name', | ||
id: 'id', | ||
}, | ||
}) as any; | ||
|
||
wrapper.find('input').trigger('input'); | ||
expect(wrapper.emitted('input')).toBeTruthy(); | ||
}); | ||
|
||
test('should display error state', () => { | ||
const wrapper = mount<any>(VueTextarea, { | ||
localVue, | ||
mocks: { | ||
errors: { | ||
first() { | ||
return true; | ||
}, | ||
}, | ||
}, | ||
propsData: { | ||
errorMessage: 'ERROR!', | ||
name: 'name', | ||
id: 'id', | ||
}, | ||
}); | ||
|
||
expect(wrapper.findAll(`.error`)).toHaveLength(1); | ||
expect(wrapper.find(`.message`).text()).toBe('ERROR!'); | ||
}); | ||
|
||
test('autofocus fallback', () => { | ||
const wrapper = mount<any>(VueTextarea, { | ||
localVue, | ||
propsData: { | ||
name: 'name', | ||
id: 'id', | ||
autofocus: true, | ||
}, | ||
}); | ||
|
||
expect(wrapper.vm.observer).toBeNull(); | ||
}); | ||
|
||
test('autofocus in modern browsers', () => { | ||
(window as any).IntersectionObserver = class IntersectionObserver { | ||
public cb: any; | ||
public options: any; | ||
|
||
constructor(cb: any, options: any) { | ||
this.cb = cb; | ||
this.options = options; | ||
} | ||
|
||
public observe() { | ||
this.cb(); | ||
} | ||
}; | ||
const wrapper = mount<any>(VueTextarea, { | ||
localVue, | ||
propsData: { | ||
name: 'name', | ||
id: 'id', | ||
autofocus: false, | ||
}, | ||
}); | ||
|
||
wrapper.vm.$refs.input.focus = jest.fn(); | ||
|
||
expect(wrapper.vm.observer).not.toBeNull(); | ||
expect(wrapper.vm.$refs.input.focus).not.toHaveBeenCalled(); | ||
|
||
wrapper.setProps({ autofocus: true }); | ||
wrapper.vm.observer.observe(); | ||
expect(wrapper.vm.$refs.input.focus).toHaveBeenCalled(); | ||
|
||
wrapper.destroy(); | ||
}); | ||
}); |
93 changes: 93 additions & 0 deletions
93
src/app/shared/components/VueTextarea/VueTextarea.stories.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import { storiesOf } from '@storybook/vue'; | ||
import { withInfo } from 'storybook-addon-vue-info'; | ||
import VueTextarea from './VueTextarea.vue'; | ||
import VueButton from '../VueButton/VueButton.vue'; | ||
import VueModal from '../VueModal/VueModal.vue'; | ||
|
||
const story = storiesOf('Atoms|Textarea', module) as any; | ||
|
||
story.add( | ||
'Default', | ||
withInfo({})(() => ({ | ||
components: { VueTextarea }, | ||
data() { | ||
return { | ||
model: '', | ||
}; | ||
}, | ||
template: `<vue-textarea placeholder="Name" name="name" id="name" v-model="model" />`, | ||
})), | ||
); | ||
|
||
story.add( | ||
'Disabled', | ||
withInfo({})(() => ({ | ||
components: { VueTextarea }, | ||
data() { | ||
return { | ||
model: '', | ||
}; | ||
}, | ||
template: `<vue-textarea placeholder="Name" name="name" id="name" v-model="model" :disabled="true" />`, | ||
})), | ||
); | ||
|
||
story.add( | ||
'Hint', | ||
withInfo({})(() => ({ | ||
components: { VueTextarea }, | ||
data() { | ||
return { | ||
model: '', | ||
}; | ||
}, | ||
template: `<vue-textarea placeholder="Name" name="name" id="name" v-model="model" message="description" />`, | ||
})), | ||
); | ||
|
||
story.add( | ||
'Validation/Error state', | ||
withInfo({})(() => ({ | ||
components: { VueTextarea }, | ||
data() { | ||
return { | ||
model: '', | ||
}; | ||
}, | ||
template: `<vue-textarea placeholder="Name" name="name" id="name" v-model="model" validation="required|integer" required message="please enter a number" errorMessage="This is not a number" />`, | ||
})), | ||
); | ||
|
||
story.add( | ||
'Readonly', | ||
withInfo({})(() => ({ | ||
components: { VueTextarea }, | ||
data() { | ||
return { | ||
model: '', | ||
}; | ||
}, | ||
template: `<vue-textarea placeholder="Name" name="name" id="name" value="foo" readonly />`, | ||
})), | ||
); | ||
|
||
story.add( | ||
'SPA autofocus', | ||
withInfo({ propTablesExclude: [VueButton, VueModal] })(() => ({ | ||
components: { VueTextarea, VueButton, VueModal }, | ||
data() { | ||
return { | ||
model: '', | ||
show: false, | ||
}; | ||
}, | ||
template: `<div> | ||
<vue-button @click="show = !show" color="primary">Login</vue-button> | ||
<vue-modal :show="show" @close="show = false"> | ||
<vue-textarea autofocus placeholder="Name" name="name" id="name" v-model="model" /> | ||
<vue-button ghost @click="show = !show">Close</vue-button> | ||
</vue-modal> | ||
</div>`, | ||
})), | ||
); |
Oops, something went wrong.