Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
699 additions
and
0 deletions.
There are no files selected for viewing
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,191 @@ | ||
# Notification | ||
|
||
> Displays a global notification message at a corner of the page. | ||
## Example | ||
|
||
Click on the button below to show a notification. By default, it is dismissible with a close button, and will dismiss automatically after 5000ms (both are configurable). | ||
|
||
```html | ||
<template> | ||
<section> | ||
<btn @click="notify" type="primary">Default Notification</btn> | ||
<btn @click="notify2" type="primary">No Auto-dismiss Notification</btn> | ||
</section> | ||
</template> | ||
<script> | ||
export default { | ||
methods: { | ||
// example with callback | ||
notify () { | ||
this.$notify({ | ||
title: 'Title', | ||
content: 'This is a notify message.' | ||
}, () => { | ||
// callback after dismissed | ||
console.log('dismissed') | ||
}) | ||
}, | ||
// example with Promise | ||
notify2 () { | ||
this.$notify({ | ||
title: 'Title', | ||
content: 'This notification will not dismiss automatically.', | ||
duration: 0 | ||
}).then(() => { | ||
// resolve after dismissed | ||
console.log('dismissed') | ||
}) | ||
} | ||
} | ||
} | ||
</script> | ||
<!-- notification-example.vue --> | ||
``` | ||
|
||
## Types | ||
|
||
There're 4 optional types of notification: `info` / `success` / `warning` / `danger`. | ||
|
||
Notification with specific type will has a default icon on the left, you can also change or remove the icon by `icon` option. | ||
|
||
```html | ||
<template> | ||
<section> | ||
<btn @click="info" type="info">Info</btn> | ||
<btn @click="success" type="success">Success</btn> | ||
<btn @click="warning" type="warning">Warning</btn> | ||
<btn @click="danger" type="danger">Danger</btn> | ||
</section> | ||
</template> | ||
<script> | ||
export default { | ||
methods: { | ||
info () { | ||
this.$notify({ | ||
type: 'info', | ||
title: 'Heads up!', | ||
content: 'This alert needs your attention, but it\'s not super important.' | ||
}) | ||
}, | ||
success () { | ||
this.$notify({ | ||
type: 'success', | ||
title: 'Well done!', | ||
content: 'You successfully read this important alert message.' | ||
}) | ||
}, | ||
warning () { | ||
this.$notify({ | ||
type: 'warning', | ||
title: 'Warning!', | ||
content: 'Better check yourself, you\'re not looking too good.' | ||
}) | ||
}, | ||
danger () { | ||
this.$notify({ | ||
type: 'danger', | ||
title: 'Oh snap!', | ||
content: 'Change a few things up and try submitting again.' | ||
}) | ||
} | ||
} | ||
} | ||
</script> | ||
<!-- notification-types.vue --> | ||
``` | ||
|
||
## Placements | ||
|
||
Notifications can be placed on any corner on a page. | ||
|
||
The `position` prop defines which corner a notification will slide in. It can be `top-right` (default), `top-left`, `bottom-right` or `bottom-left`. | ||
|
||
```html | ||
<template> | ||
<section> | ||
<btn @click="notify('top-right')" type="primary">Top Right (Default)</btn> | ||
<btn @click="notify('bottom-right')" type="primary">Bottom Right</btn> | ||
<btn @click="notify('bottom-left')" type="primary">Bottom Left</btn> | ||
<btn @click="notify('top-left')" type="primary">Top Left</btn> | ||
</section> | ||
</template> | ||
<script> | ||
export default { | ||
methods: { | ||
notify (placement) { | ||
this.$notify({ | ||
placement, // equal to `placement: placement` in ES6 | ||
title: 'Title', | ||
content: `This is a notify msg at ${placement}.` | ||
}) | ||
} | ||
} | ||
} | ||
</script> | ||
<!-- notification-placements.vue --> | ||
``` | ||
|
||
## Dismissible | ||
|
||
By default a notification is dismissible with a close button, you can hide it by setting `dismissible` to `false`. | ||
|
||
```html | ||
<template> | ||
<btn @click="notify" type="primary">Notification Without Dismiss Button</btn> | ||
</template> | ||
<script> | ||
export default { | ||
methods: { | ||
notify () { | ||
this.$notify({ | ||
title: 'Title', | ||
content: 'This is a notification without dismiss btn.', | ||
dismissible: false | ||
}) | ||
} | ||
} | ||
} | ||
</script> | ||
<!-- notification-without-dismiss-btn.vue --> | ||
``` | ||
|
||
## Global Method | ||
|
||
`$notify(options, callback)` global method for `Vue.prototype` will be added **if uiv is installed**. | ||
|
||
Note that the dismissed callback is optional. | ||
|
||
The method will return a `Promise` object that resolve while the notification is dismissed (if supported by browser or with es6 promise polyfill). | ||
|
||
## Import Individually | ||
|
||
If you prefer importing `Notification` individually: | ||
|
||
```javascript | ||
import { Notification } from 'uiv' | ||
``` | ||
|
||
The corresponding method is `Notification.notify`, with same parameters as above. | ||
|
||
# API Reference | ||
|
||
## [Notification.vue](https://github.com/wxsms/uiv/tree/master/src/services/notification/Notification.vue) | ||
|
||
These props are used as `options` in the methods above. | ||
|
||
### Props | ||
|
||
Name | Type | Default | Required | Description | ||
---------- | ---------- | -------- | -------- | ----------------------- | ||
`title` | String | | | The notification title. | ||
`content` | String | | | The notification content. | ||
`type` | String | | | Support: `info` / `success` / `warning` / `danger`. | ||
`duration` | Number | 5000 | | Dismiss after milliseconds, use 0 to prevent self-closing. | ||
`dismissible` | Boolean | true | | Show dismiss button. | ||
`placement` | String | top-right | | Support: `top-right` / `top-left` / `bottom-right` / `bottom-left`. | ||
`icon` | String | | | Custom icon class, use an empty string to disable icon. | ||
|
||
## [notification.js](https://github.com/wxsms/uiv/tree/master/src/services/notification/notification.js) | ||
|
||
This file has no props. |
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
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 |
---|---|---|
@@ -1 +1,2 @@ | ||
export {default as MessageBox} from './messagebox/messageBox.js' | ||
export {default as Notification} from './notification/notification.js' |
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,123 @@ | ||
<template> | ||
<alert | ||
class="fade" | ||
:style="styles" | ||
:type="type" | ||
:duration="duration" | ||
:dismissible="dismissible" | ||
@dismissed="onDismissed"> | ||
<div class="media" style="margin: 0"> | ||
<div class="media-left" v-if="icons"> | ||
<span :class="icons" style="font-size: 1.5em"></span> | ||
</div> | ||
<div class="media-body"> | ||
<h4 class="media-heading">{{title}}</h4> | ||
<div>{{content}}</div> | ||
</div> | ||
</div> | ||
</alert> | ||
</template> | ||
|
||
<script> | ||
import {addClass, removeClass} from '@src/utils/domUtils' | ||
import {isString} from '@src/utils/objectUtils' | ||
import Alert from '@src/components/alert/Alert.vue' | ||
import {TYPES, PLACEMENTS} from './constants' | ||
const IN_CLASS = 'in' | ||
const ICON = 'glyphicon' | ||
const OFFSET = 15 | ||
const WIDTH = 300 | ||
const TRANSITION_DURATION = 300 | ||
const getTotalHeightOfQueue = (queue, lastIndex = queue.length) => { | ||
let totalHeight = OFFSET | ||
for (let i = 0; i < lastIndex; i++) { | ||
totalHeight += queue[i].height + OFFSET | ||
} | ||
return totalHeight | ||
} | ||
export default { | ||
components: {Alert}, | ||
props: { | ||
title: String, | ||
content: String, | ||
duration: { | ||
type: Number, | ||
default: 5000 | ||
}, | ||
dismissible: { | ||
type: Boolean, | ||
default: true | ||
}, | ||
type: String, | ||
placement: String, | ||
icon: String, | ||
cb: { | ||
type: Function, | ||
required: true | ||
}, | ||
queue: { | ||
type: Array, | ||
required: true | ||
} | ||
}, | ||
data () { | ||
return { | ||
height: 0, | ||
top: 0, | ||
horizontal: this.placement === PLACEMENTS.TOP_LEFT || this.placement === PLACEMENTS.BOTTOM_LEFT ? 'left' : 'right', | ||
vertical: this.placement === PLACEMENTS.TOP_LEFT || this.placement === PLACEMENTS.TOP_RIGHT ? 'top' : 'bottom' | ||
} | ||
}, | ||
created () { | ||
// get prev notifications total height in the queue | ||
this.top = getTotalHeightOfQueue(this.queue) | ||
}, | ||
mounted () { | ||
const el = this.$el | ||
el.style[this.vertical] = this.top + 'px' | ||
this.$nextTick(() => { | ||
el.style[this.horizontal] = `-${WIDTH}px` | ||
this.height = el.offsetHeight | ||
el.style[this.horizontal] = `${OFFSET}px` | ||
addClass(el, IN_CLASS) | ||
}) | ||
}, | ||
computed: { | ||
styles () { | ||
let queue = this.queue | ||
let thisIndex = queue.indexOf(this) | ||
return { | ||
position: 'fixed', | ||
[this.vertical]: `${getTotalHeightOfQueue(queue, thisIndex)}px`, | ||
width: `${WIDTH}px`, | ||
transition: `all ${TRANSITION_DURATION / 1000}s ease-in-out` | ||
} | ||
}, | ||
icons () { | ||
if (isString(this.icon)) { | ||
return this.icon | ||
} | ||
switch (this.type) { | ||
case TYPES.INFO: | ||
case TYPES.WARNING: | ||
return `${ICON} ${ICON}-info-sign` | ||
case TYPES.SUCCESS: | ||
return `${ICON} ${ICON}-ok-sign` | ||
case TYPES.DANGER: | ||
return `${ICON} ${ICON}-remove-sign` | ||
default: | ||
return null | ||
} | ||
} | ||
}, | ||
methods: { | ||
onDismissed () { | ||
removeClass(this.$el, IN_CLASS) | ||
setTimeout(this.cb, TRANSITION_DURATION) | ||
} | ||
} | ||
} | ||
</script> |
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,13 @@ | ||
export const TYPES = { | ||
SUCCESS: 'success', | ||
INFO: 'info', | ||
DANGER: 'danger', | ||
WARNING: 'warning' | ||
} | ||
|
||
export const PLACEMENTS = { | ||
TOP_LEFT: 'top-left', | ||
TOP_RIGHT: 'top-right', | ||
BOTTOM_LEFT: 'bottom-left', | ||
BOTTOM_RIGHT: 'bottom-right' | ||
} |
Oops, something went wrong.