big buttons
This commit is contained in:
@@ -54,6 +54,8 @@
|
|||||||
X,
|
X,
|
||||||
} from "@lucide/svelte";
|
} from "@lucide/svelte";
|
||||||
|
|
||||||
|
const iconClass = "icon-btn";
|
||||||
|
|
||||||
let audioEl: HTMLAudioElement | null = null;
|
let audioEl: HTMLAudioElement | null = null;
|
||||||
|
|
||||||
// Best-effort preload of the upcoming track's URL
|
// Best-effort preload of the upcoming track's URL
|
||||||
@@ -468,16 +470,16 @@
|
|||||||
>
|
>
|
||||||
<div class="mx-auto flex max-w-4xl items-center gap-2 px-3 py-2">
|
<div class="mx-auto flex max-w-4xl items-center gap-2 px-3 py-2">
|
||||||
<button
|
<button
|
||||||
class="inline-flex h-8 w-8 items-center justify-center rounded border"
|
class="btn-icon"
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => toggleUiOpen()}
|
onclick={() => toggleUiOpen()}
|
||||||
aria-label={snap.uiOpen ? "Close player" : "Open player"}
|
aria-label={snap.uiOpen ? "Close player" : "Open player"}
|
||||||
title={snap.uiOpen ? "Close player" : "Open player"}
|
title={snap.uiOpen ? "Close player" : "Open player"}
|
||||||
>
|
>
|
||||||
{#if snap.uiOpen}
|
{#if snap.uiOpen}
|
||||||
<X class="h-4 w-4" />
|
<X class={iconClass} />
|
||||||
{:else}
|
{:else}
|
||||||
<ChevronsUpDown class="h-4 w-4" />
|
<ChevronsUpDown class={iconClass} />
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@@ -549,7 +551,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="inline-flex h-8 w-8 items-center justify-center rounded border"
|
class="btn-icon"
|
||||||
type="button"
|
type="button"
|
||||||
disabled={!canPrev}
|
disabled={!canPrev}
|
||||||
aria-label="Previous"
|
aria-label="Previous"
|
||||||
@@ -559,11 +561,11 @@
|
|||||||
void syncAndAutoplay();
|
void syncAndAutoplay();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SkipBack class="h-4 w-4" />
|
<SkipBack class={iconClass} />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="inline-flex h-8 w-8 items-center justify-center rounded border"
|
class="btn-icon"
|
||||||
type="button"
|
type="button"
|
||||||
aria-label={isPlaying ? "Pause" : "Play"}
|
aria-label={isPlaying ? "Pause" : "Play"}
|
||||||
title={isPlaying ? "Pause" : "Play"}
|
title={isPlaying ? "Pause" : "Play"}
|
||||||
@@ -575,14 +577,14 @@
|
|||||||
disabled={!snap.currentTrack}
|
disabled={!snap.currentTrack}
|
||||||
>
|
>
|
||||||
{#if isPlaying}
|
{#if isPlaying}
|
||||||
<PauseIcon class="h-4 w-4" />
|
<PauseIcon class={iconClass} />
|
||||||
{:else}
|
{:else}
|
||||||
<PlayIcon class="h-4 w-4" />
|
<PlayIcon class={iconClass} />
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="inline-flex h-8 w-8 items-center justify-center rounded border"
|
class="btn-icon"
|
||||||
type="button"
|
type="button"
|
||||||
disabled={!canNext}
|
disabled={!canNext}
|
||||||
aria-label="Next"
|
aria-label="Next"
|
||||||
@@ -592,7 +594,7 @@
|
|||||||
void syncAndAutoplay();
|
void syncAndAutoplay();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SkipForward class="h-4 w-4" />
|
<SkipForward class={iconClass} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -603,7 +605,7 @@
|
|||||||
<div class="flex flex-wrap items-center gap-2 pb-3">
|
<div class="flex flex-wrap items-center gap-2 pb-3">
|
||||||
<button
|
<button
|
||||||
class={[
|
class={[
|
||||||
"inline-flex h-8 w-8 items-center justify-center rounded border transition-colors",
|
"btn-icon transition-colors",
|
||||||
snap.shuffleEnabled &&
|
snap.shuffleEnabled &&
|
||||||
"border-primary/40 bg-primary/10 text-primary",
|
"border-primary/40 bg-primary/10 text-primary",
|
||||||
]
|
]
|
||||||
@@ -614,11 +616,11 @@
|
|||||||
aria-label={snap.shuffleEnabled ? "Shuffle on" : "Shuffle off"}
|
aria-label={snap.shuffleEnabled ? "Shuffle on" : "Shuffle off"}
|
||||||
title={snap.shuffleEnabled ? "Shuffle on" : "Shuffle off"}
|
title={snap.shuffleEnabled ? "Shuffle on" : "Shuffle off"}
|
||||||
>
|
>
|
||||||
<Shuffle class="h-4 w-4" />
|
<Shuffle class={iconClass} />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class={[
|
class={[
|
||||||
"inline-flex h-8 w-8 items-center justify-center rounded border transition-colors",
|
"btn-icon transition-colors",
|
||||||
snap.wrapEnabled &&
|
snap.wrapEnabled &&
|
||||||
"border-primary/40 bg-primary/10 text-primary",
|
"border-primary/40 bg-primary/10 text-primary",
|
||||||
]
|
]
|
||||||
@@ -629,18 +631,18 @@
|
|||||||
aria-label={snap.wrapEnabled ? "Wrap on" : "Wrap off"}
|
aria-label={snap.wrapEnabled ? "Wrap on" : "Wrap off"}
|
||||||
title={snap.wrapEnabled ? "Wrap on" : "Wrap off"}
|
title={snap.wrapEnabled ? "Wrap on" : "Wrap off"}
|
||||||
>
|
>
|
||||||
<Repeat class="h-4 w-4" />
|
<Repeat class={iconClass} />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<AlertDialog.Root bind:open={clearQueueDialogOpen}>
|
<AlertDialog.Root bind:open={clearQueueDialogOpen}>
|
||||||
<AlertDialog.Trigger
|
<AlertDialog.Trigger
|
||||||
class="inline-flex h-8 w-8 items-center justify-center rounded border"
|
class="btn-icon"
|
||||||
type="button"
|
type="button"
|
||||||
disabled={snap.queue.length === 0}
|
disabled={snap.queue.length === 0}
|
||||||
aria-label="Clear queue"
|
aria-label="Clear queue"
|
||||||
title="Clear queue"
|
title="Clear queue"
|
||||||
>
|
>
|
||||||
<Trash2 class="h-4 w-4" />
|
<Trash2 class={iconClass} />
|
||||||
</AlertDialog.Trigger>
|
</AlertDialog.Trigger>
|
||||||
|
|
||||||
<AlertDialog.Content>
|
<AlertDialog.Content>
|
||||||
@@ -667,7 +669,7 @@
|
|||||||
|
|
||||||
<label class="ml-auto flex items-center gap-2 text-sm">
|
<label class="ml-auto flex items-center gap-2 text-sm">
|
||||||
<span class="text-muted-foreground" aria-hidden="true">
|
<span class="text-muted-foreground" aria-hidden="true">
|
||||||
<Volume2 class="h-4 w-4" />
|
<Volume2 class={iconClass} />
|
||||||
</span>
|
</span>
|
||||||
<span class="sr-only">Volume</span>
|
<span class="sr-only">Volume</span>
|
||||||
<input
|
<input
|
||||||
@@ -737,13 +739,13 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="inline-flex h-8 w-8 items-center justify-center rounded border"
|
class="btn-icon"
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => removeTrack(item.track.id)}
|
onclick={() => removeTrack(item.track.id)}
|
||||||
aria-label="Remove from queue"
|
aria-label="Remove from queue"
|
||||||
title="Remove from queue"
|
title="Remove from queue"
|
||||||
>
|
>
|
||||||
<ListX class="h-4 w-4" />
|
<ListX class={iconClass} />
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
{/each}
|
{/each}
|
||||||
@@ -795,16 +797,16 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="inline-flex h-8 w-8 items-center justify-center rounded border"
|
class="btn-icon"
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => toggleUiOpen()}
|
onclick={() => toggleUiOpen()}
|
||||||
aria-label={snap.uiOpen ? "Hide player sidebar" : "Show player sidebar"}
|
aria-label={snap.uiOpen ? "Hide player sidebar" : "Show player sidebar"}
|
||||||
title={snap.uiOpen ? "Hide player sidebar" : "Show player sidebar"}
|
title={snap.uiOpen ? "Hide player sidebar" : "Show player sidebar"}
|
||||||
>
|
>
|
||||||
{#if snap.uiOpen}
|
{#if snap.uiOpen}
|
||||||
<PanelRightClose class="h-4 w-4" />
|
<PanelRightClose class={iconClass} />
|
||||||
{:else}
|
{:else}
|
||||||
<PanelRightOpen class="h-4 w-4" />
|
<PanelRightOpen class={iconClass} />
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -819,7 +821,7 @@
|
|||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<button
|
<button
|
||||||
class={[
|
class={[
|
||||||
"inline-flex h-8 w-8 items-center justify-center rounded border transition-colors",
|
"btn-icon transition-colors",
|
||||||
snap.shuffleEnabled &&
|
snap.shuffleEnabled &&
|
||||||
"border-primary/40 bg-primary/10 text-primary",
|
"border-primary/40 bg-primary/10 text-primary",
|
||||||
]
|
]
|
||||||
@@ -830,11 +832,11 @@
|
|||||||
aria-label={snap.shuffleEnabled ? "Shuffle on" : "Shuffle off"}
|
aria-label={snap.shuffleEnabled ? "Shuffle on" : "Shuffle off"}
|
||||||
title={snap.shuffleEnabled ? "Shuffle on" : "Shuffle off"}
|
title={snap.shuffleEnabled ? "Shuffle on" : "Shuffle off"}
|
||||||
>
|
>
|
||||||
<Shuffle class="h-4 w-4" />
|
<Shuffle class={iconClass} />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class={[
|
class={[
|
||||||
"inline-flex h-8 w-8 items-center justify-center rounded border transition-colors",
|
"btn-icon transition-colors",
|
||||||
snap.wrapEnabled &&
|
snap.wrapEnabled &&
|
||||||
"border-primary/40 bg-primary/10 text-primary",
|
"border-primary/40 bg-primary/10 text-primary",
|
||||||
]
|
]
|
||||||
@@ -845,18 +847,18 @@
|
|||||||
aria-label={snap.wrapEnabled ? "Wrap on" : "Wrap off"}
|
aria-label={snap.wrapEnabled ? "Wrap on" : "Wrap off"}
|
||||||
title={snap.wrapEnabled ? "Wrap on" : "Wrap off"}
|
title={snap.wrapEnabled ? "Wrap on" : "Wrap off"}
|
||||||
>
|
>
|
||||||
<Repeat class="h-4 w-4" />
|
<Repeat class={iconClass} />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<AlertDialog.Root bind:open={clearQueueDialogOpen}>
|
<AlertDialog.Root bind:open={clearQueueDialogOpen}>
|
||||||
<AlertDialog.Trigger
|
<AlertDialog.Trigger
|
||||||
class="inline-flex h-8 w-8 items-center justify-center rounded border"
|
class="btn-icon"
|
||||||
type="button"
|
type="button"
|
||||||
disabled={snap.queue.length === 0}
|
disabled={snap.queue.length === 0}
|
||||||
aria-label="Clear queue"
|
aria-label="Clear queue"
|
||||||
title="Clear queue"
|
title="Clear queue"
|
||||||
>
|
>
|
||||||
<Trash2 class="h-4 w-4" />
|
<Trash2 class={iconClass} />
|
||||||
</AlertDialog.Trigger>
|
</AlertDialog.Trigger>
|
||||||
|
|
||||||
<AlertDialog.Content>
|
<AlertDialog.Content>
|
||||||
@@ -898,7 +900,7 @@
|
|||||||
|
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<button
|
<button
|
||||||
class="inline-flex h-8 w-8 items-center justify-center rounded border"
|
class="btn-icon"
|
||||||
type="button"
|
type="button"
|
||||||
disabled={!canPrev}
|
disabled={!canPrev}
|
||||||
aria-label="Previous"
|
aria-label="Previous"
|
||||||
@@ -908,11 +910,11 @@
|
|||||||
void syncAndAutoplay();
|
void syncAndAutoplay();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SkipBack class="h-4 w-4" />
|
<SkipBack class={iconClass} />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="inline-flex h-8 w-8 items-center justify-center rounded border"
|
class="btn-icon"
|
||||||
type="button"
|
type="button"
|
||||||
aria-label={isPlaying ? "Pause" : "Play"}
|
aria-label={isPlaying ? "Pause" : "Play"}
|
||||||
title={isPlaying ? "Pause" : "Play"}
|
title={isPlaying ? "Pause" : "Play"}
|
||||||
@@ -924,14 +926,14 @@
|
|||||||
disabled={!snap.currentTrack}
|
disabled={!snap.currentTrack}
|
||||||
>
|
>
|
||||||
{#if isPlaying}
|
{#if isPlaying}
|
||||||
<PauseIcon class="h-4 w-4" />
|
<PauseIcon class={iconClass} />
|
||||||
{:else}
|
{:else}
|
||||||
<PlayIcon class="h-4 w-4" />
|
<PlayIcon class={iconClass} />
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="inline-flex h-8 w-8 items-center justify-center rounded border"
|
class="btn-icon"
|
||||||
type="button"
|
type="button"
|
||||||
disabled={!canNext}
|
disabled={!canNext}
|
||||||
aria-label="Next"
|
aria-label="Next"
|
||||||
@@ -941,12 +943,12 @@
|
|||||||
void syncAndAutoplay();
|
void syncAndAutoplay();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SkipForward class="h-4 w-4" />
|
<SkipForward class={iconClass} />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<label class="ml-auto flex items-center gap-2 text-sm">
|
<label class="ml-auto flex items-center gap-2 text-sm">
|
||||||
<span class="text-muted-foreground" aria-hidden="true">
|
<span class="text-muted-foreground" aria-hidden="true">
|
||||||
<Volume2 class="h-4 w-4" />
|
<Volume2 class={iconClass} />
|
||||||
</span>
|
</span>
|
||||||
<span class="sr-only">Volume</span>
|
<span class="sr-only">Volume</span>
|
||||||
<input
|
<input
|
||||||
@@ -1010,13 +1012,13 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="inline-flex h-8 w-8 items-center justify-center rounded border"
|
class="btn-icon"
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => removeTrack(item.track.id)}
|
onclick={() => removeTrack(item.track.id)}
|
||||||
aria-label="Remove from queue"
|
aria-label="Remove from queue"
|
||||||
title="Remove from queue"
|
title="Remove from queue"
|
||||||
>
|
>
|
||||||
<ListX class="h-4 w-4" />
|
<ListX class={iconClass} />
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
@@ -83,7 +83,7 @@
|
|||||||
<div class="mt-2 flex flex-wrap items-center gap-2">
|
<div class="mt-2 flex flex-wrap items-center gap-2">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="inline-flex h-8 w-8 items-center justify-center rounded border"
|
class="btn-icon"
|
||||||
disabled={!track}
|
disabled={!track}
|
||||||
title="Play"
|
title="Play"
|
||||||
aria-label="Play"
|
aria-label="Play"
|
||||||
@@ -93,12 +93,12 @@
|
|||||||
requestGlobalAutoplay();
|
requestGlobalAutoplay();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<PlayIcon class="h-4 w-4" />
|
<PlayIcon class="icon-btn" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="inline-flex h-8 w-8 items-center justify-center rounded border"
|
class="btn-icon"
|
||||||
disabled={!track}
|
disabled={!track}
|
||||||
title="Play next"
|
title="Play next"
|
||||||
aria-label="Play next"
|
aria-label="Play next"
|
||||||
@@ -108,12 +108,12 @@
|
|||||||
requestGlobalAutoplay();
|
requestGlobalAutoplay();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SkipForward class="h-4 w-4" />
|
<SkipForward class="icon-btn" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="inline-flex h-8 w-8 items-center justify-center rounded border"
|
class="btn-icon"
|
||||||
disabled={!track}
|
disabled={!track}
|
||||||
title="Add to queue"
|
title="Add to queue"
|
||||||
aria-label="Add to queue"
|
aria-label="Add to queue"
|
||||||
@@ -122,18 +122,18 @@
|
|||||||
addToQueue(track);
|
addToQueue(track);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ListPlus class="h-4 w-4" />
|
<ListPlus class="icon-btn" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{#if isQueued}
|
{#if isQueued}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="inline-flex h-8 w-8 items-center justify-center rounded border"
|
class="btn-icon"
|
||||||
title="Remove from queue"
|
title="Remove from queue"
|
||||||
aria-label="Remove from queue"
|
aria-label="Remove from queue"
|
||||||
onclick={() => removeTrack(annSongId)}
|
onclick={() => removeTrack(annSongId)}
|
||||||
>
|
>
|
||||||
<Trash2 class="h-4 w-4" />
|
<Trash2 class="icon-btn" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<span class="text-xs text-muted-foreground">Queued</span>
|
<span class="text-xs text-muted-foreground">Queued</span>
|
||||||
|
|||||||
@@ -118,3 +118,20 @@
|
|||||||
@apply bg-background text-foreground;
|
@apply bg-background text-foreground;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@layer utilities {
|
||||||
|
/* Reusable icon sizing utility for Lucide (and similar) icons */
|
||||||
|
.icon-btn {
|
||||||
|
@apply h-6 w-6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Shared sizing/style for icon buttons (hit area). Use alongside `.icon-btn`. */
|
||||||
|
.btn-icon {
|
||||||
|
@apply inline-flex h-10 w-10 items-center justify-center rounded border;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Optional variant: slightly smaller icon button */
|
||||||
|
.btn-icon-sm {
|
||||||
|
@apply inline-flex h-8 w-8 items-center justify-center rounded border;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user