Previous fix narrowed `IconProp` to `ComponentType<SvelteComponent<{
size?: number, strokeWidth?: number, class?: string }>>` but Lucide
icons accept `size: string | number` (you can write size="16" or
size={16}), and the resulting structural mismatch surfaces 11 type
errors at every assignment site. Drop the prop-shape constraint
entirely — TrackMenuItem only ever passes numeric values to the icon.
52 lines
1.6 KiB
Svelte
52 lines
1.6 KiB
Svelte
<script lang="ts">
|
|
import type { ComponentType, SvelteComponent } from 'svelte';
|
|
|
|
// Lucide-svelte ships class-based components (typeof ListPlus = ComponentType<...>),
|
|
// not runes-mode function components (Svelte 5's Component<...> type). Use
|
|
// ComponentType<SvelteComponent> with no prop-shape constraint — Lucide
|
|
// accepts size/strokeWidth as `string | number` and a tighter constraint
|
|
// here trips structural assignment. We always pass numeric `size={14}` and
|
|
// `strokeWidth={1}` below so the runtime contract is consistent.
|
|
type IconProp = ComponentType<SvelteComponent>;
|
|
|
|
let {
|
|
icon,
|
|
label,
|
|
onclick,
|
|
disabled = false,
|
|
danger = false,
|
|
title,
|
|
}: {
|
|
/** Lucide icon component (or any Svelte class-component matching the Lucide signature). */
|
|
icon: IconProp;
|
|
label: string;
|
|
onclick?: () => void;
|
|
disabled?: boolean;
|
|
/** Renders in oxblood for destructive actions ("Remove from library"). */
|
|
danger?: boolean;
|
|
/** Tooltip text — used to explain disabled state ("Coming with playlists"). */
|
|
title?: string;
|
|
} = $props();
|
|
|
|
const Icon = $derived(icon);
|
|
|
|
function fire() {
|
|
if (disabled || !onclick) return;
|
|
onclick();
|
|
}
|
|
</script>
|
|
|
|
<button
|
|
type="button"
|
|
role="menuitem"
|
|
aria-disabled={disabled}
|
|
{title}
|
|
onclick={fire}
|
|
class="flex w-full items-center gap-2 rounded px-2 py-1.5 text-sm
|
|
{disabled ? 'cursor-not-allowed text-text-muted' : 'text-text-primary hover:bg-surface-hover'}
|
|
{danger && !disabled ? 'text-action-destructive' : ''}"
|
|
>
|
|
<Icon size={14} strokeWidth={1} />
|
|
{label}
|
|
</button>
|