|
<script lang="ts"> |
|
import { type ComponentType } from "svelte"; |
|
export let Icon: ComponentType; |
|
export let label = ""; |
|
export let show_label = false; |
|
export let pending = false; |
|
export let size: "small" | "large" | "medium" = "small"; |
|
export let padded = true; |
|
export let highlight = false; |
|
export let disabled = false; |
|
export let hasPopup = false; |
|
export let color = "var(--block-label-text-color)"; |
|
export let transparent = false; |
|
export let background = "var(--block-background-fill)"; |
|
$: _color = highlight ? "var(--color-accent)" : color; |
|
</script> |
|
|
|
<button |
|
{disabled} |
|
on:click |
|
aria-label={label} |
|
aria-haspopup={hasPopup} |
|
title={label} |
|
class:pending |
|
class:padded |
|
class:highlight |
|
class:transparent |
|
style:color={!disabled && _color ? _color : "var(--block-label-text-color)"} |
|
style:--bg-color={!disabled ? background : "auto"} |
|
> |
|
{#if show_label}<span>{label}</span>{/if} |
|
<div |
|
class:small={size === "small"} |
|
class:large={size === "large"} |
|
class:medium={size === "medium"} |
|
> |
|
<svelte:component this={Icon} /> |
|
</div> |
|
</button> |
|
|
|
<style> |
|
button { |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
gap: 1px; |
|
z-index: var(--layer-2); |
|
border-radius: var(--radius-xs); |
|
color: var(--block-label-text-color); |
|
border: 1px solid transparent; |
|
padding: var(--spacing-xxs); |
|
} |
|
|
|
button:hover { |
|
background-color: var(--background-fill-secondary); |
|
} |
|
|
|
button[disabled] { |
|
opacity: 0.5; |
|
box-shadow: none; |
|
} |
|
|
|
button[disabled]:hover { |
|
cursor: not-allowed; |
|
} |
|
|
|
.padded { |
|
background: var(--bg-color); |
|
} |
|
|
|
button:hover, |
|
button.highlight { |
|
cursor: pointer; |
|
color: var(--color-accent); |
|
} |
|
|
|
.padded:hover { |
|
color: var(--block-label-text-color); |
|
} |
|
|
|
span { |
|
padding: 0px 1px; |
|
font-size: 10px; |
|
} |
|
|
|
div { |
|
display: flex; |
|
align-items: center; |
|
justify-content: center; |
|
transition: filter 0.2s ease-in-out; |
|
} |
|
|
|
.small { |
|
width: 14px; |
|
height: 14px; |
|
} |
|
|
|
.medium { |
|
width: 20px; |
|
height: 20px; |
|
} |
|
|
|
.large { |
|
width: 22px; |
|
height: 22px; |
|
} |
|
|
|
.pending { |
|
animation: flash 0.5s infinite; |
|
} |
|
|
|
@keyframes flash { |
|
0% { |
|
opacity: 0.5; |
|
} |
|
50% { |
|
opacity: 1; |
|
} |
|
100% { |
|
opacity: 0.5; |
|
} |
|
} |
|
|
|
.transparent { |
|
background: transparent; |
|
border: none; |
|
box-shadow: none; |
|
} |
|
</style> |
|
|