Skip to main content

Overview

The ButtonUuidCopy component displays a UUID (or any string) in a shortened format and copies the full value to the clipboard when clicked. It’s ideal for displaying identifiers in a compact, user-friendly way.

Import

import { ButtonUuidCopy } from '@invopop/popui'

Props

uuid
string
default:"''"
The UUID or string to display and copy. The full value is copied to clipboard on click.
prefixLength
number
default:"4"
Number of characters to show from the beginning of the UUID.
suffixLength
number
default:"4"
Number of characters to show from the end of the UUID.
full
boolean
default:"false"
When true, displays the entire UUID without shortening.
disabled
boolean
default:"false"
Whether the button is disabled. Disabled buttons cannot be clicked and have reduced opacity.
oncopied
(label: string) => void
Callback function triggered after the UUID is successfully copied to clipboard. Receives the copied UUID as an argument.

Basic Usage

<script>
  let userId = '550e8400-e29b-41d4-a716-446655440000'

  function handleCopied(uuid) {
    console.log('Copied:', uuid)
    // Show toast notification, etc.
  }
</script>

<ButtonUuidCopy
  uuid={userId}
  oncopied={handleCopied}
/>
Displays: 550e...0000 with a duplicate icon Source reference: /home/daytona/workspace/source/svelte/src/lib/ButtonUuidCopy.svelte:1-44

Formatting Options

Shows 4 characters from start and end:
<ButtonUuidCopy
  uuid="550e8400-e29b-41d4-a716-446655440000"
/>
Displays: 550e...0000Source reference: /home/daytona/workspace/source/svelte/src/lib/ButtonUuidCopy.svelte:8-9

Button Styling

The component uses these fixed button properties:
  • Variant: ghost - Transparent background with hover effect
  • Size: sm - Small button (24px height)
  • Icon: Duplicate icon positioned on the right
  • Font: Monospace for consistent UUID display
Source reference: /home/daytona/workspace/source/svelte/src/lib/ButtonUuidCopy.svelte:29-35

Event Handlers

Copy Handler

The component automatically copies the full UUID to clipboard when clicked:
<script>
  let documentId = '550e8400-e29b-41d4-a716-446655440000'
  let copyStatus = $state('')

  function handleCopied(uuid) {
    copyStatus = 'Copied!'
    setTimeout(() => {
      copyStatus = ''
    }, 2000)
  }
</script>

<div class="flex items-center gap-2">
  <ButtonUuidCopy
    uuid={documentId}
    oncopied={handleCopied}
  />
  {#if copyStatus}
    <span class="text-sm text-foreground-success">{copyStatus}</span>
  {/if}
</div>
Source reference: /home/daytona/workspace/source/svelte/src/lib/ButtonUuidCopy.svelte:36-40

Stop Propagation

The click event automatically stops propagation to prevent triggering parent element handlers:
<div onclick={() => console.log('parent clicked')}>
  <ButtonUuidCopy
    uuid="550e8400-e29b-41d4-a716-446655440000"
  />
  <!-- Clicking the button won't trigger the parent div's onclick -->
</div>
Source reference: /home/daytona/workspace/source/svelte/src/lib/ButtonUuidCopy.svelte:37

States

Disabled State

Disable the button to prevent copying:
<ButtonUuidCopy
  uuid="550e8400-e29b-41d4-a716-446655440000"
  disabled
/>
Source reference: /home/daytona/workspace/source/svelte/src/lib/ButtonUuidCopy.svelte:30

Advanced Examples

With Toast Notification

<script>
  import { toast } from '@invopop/popui'

  let recordId = '550e8400-e29b-41d4-a716-446655440000'

  function handleCopied(uuid) {
    toast.success('ID copied to clipboard', {
      description: uuid
    })
  }
</script>

<ButtonUuidCopy
  uuid={recordId}
  oncopied={handleCopied}
/>

In a Data Table

<script>
  let records = [
    { id: '550e8400-e29b-41d4-a716-446655440000', name: 'Record 1' },
    { id: '6ba7b810-9dad-11d1-80b4-00c04fd430c8', name: 'Record 2' },
    { id: '6ba7b811-9dad-11d1-80b4-00c04fd430c8', name: 'Record 3' }
  ]

  function handleCopied(uuid) {
    console.log('Copied:', uuid)
  }
</script>

<table>
  <thead>
    <tr>
      <th>ID</th>
      <th>Name</th>
    </tr>
  </thead>
  <tbody>
    {#each records as record}
      <tr>
        <td>
          <ButtonUuidCopy
            uuid={record.id}
            oncopied={handleCopied}
          />
        </td>
        <td>{record.name}</td>
      </tr>
    {/each}
  </tbody>
</table>

With Different Formats

<script>
  let transactionId = '550e8400-e29b-41d4-a716-446655440000'
  let shortId = 'TXN-12345'
  let hashId = 'a1b2c3d4e5f6g7h8i9j0'
</script>

<div class="flex flex-col gap-2">
  <!-- Standard UUID -->
  <div>
    <span class="text-sm">Transaction:</span>
    <ButtonUuidCopy uuid={transactionId} />
  </div>

  <!-- Short ID (shown in full) -->
  <div>
    <span class="text-sm">Reference:</span>
    <ButtonUuidCopy uuid={shortId} />
  </div>

  <!-- Hash with more context -->
  <div>
    <span class="text-sm">Hash:</span>
    <ButtonUuidCopy
      uuid={hashId}
      prefixLength={6}
      suffixLength={6}
    />
  </div>
</div>

Conditional Display

<script>
  let user = {
    id: '550e8400-e29b-41d4-a716-446655440000',
    role: 'admin',
    canViewIds: true
  }
</script>

{#if user.canViewIds}
  <ButtonUuidCopy
    uuid={user.id}
    disabled={user.role !== 'admin'}
  />
{:else}
  <span class="text-sm text-foreground-default-secondary">
    ID hidden
  </span>
{/if}

With Copy Analytics

<script>
  let documentId = '550e8400-e29b-41d4-a716-446655440000'

  function handleCopied(uuid) {
    // Track copy event
    analytics.track('UUID Copied', {
      uuid: uuid,
      location: 'document-details',
      timestamp: new Date().toISOString()
    })

    // Show confirmation
    console.log('UUID copied:', uuid)
  }
</script>

<ButtonUuidCopy
  uuid={documentId}
  oncopied={handleCopied}
/>

Multiple Formats in One View

<script>
  let orderId = '550e8400-e29b-41d4-a716-446655440000'
  let showFull = $state(false)
</script>

<div class="flex items-center gap-2">
  <ButtonUuidCopy
    uuid={orderId}
    full={showFull}
  />
  <button
    onclick={() => showFull = !showFull}
    class="text-sm text-foreground-accent"
  >
    {showFull ? 'Show Less' : 'Show Full'}
  </button>
</div>

Clipboard API

The component uses the modern Clipboard API with async/await:
await navigator.clipboard.writeText(uuid)
Source reference: /home/daytona/workspace/source/svelte/src/lib/ButtonUuidCopy.svelte:38

Accessibility

  • Uses semantic button element from BaseButton
  • Monospace font ensures consistent character spacing
  • Ghost variant provides clear hover and focus states
  • Small size maintains compact layout without sacrificing clickability
  • Disabled state properly prevents interaction
  • Icon position (right) provides clear action affordance

Type Definitions

The component uses TypeScript interfaces defined in types.ts:329-336:
export interface ButtonUuidCopyProps {
  uuid?: string;
  prefixLength?: number;
  suffixLength?: number;
  full?: boolean;
  disabled?: boolean;
  oncopied?: (label: string) => void;
}

Build docs developers (and LLMs) love