diff --git a/docs/.vuepress/components/Alert.vue b/docs/.vuepress/components/Alert.vue
new file mode 100644
index 0000000..dc5165b
--- /dev/null
+++ b/docs/.vuepress/components/Alert.vue
@@ -0,0 +1,42 @@
+
+  
+    
+  
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/.vuepress/components/Color.vue b/docs/.vuepress/components/Color.vue
new file mode 100644
index 0000000..350951b
--- /dev/null
+++ b/docs/.vuepress/components/Color.vue
@@ -0,0 +1,35 @@
+
+  
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/.vuepress/components/ColorList.vue b/docs/.vuepress/components/ColorList.vue
new file mode 100644
index 0000000..1a0480f
--- /dev/null
+++ b/docs/.vuepress/components/ColorList.vue
@@ -0,0 +1,18 @@
+
+  
+    
+  
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js
index 0b8eddd..4f85974 100644
--- a/docs/.vuepress/config.js
+++ b/docs/.vuepress/config.js
@@ -50,7 +50,7 @@ module.exports = {
     nextLinks: true,
     prevLinks: true,
   },
-  plugins: ['@vuepress/back-to-top'],
+  plugins: ['@vuepress/back-to-top', require('./plugins/alert')],
   markdown: {
     lineNumbers: true
   }
diff --git a/docs/.vuepress/plugins/alert/Alert.vue b/docs/.vuepress/plugins/alert/Alert.vue
new file mode 100644
index 0000000..433d07e
--- /dev/null
+++ b/docs/.vuepress/plugins/alert/Alert.vue
@@ -0,0 +1,46 @@
+
+  
+    
+  
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/.vuepress/plugins/alert/alertMixin.js b/docs/.vuepress/plugins/alert/alertMixin.js
new file mode 100644
index 0000000..49c65c9
--- /dev/null
+++ b/docs/.vuepress/plugins/alert/alertMixin.js
@@ -0,0 +1,38 @@
+import Alert from './Alert'
+
+const AlertMixin = {
+  install(Vue) {
+    Vue.mixin({
+      methods: {
+        $alert(message, duration = 2000) {
+          let Constructor= Vue.extend(Alert)
+          let alert = new Constructor()
+          alert.$slots.default = message
+          alert.$props.alert = this.$page.alert
+          alert.$mount()
+          document.body.appendChild(alert.$el)
+
+          const appendHeight = alert.$el.offsetHeight + 16
+          this.$page.alert.top += appendHeight
+
+          setTimeout(() => {
+            this.$page.alert.top -= appendHeight
+            this.triggerRemoveAlert(appendHeight)
+            setTimeout(() => {
+              alert.$destroy()
+              alert.$el.remove()
+            }, 100)
+          }, duration)
+        },
+        triggerRemoveAlert(height) {
+          const event = new CustomEvent('alert_remove', {
+            detail: {height}
+          })
+          window.dispatchEvent(event)
+        }
+      }
+    })
+  }
+}
+
+export default AlertMixin
diff --git a/docs/.vuepress/plugins/alert/clientRootMixin.js b/docs/.vuepress/plugins/alert/clientRootMixin.js
new file mode 100644
index 0000000..e5cf7fb
--- /dev/null
+++ b/docs/.vuepress/plugins/alert/clientRootMixin.js
@@ -0,0 +1,5 @@
+export default {
+  updated() {
+    this.$page.alert.top = 100
+  }
+}
diff --git a/docs/.vuepress/plugins/alert/enhanceApp.js b/docs/.vuepress/plugins/alert/enhanceApp.js
new file mode 100644
index 0000000..d02c403
--- /dev/null
+++ b/docs/.vuepress/plugins/alert/enhanceApp.js
@@ -0,0 +1,5 @@
+import AlertMixin from './alertMixin'
+
+export default ({Vue}) => {
+  Vue.use(AlertMixin)
+}
\ No newline at end of file
diff --git a/docs/.vuepress/plugins/alert/index.js b/docs/.vuepress/plugins/alert/index.js
new file mode 100644
index 0000000..c5ff1a7
--- /dev/null
+++ b/docs/.vuepress/plugins/alert/index.js
@@ -0,0 +1,13 @@
+const path = require('path')
+
+module.exports = (options, ctx) => {
+  return {
+    clientRootMixin: path.resolve(__dirname, 'clientRootMixin.js'),
+    extendPageData($page) {
+      $page.alert = {
+        top: 100
+      }
+    },
+    enhanceAppFiles: path.resolve(__dirname, 'enhanceApp.js')
+  }
+}
\ No newline at end of file