mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 19:01:08 +02:00
refactor(todo,photos): use shared TagChip and TagSelector components
Replace todo's custom 87-line TagSelector with thin wrapper around shared-ui TagSelector. Replace inline tag chip HTML in TaskItem, KanbanTaskCard, and PhotoDetailModal with shared TagChip component. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
04fcbd15c9
commit
de8335277a
4 changed files with 23 additions and 87 deletions
|
|
@ -3,6 +3,7 @@
|
|||
import type { Photo } from '$lib/modules/photos/types';
|
||||
import { photoStore } from '$lib/modules/photos/stores/photos.svelte';
|
||||
import { CaretRight, DownloadSimple, Heart, X } from '@manacore/shared-icons';
|
||||
import { TagChip } from '@manacore/shared-ui';
|
||||
|
||||
interface Props {
|
||||
photo: Photo;
|
||||
|
|
@ -145,12 +146,7 @@
|
|||
<h4 class="info-label">Tags</h4>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{#each photo.tags as tag}
|
||||
<span
|
||||
class="rounded-full px-2 py-0.5 text-xs"
|
||||
style="background-color: {tag.color}20; color: {tag.color}"
|
||||
>
|
||||
{tag.name}
|
||||
</span>
|
||||
<TagChip name={tag.name} color={tag.color} />
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import type { Task, TaskPriority } from '../types';
|
||||
import { getPriorityLabel, getPriorityColor } from '../queries';
|
||||
import { Check, Circle, CalendarBlank, CheckSquare } from '@manacore/shared-icons';
|
||||
import { TagChip } from '@manacore/shared-ui';
|
||||
import { isToday, isPast, format } from 'date-fns';
|
||||
import { de } from 'date-fns/locale';
|
||||
|
||||
|
|
@ -115,12 +116,7 @@
|
|||
</span>
|
||||
{/if}
|
||||
{#each taskTags as tag (tag.id)}
|
||||
<span
|
||||
class="rounded-full px-1.5 py-0.5 text-[0.625rem] font-medium"
|
||||
style="background: color-mix(in srgb, {tag.color} 15%, transparent); color: {tag.color}"
|
||||
>
|
||||
{tag.name}
|
||||
</span>
|
||||
<TagChip name={tag.name} color={tag.color} />
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
import { getContext } from 'svelte';
|
||||
import type { Observable } from 'dexie';
|
||||
import type { LocalLabel } from '../../types';
|
||||
import { X, Plus, Tag } from '@manacore/shared-icons';
|
||||
import { TagSelector as SharedTagSelector } from '@manacore/shared-ui';
|
||||
import type { Tag } from '@manacore/shared-ui';
|
||||
|
||||
interface Props {
|
||||
selectedIds: string[];
|
||||
|
|
@ -18,75 +19,22 @@
|
|||
return () => sub.unsubscribe();
|
||||
});
|
||||
|
||||
let showPicker = $state(false);
|
||||
|
||||
function toggle(id: string) {
|
||||
if (selectedIds.includes(id)) {
|
||||
onChange(selectedIds.filter((i) => i !== id));
|
||||
} else {
|
||||
onChange([...selectedIds, id]);
|
||||
}
|
||||
}
|
||||
|
||||
let selectedLabels = $derived(
|
||||
selectedIds
|
||||
.map((id) => allLabels.find((l) => l.id === id))
|
||||
.filter((l): l is LocalLabel => l != null)
|
||||
// Adapt LocalLabel[] to Tag[] for the shared component
|
||||
const tags: Tag[] = $derived(allLabels.map((l) => ({ id: l.id, name: l.name, color: l.color })));
|
||||
const selectedTags: Tag[] = $derived(
|
||||
selectedIds.map((id) => tags.find((t) => t.id === id)).filter((t): t is Tag => t != null)
|
||||
);
|
||||
|
||||
let availableLabels = $derived(allLabels.filter((l) => !selectedIds.includes(l.id)));
|
||||
function handleTagsChange(newTags: Tag[]) {
|
||||
onChange(newTags.map((t) => t.id));
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex flex-wrap items-center gap-1">
|
||||
{#each selectedLabels as label (label.id)}
|
||||
<span
|
||||
class="inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[0.6875rem] font-medium"
|
||||
style="background: color-mix(in srgb, {label.color} 15%, transparent); color: {label.color}"
|
||||
>
|
||||
{label.name}
|
||||
<button type="button" onclick={() => toggle(label.id)} class="hover:opacity-70">
|
||||
<X size={10} />
|
||||
</button>
|
||||
</span>
|
||||
{/each}
|
||||
|
||||
<div class="relative">
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => (showPicker = !showPicker)}
|
||||
class="flex items-center gap-1 rounded-md px-1.5 py-0.5 text-xs text-muted-foreground transition-colors hover:bg-muted"
|
||||
>
|
||||
<Tag size={12} />
|
||||
<Plus size={10} />
|
||||
</button>
|
||||
|
||||
{#if showPicker && availableLabels.length > 0}
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||
<div
|
||||
class="absolute left-0 top-full z-50 mt-1 min-w-[140px] rounded-lg border border-border bg-card p-1 shadow-lg"
|
||||
onclick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{#each availableLabels as label (label.id)}
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => {
|
||||
toggle(label.id);
|
||||
if (availableLabels.length <= 1) showPicker = false;
|
||||
}}
|
||||
class="flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-xs text-foreground transition-colors hover:bg-muted"
|
||||
>
|
||||
<span class="h-2.5 w-2.5 rounded-full" style="background-color: {label.color}"></span>
|
||||
{label.name}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if showPicker}
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||
<div class="fixed inset-0 z-40" onclick={() => (showPicker = false)}></div>
|
||||
{/if}
|
||||
<SharedTagSelector
|
||||
{tags}
|
||||
{selectedTags}
|
||||
onTagsChange={handleTagsChange}
|
||||
addTagLabel="Label"
|
||||
placeholder="Label hinzufügen..."
|
||||
searchPlaceholder="Label suchen..."
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
import { isToday, isPast, format } from 'date-fns';
|
||||
import { de } from 'date-fns/locale';
|
||||
import { Check, Circle, CalendarBlank, CheckSquare, Flag, Trash } from '@manacore/shared-icons';
|
||||
import { TagChip } from '@manacore/shared-ui';
|
||||
|
||||
interface Props {
|
||||
task: Task;
|
||||
|
|
@ -144,12 +145,7 @@
|
|||
{/if}
|
||||
|
||||
{#each taskLabels as label (label.id)}
|
||||
<span
|
||||
class="rounded px-1.5 py-0.5 text-[0.625rem] font-medium"
|
||||
style="background: color-mix(in srgb, {label.color} 15%, transparent); color: {label.color}"
|
||||
>
|
||||
{label.name}
|
||||
</span>
|
||||
<TagChip name={label.name} color={label.color} />
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue