|
<script lang="ts"> |
|
import { Microphone, Upload, Webcam, ImagePaste } from "@gradio/icons"; |
|
|
|
type source_types = "upload" | "microphone" | "webcam" | "clipboard" | null; |
|
|
|
export let sources: Partial<source_types>[]; |
|
export let active_source: Partial<source_types>; |
|
export let handle_clear: () => void = () => {}; |
|
export let handle_select: ( |
|
source_type: Partial<source_types> |
|
) => void = () => {}; |
|
|
|
$: unique_sources = [...new Set(sources)]; |
|
|
|
async function handle_select_source( |
|
source: Partial<source_types> |
|
): Promise<void> { |
|
handle_clear(); |
|
active_source = source; |
|
handle_select(source); |
|
} |
|
</script> |
|
|
|
{#if unique_sources.length > 1} |
|
<span class="source-selection" data-testid="source-select"> |
|
{#if sources.includes("upload")} |
|
<button |
|
class="icon" |
|
class:selected={active_source === "upload" || !active_source} |
|
aria-label="Upload file" |
|
on:click={() => handle_select_source("upload")}><Upload /></button |
|
> |
|
{/if} |
|
|
|
{#if sources.includes("microphone")} |
|
<button |
|
class="icon" |
|
class:selected={active_source === "microphone"} |
|
aria-label="Record audio" |
|
on:click={() => handle_select_source("microphone")} |
|
><Microphone /></button |
|
> |
|
{/if} |
|
|
|
{#if sources.includes("webcam")} |
|
<button |
|
class="icon" |
|
class:selected={active_source === "webcam"} |
|
aria-label="Capture from camera" |
|
on:click={() => handle_select_source("webcam")}><Webcam /></button |
|
> |
|
{/if} |
|
{#if sources.includes("clipboard")} |
|
<button |
|
class="icon" |
|
class:selected={active_source === "clipboard"} |
|
aria-label="Paste from clipboard" |
|
on:click={() => handle_select_source("clipboard")} |
|
><ImagePaste /></button |
|
> |
|
{/if} |
|
</span> |
|
{/if} |
|
|
|
<style> |
|
.source-selection { |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
border-top: 1px solid var(--border-color-primary); |
|
width: 100%; |
|
margin-left: auto; |
|
margin-right: auto; |
|
height: var(--size-10); |
|
} |
|
|
|
.icon { |
|
width: 22px; |
|
height: 22px; |
|
margin: var(--spacing-lg) var(--spacing-xs); |
|
padding: var(--spacing-xs); |
|
color: var(--neutral-400); |
|
border-radius: var(--radius-md); |
|
} |
|
|
|
.selected { |
|
color: var(--color-accent); |
|
} |
|
|
|
.icon:hover, |
|
.icon:focus { |
|
color: var(--color-accent); |
|
} |
|
</style> |
|
|