From f8aecdbef12fd1fd6e21261f4572c48d0a3fb145 Mon Sep 17 00:00:00 2001 From: metonym Date: Mon, 14 Mar 2022 08:17:20 -0700 Subject: [PATCH] refactor: inline `Copy` component (#1175) --- COMPONENT_INDEX.md | 2 + docs/src/COMPONENT_API.json | 32 +++++++++++--- src/CodeSnippet/CodeSnippet.svelte | 57 +++++++++++++++++++------ src/CopyButton/CopyButton.svelte | 47 +++++++++++++++++--- types/CopyButton/CopyButton.svelte.d.ts | 16 ++++++- 5 files changed, 125 insertions(+), 29 deletions(-) diff --git a/COMPONENT_INDEX.md b/COMPONENT_INDEX.md index c042d60d..052c625c 100644 --- a/COMPONENT_INDEX.md +++ b/COMPONENT_INDEX.md @@ -921,6 +921,8 @@ None. | Prop name | Kind | Reactive | Type | Default value | Description | | :-------------- | :--------------- | :------- | :---------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | +| feedback | let | No | string | "Copied!" | Set the feedback text shown after clicking the button | +| feedbackTimeout | let | No | number | 2000 | Set the timeout duration (ms) to display feedback text | | iconDescription | let | No | string | "Copy to clipboard" | Set the title and ARIA label for the copy button | | text | let | No | string | undefined | Specify the text to copy | | copy | let | No | (text: string) => void | async (text) => { try { await navigator.clipboard.writeText(text); } catch (e) { console.log(e); } } | Override the default copy behavior of using the navigator.clipboard.writeText API to copy text | diff --git a/docs/src/COMPONENT_API.json b/docs/src/COMPONENT_API.json index 40cc4d90..f7698d84 100644 --- a/docs/src/COMPONENT_API.json +++ b/docs/src/COMPONENT_API.json @@ -2180,6 +2180,28 @@ "moduleName": "CopyButton", "filePath": "src/CopyButton/CopyButton.svelte", "props": [ + { + "name": "feedback", + "kind": "let", + "description": "Set the feedback text shown after clicking the button", + "type": "string", + "value": "\"Copied!\"", + "isFunction": false, + "isFunctionDeclaration": false, + "constant": false, + "reactive": false + }, + { + "name": "feedbackTimeout", + "kind": "let", + "description": "Set the timeout duration (ms) to display feedback text", + "type": "number", + "value": "2000", + "isFunction": false, + "isFunctionDeclaration": false, + "constant": false, + "reactive": false + }, { "name": "iconDescription", "kind": "let", @@ -2216,16 +2238,12 @@ "moduleExports": [], "slots": [], "events": [ - { "type": "forwarded", "name": "click", "element": "Copy" }, - { "type": "forwarded", "name": "animationend", "element": "Copy" }, + { "type": "forwarded", "name": "click", "element": "button" }, + { "type": "forwarded", "name": "animationend", "element": "button" }, { "type": "dispatched", "name": "copy" } ], "typedefs": [], - "rest_props": { "type": "InlineComponent", "name": "Copy" }, - "extends": { - "interface": "CopyProps", - "import": "\"../Copy/Copy.svelte\"" - } + "rest_props": { "type": "Element", "name": "button" } }, { "moduleName": "DataTable", diff --git a/src/CodeSnippet/CodeSnippet.svelte b/src/CodeSnippet/CodeSnippet.svelte index 64add0c3..1ab20730 100644 --- a/src/CodeSnippet/CodeSnippet.svelte +++ b/src/CodeSnippet/CodeSnippet.svelte @@ -88,15 +88,18 @@ /** Obtain a reference to the pre HTML element */ export let ref = null; - import { createEventDispatcher, tick } from "svelte"; + import { createEventDispatcher, tick, onMount } from "svelte"; import ChevronDown16 from "../icons/ChevronDown16.svelte"; import Button from "../Button/Button.svelte"; - import Copy from "../Copy/Copy.svelte"; import CopyButton from "../CopyButton/CopyButton.svelte"; import CodeSnippetSkeleton from "./CodeSnippetSkeleton.svelte"; const dispatch = createEventDispatcher(); + /** @type {"fade-in" | "fade-out"} */ + let animation = undefined; + let timeout = undefined; + function setShowMoreLess() { const { height } = ref.getBoundingClientRect(); if (height > 0) showMoreLess = ref.getBoundingClientRect().height > 255; @@ -114,6 +117,10 @@ if (code === undefined) setShowMoreLess(); if (code) tick().then(setShowMoreLess); } + + onMount(() => { + return () => clearTimeout(timeout); + }); @@ -144,20 +151,35 @@ {:else} - {code} - + + {/if} {:else}
- /** @extends {"../Copy/Copy.svelte"} CopyProps */ + /** Set the feedback text shown after clicking the button */ + export let feedback = "Copied!"; + + /** Set the timeout duration (ms) to display feedback text */ + export let feedbackTimeout = 2000; /** Set the title and ARIA label for the copy button */ export let iconDescription = "Copy to clipboard"; @@ -22,15 +26,28 @@ } }; - import Copy from "../Copy/Copy.svelte"; + import { createEventDispatcher, onMount } from "svelte"; import Copy16 from "../icons/Copy16.svelte"; - import { createEventDispatcher } from "svelte"; const dispatch = createEventDispatcher(); + + /** @type {"fade-in" | "fade-out"} */ + let animation = undefined; + let timeout = undefined; + + onMount(() => { + return () => clearTimeout(timeout); + }); - { + animation = 'fade-out'; + }, feedbackTimeout); }}" on:animationend + on:animationend="{({ animationName }) => { + if (animationName === 'hide-feedback') { + animation = undefined; + } + }}" > - + + diff --git a/types/CopyButton/CopyButton.svelte.d.ts b/types/CopyButton/CopyButton.svelte.d.ts index 8af33ec5..68e357eb 100644 --- a/types/CopyButton/CopyButton.svelte.d.ts +++ b/types/CopyButton/CopyButton.svelte.d.ts @@ -1,8 +1,20 @@ /// import { SvelteComponentTyped } from "svelte"; -import { CopyProps } from "../Copy/Copy.svelte"; -export interface CopyButtonProps extends CopyProps { +export interface CopyButtonProps + extends svelte.JSX.HTMLAttributes { + /** + * Set the feedback text shown after clicking the button + * @default "Copied!" + */ + feedback?: string; + + /** + * Set the timeout duration (ms) to display feedback text + * @default 2000 + */ + feedbackTimeout?: number; + /** * Set the title and ARIA label for the copy button * @default "Copy to clipboard"