refactor(badge): eine Badge-Komponente überall, alle 7 CMS-Farben
components/Badge.svelte = einzige Badge-Quelle. colorClasses deckt jetzt alle CMS-badge.color-Werte ab (green/blue/amber/orange/purple/teal/slate) — vorher fielen orange/purple/teal/slate auf grau (Regionen-Badges sahen gleich aus). Ad-hoc Badge-Spans (ContactCard, AdressbuchBlock) durch <Badge> ersetzt. Verwaiste ui/Badge.svelte (0 Nutzungen) + Atoms/Badge-Story entfernt. Molecules/Badge-Story zeigt jetzt alle Farben. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,9 +6,21 @@
|
||||
title: 'Molecules/Badge',
|
||||
component: Badge,
|
||||
tags: ['autodocs'],
|
||||
argTypes: {
|
||||
color: {
|
||||
control: 'select',
|
||||
options: ['green', 'blue', 'amber', 'orange', 'purple', 'teal', 'slate', undefined],
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<Story name="Standard">Neu</Story>
|
||||
<Story name="Wald" args={{ color: 'wald' }}>Aktiv</Story>
|
||||
<Story name="Fire" args={{ color: 'fire' }}>Dringend</Story>
|
||||
<!-- Die eine Badge. `color` deckt alle CMS-badge.color-Werte ab. -->
|
||||
<Story name="Default">Neu</Story>
|
||||
<Story name="Green" args={{ color: 'green' }}>Gründer</Story>
|
||||
<Story name="Blue" args={{ color: 'blue' }}>Mitglied</Story>
|
||||
<Story name="Amber" args={{ color: 'amber' }}>Anfrage läuft</Story>
|
||||
<Story name="Orange" args={{ color: 'orange' }}>Südwestthüringen</Story>
|
||||
<Story name="Purple" args={{ color: 'purple' }}>Ostthüringen</Story>
|
||||
<Story name="Teal" args={{ color: 'teal' }}>Mittelthüringen</Story>
|
||||
<Story name="Slate" args={{ color: 'slate' }}>Nordthüringen</Story>
|
||||
|
||||
@@ -7,16 +7,26 @@
|
||||
class: className = "",
|
||||
}: { children?: Snippet; color?: string; class?: string } = $props();
|
||||
|
||||
// Die einzige Badge-Farbquelle. Deckt alle CMS-badge.color-Werte ab
|
||||
// (green/blue/amber/orange/purple/teal/slate) + Fallback. Marken-Töne
|
||||
// (wald/himmel) wo möglich, sonst Tailwind-Palette für klar unterscheidbare
|
||||
// Regionen-Badges. KEINE Eigenimplementierungen woanders — immer <Badge>.
|
||||
function colorClasses(c?: string): string {
|
||||
switch (c) {
|
||||
case "green": return "bg-wald-50 text-wald-700 border border-wald-200";
|
||||
case "blue": return "bg-himmel-50 text-himmel-700 border border-himmel-200";
|
||||
case "amber": return "bg-erde-50 text-erde-700 border border-erde-200";
|
||||
default: return "bg-stein-100 text-stein-600 border border-stein-200";
|
||||
case "green": return "bg-wald-50 text-wald-700 border-wald-200";
|
||||
case "blue": return "bg-himmel-50 text-himmel-700 border-himmel-200";
|
||||
case "amber": return "bg-amber-50 text-amber-700 border-amber-200";
|
||||
case "orange": return "bg-orange-50 text-orange-700 border-orange-200";
|
||||
case "purple": return "bg-purple-50 text-purple-700 border-purple-200";
|
||||
case "teal": return "bg-teal-50 text-teal-700 border-teal-200";
|
||||
case "slate": return "bg-slate-100 text-slate-700 border-slate-300";
|
||||
default: return "bg-stein-100 text-stein-600 border-stein-200";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<span class="shrink-0 rounded-full px-1.5 py-0 text-[0.65rem] font-medium {colorClasses(color)} {className}">
|
||||
<span
|
||||
class="shrink-0 whitespace-nowrap rounded-full border px-1.5 py-0 text-[0.65rem] font-medium {colorClasses(color)} {className}"
|
||||
>
|
||||
{@render children?.()}
|
||||
</span>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import "$lib/iconify-offline";
|
||||
import type { ContactEntry } from "$lib/block-types";
|
||||
import { downloadVCard } from "$lib/vcard";
|
||||
import Badge from "$lib/components/Badge.svelte";
|
||||
|
||||
let { contact }: { contact: ContactEntry } = $props();
|
||||
|
||||
@@ -23,14 +24,10 @@
|
||||
{#if contact.role || orgNames.length > 0}
|
||||
<div class="flex flex-wrap gap-1">
|
||||
{#if contact.role}
|
||||
<span class="shrink-0 rounded-full border border-stein-200 bg-stein-100 px-1.5 py-0 text-[0.65rem] font-medium text-stein-600">
|
||||
{contact.role}
|
||||
</span>
|
||||
<Badge>{contact.role}</Badge>
|
||||
{/if}
|
||||
{#each orgNames as org}
|
||||
<span class="shrink-0 rounded-full border border-wald-200 bg-wald-50 px-1.5 py-0 text-[0.65rem] font-medium text-wald-700">
|
||||
{org}
|
||||
</span>
|
||||
<Badge color="green">{org}</Badge>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import { downloadVCard, downloadVCardAll, buildVCardString } from "$lib/vcard";
|
||||
import QrButton from "$lib/components/QrButton.svelte";
|
||||
import Button from "$lib/ui/Button.svelte";
|
||||
import Badge from "$lib/components/Badge.svelte";
|
||||
|
||||
let { block }: { block: AdressbuchBlockData } = $props();
|
||||
|
||||
@@ -241,14 +242,10 @@
|
||||
{#if contact.role || (contact.organisations ?? []).some((o) => typeof o === "object" && o.name)}
|
||||
<div class="mt-0.5 flex flex-nowrap gap-1 overflow-hidden">
|
||||
{#if contact.role}
|
||||
<span class="shrink-0 whitespace-nowrap rounded-full border border-stein-200 bg-stein-100 px-1.5 py-0 text-[0.65rem] font-medium text-stein-600">
|
||||
{contact.role}
|
||||
</span>
|
||||
<Badge>{contact.role}</Badge>
|
||||
{/if}
|
||||
{#each (contact.organisations ?? []).filter((o): o is { _slug?: string; name?: string } => typeof o === "object" && !!o.name) as org}
|
||||
<span class="shrink-0 whitespace-nowrap rounded-full border border-wald-200 bg-wald-50 px-1.5 py-0 text-[0.65rem] font-medium text-wald-700">
|
||||
{org.name}
|
||||
</span>
|
||||
<Badge color="green">{org.name}</Badge>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user