Skip to content

Commit

Permalink
feat(dialog): default button support (#56)
Browse files Browse the repository at this point in the history
* feat(dialog): default button support

* test(dialog): fixed for cases without primary button

* test(dialog): covered default button focus behavior

* docs(dialog): default button examples
  • Loading branch information
arturmiz authored Feb 28, 2019
1 parent 61957be commit 0036354
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 20 deletions.
21 changes: 21 additions & 0 deletions __tests__/__snapshots__/dialog.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,27 @@ exports[`Dialog by default, when opened renders correctly 1`] = `
</div>
`;

exports[`Dialog when custom default button given when opened renders correctly 1`] = `
<div class="vnt-dialog-overlay">
<div role="dialog" tabindex="0" aria-label="Confirm Delete Action" class="vnt-dialog">
<h1 class="vnt-dialog__title">
Confirm Delete Action
</h1>
<p class="vnt-dialog__content">
Are you sure you want to delete this item?
</p>
<div class="vnt-dialog__actions">
<button type="button" class="vnt-button vnt-button--primary">
Delete
</button>
<button type="button" class="vnt-button">
Cancel
</button>
</div>
</div>
</div>
`;

exports[`Dialog when custom dismiss button given renders correctly 1`] = `
<div class="vnt-dialog-overlay">
<div role="dialog" tabindex="0" aria-label="Warning" class="vnt-dialog">
Expand Down
75 changes: 74 additions & 1 deletion __tests__/dialog.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ describe('Dialog', () => {

});

describe('when opened after initialization', () => {
describe('by default, when opened after initialization', () => {

beforeEach(() => {
wrapper = mount(VntDialog);
Expand Down Expand Up @@ -421,4 +421,77 @@ describe('Dialog', () => {

});

describe('when custom default button given', () => {

beforeEach(() => {
wrapper = mount(VntDialog, {
propsData: {
title: 'Confirm Delete Action',
content: 'Are you sure you want to delete this item?'
},
slots: {
default: '<vnt-dialog-btn-primary result="remove" default>Delete</vnt-dialog-btn-primary>'
}
});
});

describe('when opened', () => {

test('renders correctly', () => {
wrapper.setProps({ opened: true });

expect(wrapper).toMatchSnapshot();
});

});

describe('on ESC key pressed', () => {

beforeEach(() => {
wrapper.setProps({ opened: true });
});

test('emits correct result', (done) => {
wrapper.vm.$nextTick(() => {
wrapper.find(':focus').trigger('keyup.esc');

expect(emittedResult(wrapper)).toBe(null);
done();
});
});

test('closes dialog', (done) => {
wrapper.vm.$nextTick(() => {
wrapper.find(':focus').trigger('keyup.esc');

expect(openedResult(wrapper)).toBe(false);
done();
});
});

});

describe('on Enter key pressed', () => {

beforeEach(() => {
wrapper.setProps({ opened: true });

wrapper.vm.$nextTick(() => {
// FIXME: how to trigger Enter? keyup.enter / keydown.enter doesn't work
wrapper.find(':focus').trigger('click');
});
});

test('emits correct result', () => {
expect(emittedResult(wrapper)).toBe('remove');
});

test('closes dialog', () => {
expect(openedResult(wrapper)).toBe(false);
});

});

});

});
2 changes: 1 addition & 1 deletion docs/.vuepress/components/dialog-full.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<vnt-dialog :opened.sync="opened" v-on:result="onresult"
title="Question"
content="This is a dialog with two action buttons and a custom dismiss button.">
<vnt-dialog-btn-primary result="ok">OK</vnt-dialog-btn-primary>
<vnt-dialog-btn-primary result="ok" default>OK</vnt-dialog-btn-primary>
<vnt-dialog-btn-secondary result="later">Later</vnt-dialog-btn-secondary>
<vnt-dialog-btn-dismiss result="cancel">Close</vnt-dialog-btn-dismiss>
</vnt-dialog>
Expand Down
24 changes: 24 additions & 0 deletions docs/.vuepress/components/dialog-primary-default.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<template>
<div class="playground">
<vnt-button :click="showDialog">Open Dialog</vnt-button>

<div class="result"><br />opened: {{ opened }}<br />result: {{ result }}</div>

<vnt-dialog :opened.sync="opened" v-on:result="onresult"
title="Notice"
content="This is a dialog with a default action button.">
<vnt-dialog-btn-primary result="ok" default>OK</vnt-dialog-btn-primary>
</vnt-dialog>
</div>
</template>

<script>
import DialogMixin from './dialog.mixin';
export default {
name: 'DialogPrimaryDefault',
mixins: [
DialogMixin
]
}
</script>
14 changes: 13 additions & 1 deletion docs/components/dialog.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@
</vnt-dialog>
```

## Default action

<dialog-primary-default />

```html
<vnt-dialog :opened.sync="opened" v-on:result="onresult"
title="Notice"
content="This is a dialog with a default action button.">
<vnt-dialog-btn-primary result="ok" default>OK</vnt-dialog-btn-primary>
</vnt-dialog>
```

## Secondary action

<dialog-secondary />
Expand All @@ -45,7 +57,7 @@
<vnt-dialog :opened.sync="opened" v-on:result="onresult"
title="Question"
content="This is a dialog with two action buttons and a custom dismiss button.">
<vnt-dialog-btn-primary result="ok">OK</vnt-dialog-btn-primary>
<vnt-dialog-btn-primary result="ok" default>OK</vnt-dialog-btn-primary>
<vnt-dialog-btn-secondary result="later">Later</vnt-dialog-btn-secondary>
<vnt-dialog-btn-dismiss result="cancel">Close</vnt-dialog-btn-dismiss>
</vnt-dialog>
Expand Down
49 changes: 34 additions & 15 deletions src/components/dialog/Dialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<vnt-button v-for="button in buttons"
:key="button.tag"
:ref="button.tag"
:primary="button.isDefault"
:click="buttonClick(button.result)">
{{ button.label }}
</vnt-button>
Expand All @@ -32,6 +33,7 @@ import VntButton from '../button';
const BTN_PREFIX = 'vnt-dialog-btn-';
const PRIMARY_BTN = `${BTN_PREFIX}primary`;
const DISMISS_BTN = `${BTN_PREFIX}dismiss`;
const DEFAULT_BTN_ATTR = 'default';
export default {
name: 'VntDialog',
Expand Down Expand Up @@ -67,7 +69,17 @@ export default {
opened() {
this.$nextTick(() => {
if (this.opened) {
this.$refs.dialog.focus();
let focusedElement = this.$refs.dialog;
if (this.$refs[PRIMARY_BTN]) {
const [primaryBtn] = this.$refs[PRIMARY_BTN];
if (primaryBtn && primaryBtn.primary) {
focusedElement = primaryBtn.$el;
}
}
focusedElement.focus();
}
});
}
Expand All @@ -85,26 +97,33 @@ export default {
tag,
label: children[0].text,
result: attrs.result,
isDefault: tag === PRIMARY_BTN && Object.keys(attrs).includes(DEFAULT_BTN_ATTR)
};
if (tag === PRIMARY_BTN) {
this.buttons = [btn, ...this.buttons];
} else if (tag === DISMISS_BTN) {
const nonDismissBtns = this.buttons.filter(btn => btn.tag !== tag);
this.buttons = [...nonDismissBtns, btn];
} else {
const [leftBtn, ...buttons] = this.buttons;
if (leftBtn.tag === PRIMARY_BTN) {
this.buttons = [leftBtn, btn, ...buttons];
} else {
this.buttons = [btn, leftBtn, ...buttons];
}
}
this.placeButton(btn);
});
},
methods: {
placeButton(btn) {
const { tag } = btn;
if (tag === PRIMARY_BTN) {
this.buttons = [btn, ...this.buttons];
} else if (tag === DISMISS_BTN) {
const nonDismissBtns = this.buttons.filter(button => button.tag !== tag);
this.buttons = [...nonDismissBtns, btn];
} else {
const [leftBtn, ...buttons] = this.buttons;
if (leftBtn.tag === PRIMARY_BTN) {
this.buttons = [leftBtn, btn, ...buttons];
} else {
this.buttons = [btn, leftBtn, ...buttons];
}
}
},
hide() {
this.$emit('update:opened', false);
},
Expand Down
4 changes: 2 additions & 2 deletions src/components/dialog/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

```html
<vnt-dialog title="Confirm Delete Action" content="Are you sure you want to delete this item?" opened>
<vnt-dialog-btn-primary result="ok">OK</vnt-dialog-btn-primary>
<vnt-dialog-btn-secondary result="later">OK</vnt-dialog-btn-secondary>
<vnt-dialog-btn-primary result="ok" default>OK</vnt-dialog-btn-primary>
<vnt-dialog-btn-secondary result="later">Ask me later</vnt-dialog-btn-secondary>
<vnt-dialog-btn-dismiss result="cancel">Cancel</vnt-dialog-btn-dismiss>
</vnt-dialog>
```

0 comments on commit 0036354

Please sign in to comment.