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
170 lines
6.2 KiB
TypeScript
170 lines
6.2 KiB
TypeScript
"use client";
|
|
/*
|
|
* Documentation:
|
|
* Badge Feedback — https://app.subframe.com/f023064a5ca0/library?component=Badge+Feedback_896531e4-54ea-4e5a-8710-c30fc2ce10fb
|
|
*/
|
|
|
|
import React from "react";
|
|
import * as SubframeUtils from "../../utils";
|
|
|
|
export interface BadgeFeedbackRootProps
|
|
extends React.HTMLAttributes<HTMLDivElement> {
|
|
farbe?:
|
|
| "solid-neutral"
|
|
| "solid-positive"
|
|
| "solid-negative"
|
|
| "solid-warning"
|
|
| "solid-information"
|
|
| "solid-purple"
|
|
| "solid-blue"
|
|
| "solid-brand-primary"
|
|
| "solid-brand-secondary"
|
|
| "subtle-neutral"
|
|
| "subtle-positive"
|
|
| "subtle-negative"
|
|
| "subtle-warning"
|
|
| "subtle-information"
|
|
| "subtle-purple"
|
|
| "subtle-blue"
|
|
| "subtle-brand-primary"
|
|
| "subtle-brand-secondary"
|
|
| "ghost-neutral"
|
|
| "ghost-positive"
|
|
| "ghost-negative"
|
|
| "ghost-warning"
|
|
| "ghost-information"
|
|
| "ghost-purple"
|
|
| "ghost-blue"
|
|
| "ghost-brand-primary"
|
|
| "ghost-brand-secondary";
|
|
children?: React.ReactNode;
|
|
size?: "medium" | "small" | "large";
|
|
className?: string;
|
|
}
|
|
|
|
const BadgeFeedbackRoot = React.forwardRef<
|
|
HTMLDivElement,
|
|
BadgeFeedbackRootProps
|
|
>(function BadgeFeedbackRoot(
|
|
{
|
|
farbe = "solid-neutral",
|
|
children,
|
|
size = "medium",
|
|
className,
|
|
...otherProps
|
|
}: BadgeFeedbackRootProps,
|
|
ref
|
|
) {
|
|
return (
|
|
<div
|
|
className={SubframeUtils.twClassNames(
|
|
"group/896531e4 flex h-6 items-center gap-2 rounded-round bg-surface-feedback-solid-neutral px-2.5 py-1",
|
|
{
|
|
"h-8 py-2": size === "large",
|
|
"h-5 py-0.5": size === "small",
|
|
"bg-transparent px-0 py-0":
|
|
farbe === "ghost-brand-secondary" ||
|
|
farbe === "ghost-brand-primary" ||
|
|
farbe === "ghost-blue" ||
|
|
farbe === "ghost-purple" ||
|
|
farbe === "ghost-information" ||
|
|
farbe === "ghost-warning" ||
|
|
farbe === "ghost-negative" ||
|
|
farbe === "ghost-positive" ||
|
|
farbe === "ghost-neutral",
|
|
"bg-brand-brand-secondary-surface-subtle-default":
|
|
farbe === "subtle-brand-secondary",
|
|
"bg-brand-brand-surface-subtle-default":
|
|
farbe === "subtle-brand-primary",
|
|
"bg-surface-ui-subtle-blue-default": farbe === "subtle-blue",
|
|
"bg-surface-ui-subtle-purple-default": farbe === "subtle-purple",
|
|
"bg-surface-feedback-subtle-information":
|
|
farbe === "subtle-information",
|
|
"bg-surface-feedback-subtle-warning": farbe === "subtle-warning",
|
|
"bg-surface-feedback-subtle-negative": farbe === "subtle-negative",
|
|
"bg-surface-feedback-subtle-positive": farbe === "subtle-positive",
|
|
"bg-surface-feedback-subtle-neutral": farbe === "subtle-neutral",
|
|
"bg-brand-brand-secondary-surface-solid-default":
|
|
farbe === "solid-brand-secondary",
|
|
"bg-brand-brand-surface-solid-default":
|
|
farbe === "solid-brand-primary",
|
|
"bg-surface-ui-solid-blue-default": farbe === "solid-blue",
|
|
"bg-surface-ui-solid-purple-default": farbe === "solid-purple",
|
|
"bg-surface-feedback-solid-information":
|
|
farbe === "solid-information",
|
|
"bg-surface-feedback-solid-warning": farbe === "solid-warning",
|
|
"bg-surface-feedback-solid-negative-default":
|
|
farbe === "solid-negative",
|
|
"bg-surface-feedback-solid-positive-default":
|
|
farbe === "solid-positive",
|
|
},
|
|
className
|
|
)}
|
|
ref={ref}
|
|
{...otherProps}
|
|
>
|
|
<div
|
|
className={SubframeUtils.twClassNames(
|
|
"flex h-1 w-1 flex-none flex-col items-start gap-2 rounded-round bg-icon-neutral-on-solid",
|
|
{
|
|
"bg-brand-brand-secondary-surface-solid-default":
|
|
farbe === "ghost-brand-secondary" ||
|
|
farbe === "subtle-brand-secondary",
|
|
"bg-brand-brand-surface-solid-default":
|
|
farbe === "ghost-brand-primary" ||
|
|
farbe === "subtle-brand-primary",
|
|
"bg-icon-ui-blue":
|
|
farbe === "ghost-blue" || farbe === "subtle-blue",
|
|
"bg-icon-ui-purple":
|
|
farbe === "ghost-purple" || farbe === "subtle-purple",
|
|
"bg-icon-feedback-information":
|
|
farbe === "ghost-information" || farbe === "subtle-information",
|
|
"bg-icon-feedback-warning":
|
|
farbe === "ghost-warning" || farbe === "subtle-warning",
|
|
"bg-icon-feedback-negative":
|
|
farbe === "ghost-negative" || farbe === "subtle-negative",
|
|
"bg-icon-feedback-positive":
|
|
farbe === "ghost-positive" || farbe === "subtle-positive",
|
|
"bg-icon-neutral-on-subtle":
|
|
farbe === "ghost-neutral" || farbe === "subtle-neutral",
|
|
}
|
|
)}
|
|
/>
|
|
{children ? (
|
|
<span
|
|
className={SubframeUtils.twClassNames(
|
|
"whitespace-nowrap text-body-small-medium-0 font-body-small-medium-0 text-text-neutral-on-solid",
|
|
{
|
|
"text-brand-brand-secondary-surface-solid-default":
|
|
farbe === "ghost-brand-secondary",
|
|
"text-brand-brand-surface-solid-default":
|
|
farbe === "ghost-brand-primary",
|
|
"text-text-ui-blue": farbe === "ghost-blue",
|
|
"text-text-ui-purple": farbe === "ghost-purple",
|
|
"text-text-feedback-information": farbe === "ghost-information",
|
|
"text-text-feedback-warning": farbe === "ghost-warning",
|
|
"text-text-feedback-negative":
|
|
farbe === "ghost-negative" || farbe === "subtle-negative",
|
|
"text-text-feedback-positive":
|
|
farbe === "ghost-positive" || farbe === "subtle-positive",
|
|
"text-text-neutral-on-subtle":
|
|
farbe === "ghost-neutral" ||
|
|
farbe === "subtle-brand-secondary" ||
|
|
farbe === "subtle-brand-primary" ||
|
|
farbe === "subtle-blue" ||
|
|
farbe === "subtle-purple" ||
|
|
farbe === "subtle-information" ||
|
|
farbe === "subtle-warning" ||
|
|
farbe === "subtle-neutral",
|
|
}
|
|
)}
|
|
>
|
|
{children}
|
|
</span>
|
|
) : null}
|
|
</div>
|
|
);
|
|
});
|
|
|
|
export const BadgeFeedback = BadgeFeedbackRoot;
|