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

View File

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