Improve v-focus (#164)

This commit is contained in:
Rijk van Zanten
2020-03-11 17:02:45 -04:00
committed by GitHub
parent 8bdccf222a
commit 35cdf08130
6 changed files with 35 additions and 19 deletions

View File

@@ -5,3 +5,10 @@ The focus directive is basically `autofocus`, but works in Vue. Because of the w
```html
<v-input v-focus />
```
## Value
You can pass it a boolean value if you need more fine grained control over when focus is set:
```html
<v-input v-focus="active" />
```

View File

@@ -2,6 +2,7 @@ import Vue from 'vue';
import VInput from '../../components/v-input';
import Focus from './focus';
import markdown from './focus.readme.md';
import { defineComponent } from '@vue/composition-api';
import withPadding from '../../../.storybook/decorators/with-padding';
Vue.component('v-input', VInput);
@@ -9,19 +10,19 @@ Vue.directive('focus', Focus);
export default {
title: 'Directives / Focus',
component: VInput,
decorators: [withPadding],
parameters: {
notes: markdown
}
};
export const withText = () => ({
template: `
<div style="display: flex; justify-content: space-around; flex-direction: column; align-items: center">
<v-input style="margin-bottom: 20px;" />
<v-input style="margin-bottom: 20px;" />
<v-input v-focus style="margin-bottom: 20px;" />
</div>
`
});
export const withText = () =>
defineComponent({
template: `
<div style="display: flex; justify-content: space-around; flex-direction: column; align-items: center">
<v-input style="margin-bottom: 20px;" />
<v-input autofocus style="margin-bottom: 20px;" />
<v-input style="margin-bottom: 20px;" />
</div>
`
});

View File

@@ -1,11 +1,15 @@
import Focus from './focus';
describe('Directives / Focus', () => {
it('Calls focus() on the element on insertion', () => {
it('Calls focus() on the element if binding is truthy', () => {
const el = { focus: jest.fn() };
// I don't care about the exact types of this Vue internal function. We just want to make
// sure `focus()` is being called on `el`.
Focus.inserted!(el as any, null as any, null as any, null as any);
Focus.inserted!(el as any, { value: true } as any, null as any, null as any);
expect(el.focus).toHaveBeenCalled();
});
it('Calls blur() on the element if binding is false', () => {
const el = { blur: jest.fn() };
Focus.inserted!(el as any, { value: false } as any, null as any, null as any);
expect(el.blur).toHaveBeenCalled();
});
});

View File

@@ -1,8 +1,12 @@
import { DirectiveOptions } from 'vue';
const Focus: DirectiveOptions = {
inserted(el) {
el.focus();
inserted(el, binding) {
if (binding.value) {
el.focus();
} else {
el.blur();
}
}
};

View File

@@ -4,7 +4,7 @@ import Vue from 'vue';
import InterfaceTextInput from './text-input.vue';
import markdown from './readme.md';
import withPadding from '../../../.storybook/decorators/with-padding';
import { createComponent } from '@vue/composition-api';
import { defineComponent } from '@vue/composition-api';
Vue.component('interface-text-input', InterfaceTextInput);
@@ -17,7 +17,7 @@ export default {
};
export const basic = () =>
createComponent({
defineComponent({
props: {
monospace: {
default: boolean('Monospace', false, 'Options')

View File

@@ -1,7 +1,7 @@
<template>
<public-view>
<form @submit.prevent="onSubmit">
<v-input type="email" v-model="email" />
<v-input autofocus type="email" v-model="email" />
<v-input type="password" v-model="password" />
<v-button type="submit" :loading="loggingIn">Login</v-button>
</form>