refactor: Copy To Clipboard Icon component

This commit is contained in:
Aleksander Grygier 2025-11-23 23:23:38 +01:00
parent 219fd19eb8
commit e92ce07916
4 changed files with 35 additions and 18 deletions

View File

@ -3,6 +3,7 @@
ChatMessageActions,
ChatMessageStatistics,
ChatMessageThinkingBlock,
CopyToClipboardIcon,
MarkdownContent,
SelectorModel
} from '$lib/components/app';
@ -10,7 +11,7 @@
import { isLoading } from '$lib/stores/chat.svelte';
import autoResizeTextarea from '$lib/utils/autoresize-textarea';
import { fade } from 'svelte/transition';
import { Check, Copy, X, Wrench } from '@lucide/svelte';
import { Check, X, Wrench } from '@lucide/svelte';
import { Button } from '$lib/components/ui/button';
import { Checkbox } from '$lib/components/ui/checkbox';
import { INPUT_CLASSES } from '$lib/constants/input-classes';
@ -264,7 +265,7 @@
onclick={handleCopyModel}
>
{displayedModel()}
<Copy class="ml-1 h-3 w-3" />
<CopyToClipboardIcon text={displayedModel() || ''} ariaLabel="Copy model name" />
</button>
{/if}
@ -297,8 +298,10 @@
onclick={() => handleCopyToolCall(badge.copyValue)}
>
{badge.label}
<Copy class="ml-1 h-3 w-3" />
<CopyToClipboardIcon
text={badge.copyValue}
ariaLabel={`Copy tool call ${badge.label}`}
/>
</button>
{/each}
{:else if fallbackToolCalls}
@ -310,8 +313,7 @@
onclick={() => handleCopyToolCall(fallbackToolCalls)}
>
{fallbackToolCalls}
<Copy class="ml-1 h-3 w-3" />
<CopyToClipboardIcon text={fallbackToolCalls} ariaLabel="Copy tool call payload" />
</button>
{/if}
</span>

View File

@ -1,12 +1,10 @@
<script lang="ts">
import * as Dialog from '$lib/components/ui/dialog';
import * as Table from '$lib/components/ui/table';
import { BadgeModality } from '$lib/components/app';
import { BadgeModality, CopyToClipboardIcon } from '$lib/components/app';
import { serverStore } from '$lib/stores/server.svelte';
import { ChatService } from '$lib/services/chat';
import type { ApiModelListResponse } from '$lib/types/api';
import { Copy } from '@lucide/svelte';
import { copyToClipboard } from '$lib/utils/copy';
import { formatFileSize, formatParameters, formatNumber } from '$lib/utils/formatters';
interface Props {
@ -82,11 +80,10 @@
{serverStore.modelName}
</span>
<Copy
class="h-3 w-3 flex-shrink-0 cursor-pointer"
aria-label="Copy model name to clipboard"
onclick={() =>
serverStore.modelName && copyToClipboard(serverStore.modelName)}
<CopyToClipboardIcon
text={serverStore.modelName || ''}
canCopy={!!serverStore.modelName}
ariaLabel="Copy model name to clipboard"
/>
</div>
</Table.Head>
@ -107,10 +104,9 @@
{serverProps.model_path}
</span>
<Copy
class="h-3 w-3 flex-shrink-0"
aria-label="Copy model path to clipboard"
onclick={() => copyToClipboard(serverProps.model_path)}
<CopyToClipboardIcon
text={serverProps.model_path}
ariaLabel="Copy model path to clipboard"
/>
</Table.Cell>
</Table.Row>

View File

@ -56,6 +56,7 @@ export { default as ActionDropdown } from './misc/ActionDropdown.svelte';
export { default as BadgeModelName } from './misc/BadgeModelName.svelte';
export { default as BadgeModality } from './misc/BadgeModality.svelte';
export { default as ConversationSelection } from './misc/ConversationSelection.svelte';
export { default as CopyToClipboardIcon } from './misc/CopyToClipboardIcon.svelte';
export { default as KeyboardShortcutInfo } from './misc/KeyboardShortcutInfo.svelte';
export { default as MarkdownContent } from './misc/MarkdownContent.svelte';
export { default as RemoveButton } from './misc/RemoveButton.svelte';

View File

@ -0,0 +1,18 @@
<script lang="ts">
import { Copy } from '@lucide/svelte';
import { copyToClipboard } from '$lib/utils/copy';
interface Props {
ariaLabel?: string;
canCopy?: boolean;
text: string;
}
let { ariaLabel = 'Copy to clipboard', canCopy = true, text }: Props = $props();
</script>
<Copy
class="h-3 w-3 flex-shrink-0 cursor-{canCopy ? 'pointer' : 'not-allowed'}"
aria-label={ariaLabel}
onclick={() => canCopy && copyToClipboard(text)}
/>