Skip to content

Commit

Permalink
Merge pull request #4 from rossrobino/feat--copy-button-reactivity
Browse files Browse the repository at this point in the history
feat: copy button reactivity
  • Loading branch information
rossrobino authored Aug 24, 2023
2 parents 8cdd302 + d8d5879 commit b33b2d1
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 21 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "drab",
"version": "3.0.1",
"version": "3.0.2",
"description": "An Unstyled Svelte Component Library",
"keywords": [
"components",
Expand Down
40 changes: 23 additions & 17 deletions src/lib/components/CopyButton.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
### CopyButton
Uses the [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard) to copy data to the clipboard. Falls back to `writeText` if `write` is not supported and `blob.type` is text. If JavaScript is disabled, the button is disabled and `blobParts.join()` is displayed after the button if `blob.type` is text.
Uses the [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipboard) to copy data to the clipboard. Falls back to `writeText` if `write` is not supported and `blob.type` is text.
@props
- `blobParts` - array of `BlobParts` to copy - [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob#parameters)
- `blob` - use a blob in instead of `blobParts` and `options`, defaults to `new Blob(blobParts, options)`
- `classNoscript` - `noscript` class
- `class`
- `id`
- `options` - defaults to `{ type: "text/plain" }` - [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob#parameters)
Expand All @@ -27,9 +26,13 @@ Uses the [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipbo
```svelte
<script lang="ts">
import { CopyButton } from "drab";
let value = "Text to copy";
</script>
<CopyButton class="btn" blobParts={["Text to copy"]} />
<input class="input mb-4" type="text" bind:value />
<CopyButton class="btn" blobParts={[value]} />
```
-->

Expand All @@ -53,22 +56,25 @@ Uses the [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipbo
/** use a blob in instead of `blobParts` and `options`, defaults to `new Blob(blobParts, options)` */
export let blob: Blob = new Blob(blobParts, options);
/** `noscript` class */
export let classNoscript = "";
/** set to `false` on the client depending on support */
let disabled = true;
/** changes `button` text after message is successfully copied */
let complete = false;
const writeSupport = () => "write" in navigator.clipboard;
/** used if `writeText` is required, can't use `blobParts` directly in case `blob` prop is used */
let blobText: string;
const typeText = blob.type.startsWith("text");
const setBlobText = async (blob: Blob) => (blobText = await blob.text());
/** determines if `writeText` can be utilized instead if `write` is not supported */
const writeSupport = () => "write" in navigator.clipboard;
/** determines if `writeText` can be utilized instead, if `write` is not supported */
const canWriteText = () => {
// check browser support
const writeTextSupport = "writeText" in navigator.clipboard;
// check if the type is text (able to pass into `writeText`)
const typeText = blob.type.startsWith("text");
return writeTextSupport && typeText;
};
Expand All @@ -80,7 +86,7 @@ Uses the [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipbo
await navigator.clipboard.write(data);
} else if (canWriteText()) {
// use writeText
await navigator.clipboard.writeText(blobParts ? blobParts.join() : "");
await navigator.clipboard.writeText(blobText);
}
complete = true;
setTimeout(() => (complete = false), delay);
Expand All @@ -89,9 +95,15 @@ Uses the [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipbo
}
};
onMount(() => {
onMount(async () => {
if (writeSupport() || canWriteText()) disabled = false;
});
// if `blobParts` prop is used and it changes, reset `blob`
$: if (blobParts) blob = new Blob(blobParts, options);
// if the blob changes, reset `blobText`
$: setBlobText(blob);
</script>

<button
Expand All @@ -108,9 +120,3 @@ Uses the [Clipboard API](https://developer.mozilla.org/en-US/docs/Web/API/Clipbo
<slot>Copy</slot>
{/if}
</button>

{#if typeText}
<noscript>
<span class={classNoscript}>{blobParts ? blobParts.join() : ""}</span>
</noscript>
{/if}
6 changes: 5 additions & 1 deletion src/routes/docs/CopyButton/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<script lang="ts">
import { CopyButton } from "$lib";
let value = "Text to copy";
</script>

<CopyButton class="btn" blobParts={["Text to copy"]} />
<input class="input mb-4" type="text" bind:value />

<CopyButton class="btn" blobParts={[value]} />

1 comment on commit b33b2d1

@vercel
Copy link

@vercel vercel bot commented on b33b2d1 Aug 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.