2024-06-18 03:52:38 +00:00
|
|
|
<script lang="ts">
|
2025-05-21 18:12:00 +02:00
|
|
|
import type { Shortcut } from '$lib/actions/shortcut';
|
|
|
|
|
import { shortcut as bindShortcut, shortcutLabel as computeShortcutLabel } from '$lib/actions/shortcut';
|
2024-06-18 03:52:38 +00:00
|
|
|
import { optionClickCallbackStore, selectedIdStore } from '$lib/stores/context-menu.store';
|
2025-05-21 18:12:00 +02:00
|
|
|
import { generateId } from '$lib/utils/generate-id';
|
2025-09-16 21:40:43 +02:00
|
|
|
import { Icon } from '@immich/ui';
|
2024-03-21 19:39:33 +01:00
|
|
|
|
2024-11-14 08:43:25 -06:00
|
|
|
interface Props {
|
|
|
|
|
text: string;
|
|
|
|
|
subtitle?: string;
|
|
|
|
|
icon?: string;
|
|
|
|
|
activeColor?: string;
|
|
|
|
|
textColor?: string;
|
|
|
|
|
onClick: () => void;
|
2025-01-07 17:29:22 +01:00
|
|
|
shortcut?: Shortcut | null;
|
|
|
|
|
shortcutLabel?: string;
|
2024-11-14 08:43:25 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let {
|
|
|
|
|
text,
|
|
|
|
|
subtitle = '',
|
|
|
|
|
icon = '',
|
|
|
|
|
activeColor = 'bg-slate-300',
|
|
|
|
|
textColor = 'text-immich-fg dark:text-immich-dark-bg',
|
|
|
|
|
onClick,
|
2025-01-07 17:29:22 +01:00
|
|
|
shortcut = null,
|
|
|
|
|
shortcutLabel = '',
|
2024-11-14 08:43:25 -06:00
|
|
|
}: Props = $props();
|
2024-06-18 03:52:38 +00:00
|
|
|
|
|
|
|
|
let id: string = generateId();
|
|
|
|
|
|
2024-11-14 08:43:25 -06:00
|
|
|
let isActive = $derived($selectedIdStore === id);
|
2024-06-18 03:52:38 +00:00
|
|
|
|
|
|
|
|
const handleClick = () => {
|
|
|
|
|
$optionClickCallbackStore?.();
|
2024-06-20 21:15:36 +00:00
|
|
|
onClick();
|
2024-06-18 03:52:38 +00:00
|
|
|
};
|
2025-01-07 17:29:22 +01:00
|
|
|
|
|
|
|
|
if (shortcut && !shortcutLabel) {
|
|
|
|
|
shortcutLabel = computeShortcutLabel(shortcut);
|
|
|
|
|
}
|
|
|
|
|
const bindShortcutIfSet = shortcut
|
|
|
|
|
? (n: HTMLElement) => bindShortcut(n, { shortcut, onShortcut: onClick })
|
|
|
|
|
: () => {};
|
2022-07-23 13:08:49 -05:00
|
|
|
</script>
|
|
|
|
|
|
2025-05-21 18:12:00 +02:00
|
|
|
<svelte:document use:bindShortcutIfSet />
|
2025-01-07 17:29:22 +01:00
|
|
|
|
2024-11-14 08:43:25 -06:00
|
|
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
|
|
|
<!-- svelte-ignore a11y_mouse_events_have_key_events -->
|
2024-06-18 03:52:38 +00:00
|
|
|
<li
|
|
|
|
|
{id}
|
2024-11-14 08:43:25 -06:00
|
|
|
onclick={handleClick}
|
|
|
|
|
onmouseover={() => ($selectedIdStore = id)}
|
|
|
|
|
onmouseleave={() => ($selectedIdStore = undefined)}
|
2025-04-28 09:53:53 -04:00
|
|
|
class="w-full p-4 text-start text-sm font-medium {textColor} focus:outline-none focus:ring-2 focus:ring-inset cursor-pointer border-gray-200 flex gap-2 items-center {isActive
|
2024-06-20 21:15:36 +00:00
|
|
|
? activeColor
|
|
|
|
|
: 'bg-slate-100'}"
|
2023-07-01 00:50:47 -04:00
|
|
|
role="menuitem"
|
2022-07-23 13:08:49 -05:00
|
|
|
>
|
2024-06-20 21:15:36 +00:00
|
|
|
{#if icon}
|
2025-09-16 21:40:43 +02:00
|
|
|
<Icon {icon} aria-hidden size="18" />
|
2024-06-20 21:15:36 +00:00
|
|
|
{/if}
|
2025-01-07 17:29:22 +01:00
|
|
|
<div class="w-full">
|
|
|
|
|
<div class="flex justify-between">
|
|
|
|
|
{text}
|
|
|
|
|
{#if shortcutLabel}
|
2025-04-28 09:53:53 -04:00
|
|
|
<span class="text-gray-500 ps-4">
|
2025-01-07 17:29:22 +01:00
|
|
|
{shortcutLabel}
|
|
|
|
|
</span>
|
|
|
|
|
{/if}
|
|
|
|
|
</div>
|
2024-06-20 21:15:36 +00:00
|
|
|
{#if subtitle}
|
|
|
|
|
<p class="text-xs text-gray-500">
|
|
|
|
|
{subtitle}
|
2024-03-21 19:39:33 +01:00
|
|
|
</p>
|
|
|
|
|
{/if}
|
2024-06-20 21:15:36 +00:00
|
|
|
</div>
|
2024-06-18 03:52:38 +00:00
|
|
|
</li>
|