2024-06-28 06:19:00 +01:00
|
|
|
<script>
|
2024-07-08 11:56:26 +01:00
|
|
|
import { playSound } from '../sound.js';
|
2024-06-28 06:19:00 +01:00
|
|
|
import { createEventDispatcher } from 'svelte';
|
2024-07-02 19:38:20 +01:00
|
|
|
import { afterUpdate } from 'svelte';
|
|
|
|
|
2024-06-28 06:19:00 +01:00
|
|
|
const dispatch = createEventDispatcher();
|
|
|
|
|
2025-07-14 01:06:16 +01:00
|
|
|
let className = "";
|
|
|
|
export { className as class };
|
2024-06-28 06:19:00 +01:00
|
|
|
export let active = false;
|
|
|
|
export let filled = false;
|
|
|
|
export let disabled = false;
|
|
|
|
export let centered = false;
|
|
|
|
export let label = undefined;
|
|
|
|
export let sound = "default";
|
2025-07-14 01:06:16 +01:00
|
|
|
export let href = undefined;
|
|
|
|
export let onClick = undefined;
|
2024-06-28 06:19:00 +01:00
|
|
|
|
|
|
|
let classes = [];
|
|
|
|
|
|
|
|
function click() {
|
2024-07-02 12:40:39 +01:00
|
|
|
if (disabled) return;
|
2024-07-08 11:56:26 +01:00
|
|
|
playSound(sound);
|
2024-06-28 06:19:00 +01:00
|
|
|
dispatch('click');
|
|
|
|
}
|
2024-07-02 19:38:20 +01:00
|
|
|
|
|
|
|
afterUpdate(() => {
|
2025-07-14 01:06:16 +01:00
|
|
|
classes = className.split(' ');
|
|
|
|
if (active) classes.push("active");
|
|
|
|
if (filled) classes.push("filled");
|
|
|
|
if (disabled) classes.push("disabled");
|
2024-07-02 19:38:20 +01:00
|
|
|
if (centered) classes.push("centered");
|
|
|
|
});
|
2024-06-28 06:19:00 +01:00
|
|
|
</script>
|
|
|
|
|
2025-07-14 01:06:16 +01:00
|
|
|
{#if href}
|
|
|
|
<a
|
|
|
|
class={classes.join(' ')}
|
|
|
|
title={label}
|
|
|
|
aria-label={label}
|
|
|
|
href={href}
|
|
|
|
on:click={() => click()}>
|
|
|
|
<span class="icon">
|
|
|
|
<slot name="icon" />
|
|
|
|
</span>
|
|
|
|
<slot/>
|
|
|
|
</a>
|
|
|
|
{:else}
|
|
|
|
<button
|
|
|
|
type="button"
|
|
|
|
class={classes.join(' ')}
|
|
|
|
title={label}
|
|
|
|
aria-label={label}
|
|
|
|
on:click={() => click()}>
|
|
|
|
<span class="icon">
|
|
|
|
<slot name="icon" />
|
|
|
|
</span>
|
|
|
|
<slot/>
|
|
|
|
</button>
|
|
|
|
{/if}
|
2024-06-28 06:19:00 +01:00
|
|
|
|
|
|
|
<style>
|
2025-07-14 01:06:16 +01:00
|
|
|
a, button {
|
2025-07-10 22:32:54 +01:00
|
|
|
height: fit-content;
|
|
|
|
padding: .7em .8em;
|
2024-06-28 06:19:00 +01:00
|
|
|
display: flex;
|
|
|
|
flex-direction: row;
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
font-family: inherit;
|
|
|
|
font-size: 1rem;
|
|
|
|
font-weight: 600;
|
|
|
|
text-align: left;
|
2025-07-14 01:06:16 +01:00
|
|
|
text-decoration: none;
|
2024-06-28 06:19:00 +01:00
|
|
|
|
|
|
|
border-radius: 8px;
|
2025-07-10 22:32:54 +01:00
|
|
|
border: 2px solid var(--bg-700);
|
2024-06-28 06:19:00 +01:00
|
|
|
|
2025-07-13 15:41:56 +01:00
|
|
|
background-color: var(--bg-700);
|
2024-06-28 06:19:00 +01:00
|
|
|
color: var(--text);
|
|
|
|
|
|
|
|
transition-property: border-color, background-color, color;
|
|
|
|
transition-timing-function: ease-out;
|
|
|
|
transition-duration: .1s;
|
|
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
}
|
2025-07-14 01:06:16 +01:00
|
|
|
a {
|
|
|
|
width: calc(100% - 1.6em);
|
|
|
|
}
|
|
|
|
button {
|
|
|
|
width: 100%;
|
|
|
|
}
|
2024-06-28 06:19:00 +01:00
|
|
|
|
2025-07-14 01:06:16 +01:00
|
|
|
a.centered,
|
2024-06-28 06:19:00 +01:00
|
|
|
button.centered {
|
|
|
|
text-align: center;
|
|
|
|
justify-content: center;
|
|
|
|
}
|
|
|
|
|
2025-07-14 01:06:16 +01:00
|
|
|
a:hover,
|
2024-06-28 06:19:00 +01:00
|
|
|
button:hover {
|
2025-07-13 15:41:56 +01:00
|
|
|
border-color: color-mix(in srgb, var(--bg-700), black 10%);
|
|
|
|
background-color: color-mix(in srgb, var(--bg-700), black 10%);
|
2024-06-28 06:19:00 +01:00
|
|
|
}
|
|
|
|
|
2025-07-14 01:06:16 +01:00
|
|
|
a:active,
|
2024-06-28 06:19:00 +01:00
|
|
|
button:active {
|
2025-07-13 15:41:56 +01:00
|
|
|
border-color: color-mix(in srgb, var(--bg-700), black 20%);
|
|
|
|
background-color: color-mix(in srgb, var(--bg-700), black 20%);
|
2024-06-28 06:19:00 +01:00
|
|
|
}
|
|
|
|
|
2025-07-14 01:06:16 +01:00
|
|
|
a.active,
|
2024-06-28 06:19:00 +01:00
|
|
|
button.active {
|
|
|
|
background-color: var(--bg-600);
|
|
|
|
color: var(--accent);
|
|
|
|
border-color: var(--accent);
|
|
|
|
text-shadow: 0px 2px 32px var(--accent);
|
|
|
|
}
|
|
|
|
|
2025-07-14 01:06:16 +01:00
|
|
|
a.active:hover,
|
2024-06-28 06:19:00 +01:00
|
|
|
button.active:hover {
|
|
|
|
color: color-mix(in srgb, var(--accent), var(--bg-1000) 20%);
|
|
|
|
border-color: color-mix(in srgb, var(--accent), var(--bg-1000) 20%);
|
|
|
|
background-color: color-mix(in srgb, var(--bg-600), var(--accent) 10%);
|
|
|
|
}
|
|
|
|
|
2025-07-14 01:06:16 +01:00
|
|
|
a.active:active,
|
2024-06-28 06:19:00 +01:00
|
|
|
button.active:active {
|
|
|
|
color: color-mix(in srgb, var(--accent), var(--bg-800) 10%);
|
|
|
|
border-color: color-mix(in srgb, var(--accent), var(--bg-800) 10%);
|
|
|
|
background-color: color-mix(in srgb, var(--bg-600), var(--bg-800) 10%);
|
|
|
|
}
|
|
|
|
|
2025-07-14 01:06:16 +01:00
|
|
|
a.filled,
|
2024-06-28 06:19:00 +01:00
|
|
|
button.filled {
|
|
|
|
background-color: var(--accent);
|
|
|
|
color: var(--bg-800);
|
|
|
|
border-color: transparent;
|
|
|
|
}
|
|
|
|
|
2025-07-14 04:12:20 +01:00
|
|
|
a.filled:not(.disabled):hover,
|
|
|
|
button.filled:not(.disabled):hover {
|
2024-06-28 06:19:00 +01:00
|
|
|
color: color-mix(in srgb, var(--bg-800), white 10%);
|
|
|
|
background-color: color-mix(in srgb, var(--accent), white 20%);
|
|
|
|
}
|
|
|
|
|
2025-07-14 04:12:20 +01:00
|
|
|
a.filled:not(.disabled):active,
|
|
|
|
button.filled:not(.disabled):active {
|
2024-06-28 06:19:00 +01:00
|
|
|
color: color-mix(in srgb, var(--bg-800), black 10%);
|
|
|
|
background-color: color-mix(in srgb, var(--accent), black 20%);
|
|
|
|
}
|
|
|
|
|
2025-07-14 01:06:16 +01:00
|
|
|
a.disabled,
|
2024-06-28 06:19:00 +01:00
|
|
|
button.disabled {
|
|
|
|
color: var(--text);
|
2025-07-14 18:48:31 +01:00
|
|
|
opacity: .35;
|
2024-06-28 06:19:00 +01:00
|
|
|
border-color: transparent;
|
2025-07-14 04:12:20 +01:00
|
|
|
cursor: not-allowed;
|
2024-06-28 06:19:00 +01:00
|
|
|
}
|
|
|
|
|
2024-06-30 19:57:32 +01:00
|
|
|
.icon:not(:empty) {
|
2025-07-10 22:32:54 +01:00
|
|
|
height: 1.8em;
|
2024-06-30 19:57:32 +01:00
|
|
|
margin-right: 8px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.icon :global(svg) {
|
|
|
|
height: 100%;
|
|
|
|
}
|
|
|
|
|
|
|
|
.centered .icon {
|
|
|
|
margin-right: 0px;
|
|
|
|
}
|
2024-06-28 06:19:00 +01:00
|
|
|
</style>
|