├── .browserslistrc ├── .eslintrc.js ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── babel.config.js ├── jest.config.js ├── package.json ├── src ├── VTNotification.vue ├── VTNotificationGroup.vue ├── components │ └── HelloWorld.vue ├── index.js └── notifications.js └── tests └── unit └── example.spec.js /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | env: { 5 | node: true 6 | }, 7 | 8 | 'extends': [ 9 | 'plugin:vue/essential', 10 | 'eslint:recommended' 11 | ], 12 | 13 | parserOptions: { 14 | parser: 'babel-eslint' 15 | }, 16 | 17 | rules: { 18 | 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 19 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off' 20 | }, 21 | 22 | overrides: [ 23 | { 24 | files: [ 25 | '**/__tests__/*.{j,t}s?(x)', 26 | '**/tests/unit/**/*.spec.{j,t}s?(x)' 27 | ], 28 | env: { 29 | jest: true 30 | } 31 | } 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | *.sublime-* 25 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | 4 | ### 1.0.1 (2021-05-28) 5 | 6 | * fix: Update VTNotification.vue (@NoahCardoza) 7 | * chore: get rid of the slots warning (@emmanuelsw) 8 | 9 | 10 | 11 | ### 1.0.0 (2021-02-19) 12 | 13 | * feat: port to vue 3 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Alexey Kucherenko 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | [![](https://img.shields.io/github/license/killmenot/vue3-vt-notifications?style=flat-square)](https://github.com/killmenot/vue3-vt-notifications) 3 | [![](https://img.shields.io/npm/dt/vue3-vt-notifications.svg?style=flat-square)](https://www.npmjs.com/package/vue3-vt-notifications) 4 | 5 | # vue3-vt-notifications 6 | 7 | A headless vue notification library to use with tailwind 8 | 9 | - This is port of Vue 2 [vt-notifications](https://github.com/sansil/vt-notifications) created by [sansil](https://github.com/sansil). Please use his version if you use Vue 2.x 10 | - Sponsored by [Britton Mathew](https://github.com/printscreen) from Veedback 11 | 12 | ## 🌟 Features 13 | 14 | - 100% customizable 15 | - Create different groups of notifications 16 | - Built in transitions 17 | 18 | ## 🤖 Demo 19 | 20 | [Live demo](https://codesandbox.io/s/vue-tailwind-notifications-forked-i74t0?file=/src/App.vue) 21 | 22 | ## ⚡️ Installation 23 | 24 | ```bash 25 | yarn add vue3-vt-notifications 26 | ``` 27 | 28 | or 29 | 30 | ```bash 31 | npm i vue3-vt-notifications 32 | ``` 33 | 34 | You can then register Notifications as a Vue plugin. 35 | 36 | ```js 37 | import { createApp } from 'vue' 38 | import Notifications from 'vue3-vt-notifications' 39 | import App from './App.vue' 40 | 41 | createApp(App) 42 | .use(Notifications) 43 | .mount('#app') 44 | 45 | 46 | ``` 47 | 48 | ## 🍞 How to use 49 | 50 | ```vue 51 | 52 | // Here put your notifications wrapper box 53 | ... 54 | 55 | // Here put your notification layout 56 | ... 57 | 58 | 59 | ``` 60 | 61 | ### Basic example 62 | 63 | For example in your App.vue 64 | 65 | ```vue 66 | 67 |
70 |
71 | 72 |
77 |
78 | 83 | 86 | 87 |
88 | 89 |
90 |
91 | {{notification.title}} 92 |

{{notification.text}}

93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 | ``` 101 | 102 | Then in any of your vue files: 103 | 104 | ```javascript 105 | this.$notify( 106 | { group: "foo", title: "Success", text: "Your account was registered!" }, 107 | 2000 108 | ); // 2s 109 | ``` 110 | 111 | The first argument is an object containing the data for the `notification` layout, it important to specify the group where the notificatoins are going to be displayed, the second argument is the timeout. The default timeout is 3 seconds. 112 | 113 | ### Example with differents groups 114 | 115 | You can use `notificationGroup` component to have different types of notifcations. For example, notifcations error messages in top center and generic app notifications in bottom-right corner 116 | 117 | ```vue 118 | 119 |
122 |
123 | 124 |
129 |
130 | 131 | 132 | 133 |
134 | 135 |
136 |
137 | {{notification.title}} 138 |

{{notification.text}}

139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 | 147 | 148 |
151 |
152 | 153 |
158 |
159 | 160 | 161 | 162 |
163 |
164 |
165 | {{notification.title}}Info 166 |

{{notification.text}}

167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 | ``` 175 | 176 | Then in any of your vue files: 177 | 178 | ```javascript 179 | // error notifcation 180 | this.$notify( 181 | { group: "error", title: "Error", text: "Your email is already used!" }, 182 | 4000 183 | ); 184 | // generic notification 185 | this.$notify( 186 | { 187 | group: "generic", 188 | title: "Info", 189 | text: "This channel archived by the owner", 190 | }, 191 | 4000 192 | ); 193 | ``` 194 | 195 | ### Using different types of notifcations 196 | 197 | You can render different types of notifications in the same group using a conditional, for example `v-if="notification.type==='info'"` 198 | 199 | ```vue 200 | 201 |
202 |
203 | 204 |
205 |
209 |
210 | 215 | 218 | 219 |
220 | 221 |
222 |
223 | {{notification.title}} 224 |

T{{notification.text}}

225 |
226 |
227 |
228 |
232 |
233 | 238 | 241 | 242 |
243 | 244 |
245 |
246 | {{notification.title}} 247 |

{{notification.text}}

248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 | ``` 257 | 258 | Then in any of your vue files: 259 | 260 | ```javascript 261 | // error notifcation 262 | this.$notify( 263 | { 264 | title: "Info", 265 | text: "This channel archived by the owner!", 266 | type: "info", 267 | group: "foo", 268 | }, 269 | 4000 270 | ); 271 | // generic notification 272 | this.$notify( 273 | { 274 | title: "Warning", 275 | text: "Your image size is too large!", 276 | type: "warning", 277 | group: "foo", 278 | }, 279 | 4000 280 | ); 281 | ``` 282 | 283 | ## Props 284 | 285 | Props for **notification component**, all are opcional. 286 | 287 | | Name | Type | Default | Description | 288 | | ---------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | 289 | | maxNotifications | Number | 10 | Maximum notifications displayed simultaneously | 290 | | transitionGroupClasses | Object | {enterActiveClassDelayed:"transform ease-out duration-300 transition delay-300",enterActiveClass:"transform ease-out duration-300 transition",enterFromClass:"translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-4",enterToClass:"translate-y-0 opacity-100 sm:translate-x-0",leaveActiveClass:"transition ease-in duration-500",leaveFromClass:"opacity-100",leaveToClass: "opacity-0", moveClass: "transition duration-500 "} | Classes for the transition-group component | 291 | 292 | Props for **notification group component**, all are opcional. 293 | 294 | | Name | Type | Description | 295 | | -------- | ------ | --------------------------------------- | 296 | | position | String | "bottom" or "top are the posible values | 297 | | group | String | Name of the group of notifications | 298 | 299 | ## Defualt scoped slot 300 | 301 | Scope props: 302 | 303 | | Name | Type | Description | 304 | | ------------- | -------- | ------------------------------------------------------------------------ | 305 | | notifications | Array | Arrya of notification object | 306 | | close | Function | when called closes the notification. Expect the notification id as input | 307 | 308 | ### Example 309 | 310 | ```vue 311 | 312 | 335 | 336 | ``` 337 | 338 | ## Using the library in Nuxt.js 339 | 340 | To get this library working in Nuxt.js you need to prepare a few things. 341 | 342 | Create a new plugin in your Nuxt.js project `plugin/vue3-vt-notifications.js` and add the following: 343 | 344 | ```js 345 | import Vue from "vue"; 346 | import Notifications from "vue3-vt-notifications"; 347 | 348 | Vue.use(Notifications); 349 | ``` 350 | 351 | Now you need to add the plugin in your `nuxt.config.js` and add vue3-vt-notifications to the transpilation build step. 352 | 353 | Add the following lines in your `nuxt.config.js`: 354 | 355 | ```js 356 | plugins: [ 357 | { src: "~/plugins/vue3-vt-notifications" }, 358 | ], 359 | build: { 360 | transpile: [ 361 | "vue3-vt-notifications" 362 | ], 363 | } 364 | ``` 365 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: '@vue/cli-plugin-unit-jest' 3 | } 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue3-vt-notifications", 3 | "description": "A headless vue notification library to use with tailwind", 4 | "version": "1.0.1", 5 | "main": "src/index.js", 6 | "license": "MIT", 7 | "author": { 8 | "name": "Alexey Kucherenko", 9 | "url": "https://github.com/killmenot" 10 | }, 11 | "homepage": "https://github.com/killmenot/vue3-vt-notifications", 12 | "repository": { 13 | "type": "git", 14 | "url": "git@github.com:killmenot/vue3-vt-notifications.git" 15 | }, 16 | "bugs": { 17 | "url": "https://github.com/killmenot/vue3-vt-notifications/issues" 18 | }, 19 | "scripts": { 20 | "lint": "vue-cli-service lint", 21 | "test:unit": "vue-cli-service test:unit" 22 | }, 23 | "devDependencies": { 24 | "@vue/cli-plugin-babel": "^4.5.0", 25 | "@vue/cli-plugin-eslint": "^4.5.0", 26 | "@vue/cli-plugin-unit-jest": "^4.5.4", 27 | "@vue/cli-service": "^4.5.0", 28 | "@vue/test-utils": "^1.0.3", 29 | "babel-eslint": "^10.1.0", 30 | "eslint": "^6.7.2", 31 | "eslint-plugin-vue": "^6.2.2", 32 | "vue-template-compiler": "^2.6.11" 33 | }, 34 | "peerDependencies": { 35 | "vue": "^3.0.0" 36 | }, 37 | "keywords": [ 38 | "vue", 39 | "vue3", 40 | "vuejs", 41 | "tailwindcss", 42 | "tailwindui", 43 | "notifications", 44 | "toast" 45 | ] 46 | } -------------------------------------------------------------------------------- /src/VTNotification.vue: -------------------------------------------------------------------------------- 1 | 2 | 80 | -------------------------------------------------------------------------------- /src/VTNotificationGroup.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | -------------------------------------------------------------------------------- /src/components/HelloWorld.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 15 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import VTNotification from './VTNotification.vue' 2 | import VTNotificationGroup from './VTNotificationGroup.vue' 3 | import { methods } from './notifications.js' 4 | 5 | let installed = false 6 | 7 | export default { 8 | install(app) { 9 | if (installed) return 10 | app.component('notification', VTNotification) 11 | app.component('notificationGroup', VTNotificationGroup) 12 | app.config.globalProperties.$notify = (data, timeout) => methods.notify(data, timeout) 13 | installed = true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/notifications.js: -------------------------------------------------------------------------------- 1 | import { reactive } from 'vue' 2 | 3 | export const state = reactive({ 4 | notifications: [ 5 | ], 6 | }); 7 | 8 | let count = 0; 9 | const generateId = () => { 10 | count = count + 1; 11 | return count 12 | } 13 | export const methods = { 14 | notify(notification, timeout) { 15 | notification.id = generateId() 16 | notification.group = notification.group || ''; // add default group 17 | state.notifications.push(notification); 18 | setTimeout(() => { 19 | this.removeNotification(notification.id) 20 | }, timeout || 3000) // default time 3s 21 | }, 22 | removeNotification(id) { 23 | state.notifications.splice(state.notifications.findIndex(n => n.id === id), 1) 24 | } 25 | }; -------------------------------------------------------------------------------- /tests/unit/example.spec.js: -------------------------------------------------------------------------------- 1 | import { shallowMount } from '@vue/test-utils' 2 | import HelloWorld from '@/components/HelloWorld.vue' 3 | 4 | describe('HelloWorld.vue', () => { 5 | it('renders props.msg when passed', () => { 6 | const msg = 'new message' 7 | const wrapper = shallowMount(HelloWorld, { 8 | propsData: { msg } 9 | }) 10 | expect(wrapper.text()).toMatch(msg) 11 | }) 12 | }) 13 | --------------------------------------------------------------------------------