diff --git a/Colorschemepicker.class.php b/Colorschemepicker.class.php
index 31759274eb5a5404339e00ac36d8eca3d7e69ea0..c04dec4b942ba8bd509ef301e8f8a01a409e5ef0 100644
--- a/Colorschemepicker.class.php
+++ b/Colorschemepicker.class.php
@@ -57,7 +57,7 @@ class Colorschemepicker extends StudIPPlugin implements SystemPlugin
         $widget = Sidebar::get()->addWidget(new SearchWidget());
         $widget->setTitle(_('Farbwert suchen'));
         $widget->addNeedle('#abcdef', 'search-color', true, null, null, null, [
-            'pattern' => '#?[a-fA-F0-9]{6}'
+            'pattern' => '#?(?:[a-fA-F0-9]{3}){1,2}'
         ]);
 
         $factory = new Flexi_TemplateFactory($this->getPluginPath() . '/templates');
diff --git a/assets/script.js b/assets/script.js
index 31834eaa02596efb45d6e43bb9da8a1c7aea0244..be3db249bd26c831ad6f2969da9487eb70a9fbdb 100644
--- a/assets/script.js
+++ b/assets/script.js
@@ -5,6 +5,10 @@
                 hex = hex.slice(1);
             }
 
+            if (hex.length === 3) {
+                hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
+            }
+
             const rgb = {
                 r: parseInt(hex.slice(0, 2), 16),
                 g: parseInt(hex.slice(2, 4), 16),
@@ -125,27 +129,58 @@
             return allVars.concat(...colors);
         }, []);
 
+        const minibus = {
+            handlers: {},
+            trigger(event, ...args) {
+                if (this.handlers[event] === undefined) {
+                    return;
+                }
+
+                this.handlers[event].forEach(handler => handler(...args));
+            },
+            on(event, handler) {
+                if (this.handlers[event] === undefined) {
+                    this.handlers[event] = [];
+                }
+                this.handlers[event].push(handler);
+            }
+        }
+
         // Create vue app
         const appConfig = {
             el: document.getElementById('color-list'),
-            data: {
-                colors: colors,
-                searchColor: false,
-                sortByColor: false,
+            data() {
+                return {
+                    colors: colors,
+                    searchColor: false,
+                    sortByColor: false,
+                };
             },
             methods: {
                 copy(event) {
-                    const dummy = document.createElement('textarea');
-                    dummy.value = event.target.value;
-                    document.body.appendChild(dummy);
-                    dummy.select();
-                    if (document.execCommand('copy')) {
+                    (new Promise((resolve, reject) => {
+                        if (navigator.clipboard) {
+                            navigator.clipboard.writeText(event.target.value).then(resolve, reject);
+                        }
+
+                        const dummy = document.createElement('textarea');
+                        dummy.value = event.target.value;
+                        document.body.appendChild(dummy);
+                        dummy.select();
+                        if (document.execCommand('copy')) {
+                            resolve();
+                        } else {
+                            reject();
+                        }
+                        document.body.removeChild(dummy);
+                    })).then(() => {
+                        console.log('fooooo');
+
                         event.target.classList.add('copied-value');
                         event.target.addEventListener('animationend', () => {
                             event.target.classList.remove('copied-value');
                         });
-                    }
-                    document.body.removeChild(dummy);
+                    });
                 },
                 toggleSortByColor() {
                     if (!this.sortByColor) {
@@ -196,13 +231,16 @@
                     }
                     return colors;
                 }
+            },
+            created() {
+                minibus.on('search-color', color => this.searchColor = color);
             }
         };
 
         let promise;
-        if (window.Vue) {
+        if (window.Vue !== undefined) {
             promise = Promise.resolve(new Vue(appConfig));
-        } else if (window.STUDIP.Vue) {
+        } else if (window.STUDIP.Vue !== undefined) {
             promise = STUDIP.Vue.load().then(({createApp}) => {
                 return createApp(appConfig);
             })
@@ -210,14 +248,15 @@
             promise = Promise.reject('No search possible due to missing vue');
         }
 
-        promise.then(app => {
+        promise.then(() => {
             // Attach search input from sidebar
             const search = document.querySelector('.sidebar,#sidebar').querySelector('input[name="search-color"]');
+            console.log('search', search);
             search.addEventListener('keyup', event => {
                 if (search.checkValidity()) {
-                    app.searchColor = Color.fromHexValue(search.value);
+                    minibus.trigger('search-color', Color.fromHexValue(search.value));
                 } else {
-                    app.searchColor = false;
+                    minibus.trigger('search-color', false);
                 }
             });
             search.closest('form').addEventListener(
diff --git a/plugin.manifest b/plugin.manifest
index 4ab2ab0dcd3ba6793bf9b3acb7ae5cb42f80df61..bb64a60116ac66cb22f6caf6ecf46494eefda634 100644
--- a/plugin.manifest
+++ b/plugin.manifest
@@ -1,5 +1,5 @@
 pluginname=Colorscheme Picker
 pluginclassname=Colorschemepicker
 origin=UOL
-version=2.3.1
-studipMinVersion=4.5
+version=2.3.2
+studipMinVersion=5.0