Browse Source

Merge pull request #25 from ryangjchandler/feature/x-clipboard

Ryan Chandler 3 years ago
parent
commit
17b80d836c
5 changed files with 84 additions and 24 deletions
  1. 22 0
      README.md
  2. 29 11
      dist/alpine-clipboard.js
  3. 0 1
      dist/alpine-clipboard.js.map
  4. 8 0
      examples/index.html
  5. 25 12
      src/index.js

+ 22 - 0
README.md

@@ -55,6 +55,28 @@ To copy some data to the clipboard, invoke `$clipboard` from an event handler in
 </div>
 ```
 
+### Directive
+
+This package also includes an `x-clipboard` directive that can be added to any element (usually a `button`) and it will copy the result of the expression on `click`.
+
+```html
+<div x-data="{ input: 'Foo!' }">
+    <button x-clipboard="input">
+        Copy to Clipboard
+    </button>
+</div>
+```
+
+If you are rendering on the server, you might prefer to copy raw content instead of evaluating the expression as JavaScript. This can be done by adding the `.raw` modifier to the directive.
+
+Here's a Blade snippet as an example:
+
+```blade
+<button x-clipboard.raw="{{ $post->url() }}">
+    Copy to Clipboard
+</button>
+```
+
 ### `Object` and `Array`
 
 Since you can pass any properties through to the `$clipboard` function, if you pass through an `Object` or `Array`, it will be run through `JSON.stringify` before being copied to the clipboard.

+ 29 - 11
dist/alpine-clipboard.js

@@ -5,19 +5,37 @@
 
     let onCopy = () => {};
 
-    function Clipboard(Alpine) {
-      Alpine.magic('clipboard', () => {
-        return function (target) {
-          if (typeof target === 'function') {
-            target = target();
-          }
+    const copy = target => {
+      if (typeof target === 'function') {
+        target = target();
+      }
 
-          if (typeof target === 'object') {
-            target = JSON.stringify(target);
-          }
+      if (typeof target === 'object') {
+        target = JSON.stringify(target);
+      }
 
-          return window.navigator.clipboard.writeText(target).then(onCopy);
-        };
+      return window.navigator.clipboard.writeText(target).then(onCopy);
+    };
+
+    function Clipboard(Alpine) {
+      Alpine.magic('clipboard', () => {
+        return copy;
+      });
+      Alpine.directive('clipboard', (el, {
+        modifiers,
+        expression
+      }, {
+        evaluateLater,
+        cleanup
+      }) => {
+        const getCopyContent = modifiers.includes('raw') ? c => c(expression) : evaluateLater(expression);
+
+        const clickHandler = () => getCopyContent(copy);
+
+        el.addEventListener('click', clickHandler);
+        cleanup(() => {
+          el.removeEventListener('click', clickHandler);
+        });
       });
     }
 

File diff suppressed because it is too large
+ 0 - 1
dist/alpine-clipboard.js.map


+ 8 - 0
examples/index.html

@@ -21,5 +21,13 @@
         <button type="button" @click="$clipboard(items)">Copy the JSON representation of `items` to your clipboard</button>
     </div>
 
+    <div x-data="{ text: 'boo' }">
+        <button x-clipboard="text">This uses clipboard directive to copy the text "boo" to your clipboard.</button>
+
+        <button x-clipboard.raw="Here is some raw text to copy to the clipboard.">
+            This will let you copy any raw text in the directive.
+        </button>
+    </div>
+
     <script src="../dist/alpine-clipboard.js"></script>
 </body>

+ 25 - 12
src/index.js

@@ -1,19 +1,32 @@
 let onCopy = () => {}
 
+const copy = (target) => {
+    if (typeof target === 'function') {
+        target = target()
+    }
+
+    if (typeof target === 'object') {
+        target = JSON.stringify(target)
+    }
+
+    return window.navigator.clipboard.writeText(target)
+        .then(onCopy)
+}
+
 function Clipboard(Alpine) {
     Alpine.magic('clipboard', () => {
-        return function (target) {
-            if (typeof target === 'function') {
-                target = target()
-            }
-
-            if (typeof target === 'object') {
-                target = JSON.stringify(target)
-            }
-
-            return window.navigator.clipboard.writeText(target)
-                .then(onCopy)
-        }
+        return copy
+    })
+
+    Alpine.directive('clipboard', (el, { modifiers, expression }, { evaluateLater, cleanup }) => {
+        const getCopyContent = modifiers.includes('raw') ? c => c(expression) : evaluateLater(expression)
+        const clickHandler = () => getCopyContent(copy)
+
+        el.addEventListener('click', clickHandler)
+
+        cleanup(() => {
+            el.removeEventListener('click', clickHandler)
+        })
     })
 }
 

Some files were not shown because too many files changed in this diff