UI/UX-Prototyp der Analytics-Dashboards in HiveGrid, fachlich auf einen SHK-/Handwerksbetrieb zugeschnitten. Ziel ist die Übergabe an die Entwicklung, nicht der Produktivbetrieb. Inhalt: sechs Seiten (Übersicht, Finanzen, Aufträge, Kunden, Team, Komponenten), 26 KPIs, neun Chart-Bausteine, Filtersystem mit seitenabhängiger Relevanz und ein deterministischer Demo-Datensatz (420 Kunden, 1.900 Aufträge, Stichtag 30.07.2026). Drei Quellen sind zusammengeführt: die fachliche Planung mit dem Branchenpartner (Januar 2026), die Subframe-Komponentenbibliothek aus dem HiveGrid-Pitch und IBM Carbon Data Visualization für die Diagrammregeln. Herkunft und bewusste Abweichungen stehen in docs/HERKUNFT.md. Dokumentation: README, HANDOVER (was echte Logik braucht), docs/DESIGN-SYSTEM, KPI-KATALOG, DATENMODELL, NAVIGATION, HERKUNFT, ZIELSYSTEM (Einbauort in HiveGrid Cloud) und LEITPLANKEN (welche Cloud-Screens als Vorbild taugen). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QPeZNwSeU7qG3RRCwaxEZX
318 lines
13 KiB
TypeScript
318 lines
13 KiB
TypeScript
"use client";
|
|
/*
|
|
* Documentation:
|
|
* Badge — https://app.subframe.com/f023064a5ca0/library?component=Badge_7d75e221-355a-4695-acb7-3902a9f6ffde
|
|
*/
|
|
|
|
import React from "react";
|
|
import * as SubframeUtils from "../../utils";
|
|
|
|
export interface BadgeRootProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
tone?:
|
|
| "red-subtle"
|
|
| "orange-subtle"
|
|
| "yellow-subtle"
|
|
| "pear-subtle"
|
|
| "lime-subtle"
|
|
| "green-subtle"
|
|
| "teal-subtle"
|
|
| "ocean-subtle"
|
|
| "sky-subtle"
|
|
| "blue-subtle"
|
|
| "indigo-subtle"
|
|
| "violet-subtle"
|
|
| "fuchsia-subtle"
|
|
| "pink-subtle"
|
|
| "sand-subtle"
|
|
| "brown-subtle"
|
|
| "red-solid"
|
|
| "orange-solid"
|
|
| "yellow-solid"
|
|
| "pear-solid"
|
|
| "lime-solid"
|
|
| "green-solid"
|
|
| "teal-solid"
|
|
| "ocean-solid"
|
|
| "sky-solid"
|
|
| "blue-solid"
|
|
| "indigo-solid"
|
|
| "violet-solid"
|
|
| "fuchsia-solid"
|
|
| "pink-solid"
|
|
| "sand-solid"
|
|
| "brown-solid"
|
|
| "red-outline"
|
|
| "orange-outline"
|
|
| "yellow-outline"
|
|
| "pear-outline"
|
|
| "lime-outline"
|
|
| "green-outline"
|
|
| "teal-outline"
|
|
| "ocean-outline"
|
|
| "sky-outline"
|
|
| "blue-outline"
|
|
| "indigo-outline"
|
|
| "violet-outline"
|
|
| "fuchsia-outline"
|
|
| "pink-outline"
|
|
| "sand-outline"
|
|
| "brown-outline"
|
|
| "brand-primary-solid"
|
|
| "brand-secondary-solid"
|
|
| "neutral-solid"
|
|
| "brand-primary-subtle"
|
|
| "brand-secondary-subtle"
|
|
| "neutral-subtle"
|
|
| "white";
|
|
children?: React.ReactNode;
|
|
size?: "small" | "medium" | "large";
|
|
hideDot?: boolean;
|
|
className?: string;
|
|
}
|
|
|
|
const BadgeRoot = React.forwardRef<HTMLDivElement, BadgeRootProps>(
|
|
function BadgeRoot(
|
|
{
|
|
tone = "neutral-subtle",
|
|
children,
|
|
size = "medium",
|
|
hideDot = false,
|
|
className,
|
|
...otherProps
|
|
}: BadgeRootProps,
|
|
ref
|
|
) {
|
|
return (
|
|
<div
|
|
className={SubframeUtils.twClassNames(
|
|
"group/7d75e221 flex h-6 items-center gap-2 rounded-round border border-solid border-border-default bg-surface-feedback-subtle-neutral px-2.5 py-1",
|
|
{
|
|
"h-8 py-2": size === "large",
|
|
"h-5 py-0.5": size === "small",
|
|
"bg-surface-neutral-secondary": tone === "white",
|
|
"border border-solid border-brand-brand-secondary-surface-subtle-default bg-brand-brand-secondary-surface-subtle-default":
|
|
tone === "brand-secondary-subtle",
|
|
"border border-solid border-brand-brand-surface-subtle-default bg-brand-brand-surface-subtle-default":
|
|
tone === "brand-primary-subtle",
|
|
"border border-solid border-surface-feedback-solid-neutral bg-surface-feedback-solid-neutral":
|
|
tone === "neutral-solid",
|
|
"border border-solid border-brand-brand-secondary-surface-solid-default bg-brand-brand-secondary-surface-solid-default":
|
|
tone === "brand-secondary-solid",
|
|
"border border-solid border-brand-brand-surface-solid-default bg-brand-brand-surface-solid-default":
|
|
tone === "brand-primary-solid",
|
|
"border-2 border-solid border-[#c2a682] bg-[#fafafa]":
|
|
tone === "brown-outline",
|
|
"border-2 border-solid border-[#c8baa9] bg-[#fafafa]":
|
|
tone === "sand-outline",
|
|
"border-2 border-solid border-[#f9a8d4] bg-[#fafafa]":
|
|
tone === "pink-outline",
|
|
"border-2 border-solid border-[#f0abfc] bg-[#fafafa]":
|
|
tone === "fuchsia-outline",
|
|
"border-2 border-solid border-[#cfb2ff] bg-[#fafafa]":
|
|
tone === "violet-outline",
|
|
"border-2 border-solid border-[#b3b8ff] bg-[#fafafa]":
|
|
tone === "indigo-outline",
|
|
"border-2 border-solid border-[#85c7ff] bg-[#fafafa]":
|
|
tone === "blue-outline",
|
|
"border-2 border-solid border-[#79c7ff] bg-[#fafafa]":
|
|
tone === "sky-outline",
|
|
"border-2 border-solid border-[#81dbf8] bg-[#fafafa]":
|
|
tone === "ocean-outline",
|
|
"border-2 border-solid border-[#51f7e5] bg-[#fafafa]":
|
|
tone === "teal-outline",
|
|
"border-2 border-solid border-[#85f0a3] bg-[#fafafa]":
|
|
tone === "green-outline",
|
|
"border-2 border-solid border-[#bef264] bg-[#fafafa]":
|
|
tone === "lime-outline",
|
|
"border-2 border-solid border-[#e0eb6b] bg-[#fafafa]":
|
|
tone === "pear-outline",
|
|
"border-2 border-solid border-[#f6d84e] bg-[#fafafa]":
|
|
tone === "yellow-outline",
|
|
"border-2 border-solid border-[#ffa570] bg-[#fafafa]":
|
|
tone === "orange-outline",
|
|
"border-2 border-solid border-[#fba6a6] bg-[#fafafa]":
|
|
tone === "red-outline",
|
|
"border border-solid border-[#8a5f44] bg-[#8a5f44]":
|
|
tone === "brown-solid",
|
|
"border border-solid border-[#947562] bg-[#947562]":
|
|
tone === "sand-solid",
|
|
"border border-solid border-[#db2777] bg-[#db2777]":
|
|
tone === "pink-solid",
|
|
"border border-solid border-[#c026d3] bg-[#c026d3]":
|
|
tone === "fuchsia-solid",
|
|
"border border-solid border-[#7c2df0] bg-[#7c2df0]":
|
|
tone === "violet-solid",
|
|
"border border-solid border-[#4835f2] bg-[#4835f2]":
|
|
tone === "indigo-solid",
|
|
"border border-solid border-[#0c4bff] bg-[#0c4bff]":
|
|
tone === "blue-solid",
|
|
"border border-solid border-[#0071ce] bg-[#0071ce]":
|
|
tone === "sky-solid",
|
|
"border border-solid border-[#0890c1] bg-[#0890c1]":
|
|
tone === "ocean-solid",
|
|
"border border-solid border-[#05807c] bg-[#05807c]":
|
|
tone === "teal-solid",
|
|
"border border-solid border-[#15a43e] bg-[#15a43e]":
|
|
tone === "green-solid",
|
|
"border border-solid border-[#4d7c0f] bg-[#4d7c0f]":
|
|
tone === "lime-solid",
|
|
"border border-solid border-[#677615] bg-[#677615]":
|
|
tone === "pear-solid",
|
|
"border border-solid border-[#e0c200] bg-[#e0c200]":
|
|
tone === "yellow-solid",
|
|
"border border-solid border-[#ea580c] bg-[#ea580c]":
|
|
tone === "orange-solid",
|
|
"border border-solid border-[#da2828] bg-[#da2828]":
|
|
tone === "red-solid",
|
|
"border border-solid border-[#d9c8af] bg-[#ebe3d6]":
|
|
tone === "brown-subtle",
|
|
"border border-solid border-[#ded6ca] bg-[#ede9e3]":
|
|
tone === "sand-subtle",
|
|
"border border-solid border-[#fbcfe8] bg-[#fce7f3]":
|
|
tone === "pink-subtle",
|
|
"border border-solid border-[#f5d0fe] bg-[#fae8ff]":
|
|
tone === "fuchsia-subtle",
|
|
"border border-solid border-[#e4d4ff] bg-[#f0e7ff]":
|
|
tone === "violet-subtle",
|
|
"border border-solid border-[#d5d9ff] bg-[#e8e9ff]":
|
|
tone === "indigo-subtle",
|
|
"border border-solid border-[#b3dfff] bg-[#d5efff]":
|
|
tone === "blue-subtle",
|
|
"border border-solid border-border-information-subtle bg-surface-feedback-subtle-information":
|
|
tone === "sky-subtle",
|
|
"border border-solid border-[#bceafb] bg-[#e1f4fd]":
|
|
tone === "ocean-subtle",
|
|
"border border-solid border-[#90ffee] bg-[#c8fff7]":
|
|
tone === "teal-subtle",
|
|
"border border-solid border-[#baf8cb] bg-[#dcfce4]":
|
|
tone === "green-subtle",
|
|
"border border-solid border-[#d9f99d] bg-[#ecfccb]":
|
|
tone === "lime-subtle",
|
|
"border border-solid border-[#eff4a2] bg-[#f8facd]":
|
|
tone === "pear-subtle",
|
|
"border border-solid border-[#faeb8e] bg-[#fcf6c5]":
|
|
tone === "yellow-subtle",
|
|
"border border-solid border-[#ffcaa8] bg-[#ffe7d4]":
|
|
tone === "orange-subtle",
|
|
"border border-solid border-[#fdcbcb] bg-[#fee2e2]":
|
|
tone === "red-subtle",
|
|
},
|
|
className
|
|
)}
|
|
ref={ref}
|
|
{...otherProps}
|
|
>
|
|
<div
|
|
className={SubframeUtils.twClassNames(
|
|
"flex h-1 w-1 flex-none flex-col items-start rounded-round bg-icon-neutral-on-subtle",
|
|
{
|
|
hidden: hideDot,
|
|
"bg-brand-brand-secondary-surface-solid-default":
|
|
tone === "brand-secondary-subtle",
|
|
"bg-brand-brand-surface-solid-default":
|
|
tone === "brand-primary-subtle",
|
|
"bg-icon-neutral-on-solid":
|
|
tone === "neutral-solid" ||
|
|
tone === "brand-secondary-solid" ||
|
|
tone === "brand-primary-solid" ||
|
|
tone === "brown-solid" ||
|
|
tone === "sand-solid" ||
|
|
tone === "pink-solid" ||
|
|
tone === "fuchsia-solid" ||
|
|
tone === "violet-solid" ||
|
|
tone === "indigo-solid" ||
|
|
tone === "blue-solid" ||
|
|
tone === "sky-solid" ||
|
|
tone === "ocean-solid" ||
|
|
tone === "teal-solid" ||
|
|
tone === "green-solid" ||
|
|
tone === "lime-solid" ||
|
|
tone === "pear-solid" ||
|
|
tone === "yellow-solid" ||
|
|
tone === "orange-solid" ||
|
|
tone === "red-solid",
|
|
"bg-[#6f4a39]": tone === "brown-outline",
|
|
"bg-[#7c6052]": tone === "sand-outline",
|
|
"bg-[#be185d]": tone === "pink-outline",
|
|
"bg-[#a21caf]": tone === "fuchsia-outline",
|
|
"bg-[#691cd4]": tone === "violet-outline",
|
|
"bg-[#3923de]": tone === "indigo-outline",
|
|
"bg-[#003beb]": tone === "blue-outline",
|
|
"bg-[#0071ce]": tone === "sky-outline" || tone === "sky-subtle",
|
|
"bg-[#08739c]": tone === "ocean-outline",
|
|
"bg-[#05807c]": tone === "teal-outline" || tone === "teal-subtle",
|
|
"bg-[#148134]": tone === "green-outline",
|
|
"bg-[#4d7c0f]": tone === "lime-outline" || tone === "lime-subtle",
|
|
"bg-[#677615]": tone === "pear-outline" || tone === "pear-subtle",
|
|
"bg-[#9b5e0d]": tone === "yellow-outline",
|
|
"bg-[#c72307]": tone === "orange-outline",
|
|
"bg-[#c52020]": tone === "red-outline",
|
|
"bg-[#8a5f44]": tone === "brown-subtle",
|
|
"bg-[#947562]": tone === "sand-subtle",
|
|
"bg-[#db2777]": tone === "pink-subtle",
|
|
"bg-[#c026d3]": tone === "fuchsia-subtle",
|
|
"bg-[#7c2df0]": tone === "violet-subtle",
|
|
"bg-[#4835f2]": tone === "indigo-subtle",
|
|
"bg-[#0c4bff]": tone === "blue-subtle",
|
|
"bg-[#0890c1]": tone === "ocean-subtle",
|
|
"bg-[#15a43e]": tone === "green-subtle",
|
|
"bg-[#e0c200]": tone === "yellow-subtle",
|
|
"bg-[#ea580c]": tone === "orange-subtle",
|
|
"bg-[#da2828]": tone === "red-subtle",
|
|
}
|
|
)}
|
|
/>
|
|
{children ? (
|
|
<span
|
|
className={SubframeUtils.twClassNames(
|
|
"whitespace-nowrap text-body-small-medium-0 font-body-small-medium-0 text-text-neutral-on-subtle",
|
|
{
|
|
"text-text-neutral-on-solid":
|
|
tone === "neutral-solid" ||
|
|
tone === "brand-secondary-solid" ||
|
|
tone === "brand-primary-solid" ||
|
|
tone === "brown-solid" ||
|
|
tone === "sand-solid" ||
|
|
tone === "pink-solid" ||
|
|
tone === "fuchsia-solid" ||
|
|
tone === "violet-solid" ||
|
|
tone === "indigo-solid" ||
|
|
tone === "blue-solid" ||
|
|
tone === "sky-solid" ||
|
|
tone === "ocean-solid" ||
|
|
tone === "teal-solid" ||
|
|
tone === "green-solid" ||
|
|
tone === "lime-solid" ||
|
|
tone === "pear-solid" ||
|
|
tone === "yellow-solid" ||
|
|
tone === "orange-solid" ||
|
|
tone === "red-solid",
|
|
"text-[#6f4a39]": tone === "brown-outline",
|
|
"text-[#7c6052]": tone === "sand-outline",
|
|
"text-[#be185d]": tone === "pink-outline",
|
|
"text-[#a21caf]": tone === "fuchsia-outline",
|
|
"text-[#691cd4]": tone === "violet-outline",
|
|
"text-[#3923de]": tone === "indigo-outline",
|
|
"text-[#003beb]": tone === "blue-outline",
|
|
"text-[#0071ce]": tone === "sky-outline",
|
|
"text-[#08739c]": tone === "ocean-outline",
|
|
"text-[#05807c]": tone === "teal-outline",
|
|
"text-[#148134]": tone === "green-outline",
|
|
"text-[#4d7c0f]": tone === "lime-outline",
|
|
"text-[#677615]": tone === "pear-outline",
|
|
"text-[#9b5e0d]": tone === "yellow-outline",
|
|
"text-[#c72307]": tone === "orange-outline",
|
|
"text-[#c52020]": tone === "red-outline",
|
|
}
|
|
)}
|
|
>
|
|
{children}
|
|
</span>
|
|
) : null}
|
|
</div>
|
|
);
|
|
}
|
|
);
|
|
|
|
export const Badge = BadgeRoot;
|