@fastnd/components 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ export interface DonutSegment {
3
+ color: string;
4
+ dashArray: string;
5
+ dashOffset: string;
6
+ animationDelay: string;
7
+ }
8
+ export interface DonutChartProps {
9
+ total: number;
10
+ totalLabel: string;
11
+ segments: DonutSegment[];
12
+ ariaLabel: string;
13
+ className?: string;
14
+ }
15
+ export declare const DonutChart: React.ForwardRefExoticComponent<DonutChartProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ export interface FavoriteButtonProps {
3
+ pressed: boolean;
4
+ projectName: string;
5
+ variant?: 'default' | 'featured';
6
+ onToggle?: (nextPressed: boolean) => void;
7
+ className?: string;
8
+ }
9
+ export declare const FavoriteButton: React.ForwardRefExoticComponent<FavoriteButtonProps & React.RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ export type LegendItemFilter = 'alle' | 'neu' | 'offen' | 'pruefung' | 'validierung' | 'abgeschlossen';
3
+ export interface LegendItemProps {
4
+ filter: LegendItemFilter;
5
+ label: string;
6
+ count: number;
7
+ pressed: boolean;
8
+ onSelect: (filter: LegendItemFilter) => void;
9
+ className?: string;
10
+ }
11
+ export declare const LegendItem: React.ForwardRefExoticComponent<LegendItemProps & React.RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { type StatusBadgeStatus } from '../StatusBadge/StatusBadge';
3
+ export interface ProjectFeaturedProps {
4
+ name: string;
5
+ client: string;
6
+ status: StatusBadgeStatus;
7
+ statusLabel: string;
8
+ favorite: boolean;
9
+ onFavoriteToggle?: (nextPressed: boolean) => void;
10
+ className?: string;
11
+ }
12
+ export declare const ProjectFeatured: React.ForwardRefExoticComponent<ProjectFeaturedProps & React.RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { type StatusBadgeStatus } from '../StatusBadge/StatusBadge';
3
+ export interface ProjectRow {
4
+ id: string;
5
+ name: string;
6
+ client: string;
7
+ app: string;
8
+ status: StatusBadgeStatus;
9
+ statusLabel: string;
10
+ favorite: boolean;
11
+ }
12
+ export interface ProjectTableProps {
13
+ rows: ProjectRow[];
14
+ onFavoriteToggle?: (id: string, nextPressed: boolean) => void;
15
+ className?: string;
16
+ }
17
+ export declare const ProjectTable: React.ForwardRefExoticComponent<ProjectTableProps & React.RefAttributes<HTMLTableElement>>;
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { type DonutSegment } from '../DonutChart/DonutChart';
3
+ import { type LegendItemFilter } from '../LegendItem/LegendItem';
4
+ export interface StatsPanelLegendEntry {
5
+ filter: LegendItemFilter;
6
+ label: string;
7
+ count: number;
8
+ }
9
+ export interface StatsPanelProps {
10
+ total: number;
11
+ segments: DonutSegment[];
12
+ legend: StatsPanelLegendEntry[];
13
+ activeFilter: LegendItemFilter;
14
+ onFilterChange: (filter: LegendItemFilter) => void;
15
+ className?: string;
16
+ }
17
+ export declare const StatsPanel: React.ForwardRefExoticComponent<StatsPanelProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ export type StatusBadgeStatus = 'neu' | 'offen' | 'pruefung' | 'validierung' | 'abgeschlossen';
3
+ export interface StatusBadgeProps {
4
+ status: StatusBadgeStatus;
5
+ label: string;
6
+ variant?: 'default' | 'featured';
7
+ className?: string;
8
+ }
9
+ export declare const StatusBadge: React.ForwardRefExoticComponent<StatusBadgeProps & React.RefAttributes<HTMLSpanElement>>;
@@ -0,0 +1,14 @@
1
+ export { StatusBadge } from './StatusBadge/StatusBadge';
2
+ export type { StatusBadgeProps, StatusBadgeStatus } from './StatusBadge/StatusBadge';
3
+ export { FavoriteButton } from './FavoriteButton/FavoriteButton';
4
+ export type { FavoriteButtonProps } from './FavoriteButton/FavoriteButton';
5
+ export { LegendItem } from './LegendItem/LegendItem';
6
+ export type { LegendItemProps, LegendItemFilter } from './LegendItem/LegendItem';
7
+ export { DonutChart } from './DonutChart/DonutChart';
8
+ export type { DonutChartProps, DonutSegment } from './DonutChart/DonutChart';
9
+ export { StatsPanel } from './StatsPanel/StatsPanel';
10
+ export type { StatsPanelProps, StatsPanelLegendEntry } from './StatsPanel/StatsPanel';
11
+ export { ProjectFeatured } from './ProjectFeatured/ProjectFeatured';
12
+ export type { ProjectFeaturedProps } from './ProjectFeatured/ProjectFeatured';
13
+ export { ProjectTable } from './ProjectTable/ProjectTable';
14
+ export type { ProjectTableProps, ProjectRow } from './ProjectTable/ProjectTable';
@@ -0,0 +1,296 @@
1
+ (function(){"use strict";try{if(typeof document<"u"){var e=document.createElement("style");e.appendChild(document.createTextNode("._badge_982rt_1{display:inline-flex;align-items:center;gap:.375rem;padding:.25rem .75rem;border-radius:9999px;font-size:.6875rem;font-weight:500;letter-spacing:.01em;white-space:nowrap;line-height:1.4}._badge__dot_982rt_14{width:6px;height:6px;border-radius:50%}._badge--neu_982rt_20{background-color:hsl(var(--status-neu) / .1);color:hsl(var(--status-neu))}._badge--neu_982rt_20 ._badge__dot_982rt_14{background-color:hsl(var(--status-neu))}._badge--offen_982rt_26{background-color:hsl(var(--status-offen) / .1);color:hsl(var(--status-offen))}._badge--offen_982rt_26 ._badge__dot_982rt_14{background-color:hsl(var(--status-offen))}._badge--pruefung_982rt_32{background-color:hsl(var(--status-pruefung) / .12);color:#ae8813}._badge--pruefung_982rt_32 ._badge__dot_982rt_14{background-color:hsl(var(--status-pruefung))}._badge--validierung_982rt_38{background-color:hsl(var(--status-validierung) / .1);color:hsl(var(--status-validierung))}._badge--validierung_982rt_38 ._badge__dot_982rt_14{background-color:hsl(var(--status-validierung))}._badge--abgeschlossen_982rt_44{background-color:hsl(var(--score-high) / .1);color:hsl(var(--score-high))}._badge--abgeschlossen_982rt_44 ._badge__dot_982rt_14{background-color:hsl(var(--score-high))}._badge--featured_982rt_50{background-color:#fff3;color:#fff}._badge--featured_982rt_50 ._badge__dot_982rt_14{background-color:#fff}._btn_1uvto_1{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:var(--radius-sm);transition:background-color .15s ease,color .15s ease;color:hsl(var(--muted-foreground))}._btn_1uvto_1:hover{background-color:hsl(var(--muted))}._btn_1uvto_1[aria-pressed=true]{color:hsl(var(--score-medium))}._btn--featured_1uvto_20{color:#fff9}._btn--featured_1uvto_20:hover{background-color:#ffffff1a}._btn--featured_1uvto_20[aria-pressed=true]{color:#fff}._btn_1uvto_1 svg{width:18px;height:18px;pointer-events:none}._item_2eawr_1{display:flex;align-items:center;gap:.625rem;padding:.5rem .75rem;border-radius:var(--radius-md);transition:background-color .15s ease;width:100%;text-align:left}._item_2eawr_1:hover{background-color:hsl(var(--sidebar-accent))}._item_2eawr_1[aria-pressed=true]{background-color:hsl(var(--sidebar-accent));font-weight:500}._item__dot_2eawr_21{width:10px;height:10px;border-radius:50%;flex-shrink:0}._item__dot--alle_2eawr_28{background:var(--gradient-primary)}._item__dot--neu_2eawr_29{background-color:hsl(var(--status-neu))}._item__dot--offen_2eawr_30{background-color:hsl(var(--status-offen))}._item__dot--pruefung_2eawr_31{background-color:hsl(var(--status-pruefung))}._item__dot--validierung_2eawr_32{background-color:hsl(var(--status-validierung))}._item__dot--abgeschlossen_2eawr_33{background-color:hsl(var(--status-abgeschlossen))}._item__label_2eawr_35{flex:1;font-size:.8125rem;color:hsl(var(--sidebar-foreground))}._item__count_2eawr_41{font-family:var(--font-display);font-size:.8125rem;font-weight:600;color:hsl(var(--foreground));min-width:2rem;text-align:right}._chart_wxr92_1{position:relative;width:180px;height:180px}._chart__center_wxr92_7{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);text-align:center}._chart__total_wxr92_15{font-family:var(--font-display);font-size:1.75rem;font-weight:700;color:hsl(var(--foreground));line-height:1}._chart__label_wxr92_23{font-size:.625rem;color:hsl(var(--muted-foreground));text-transform:uppercase;letter-spacing:.08em;margin-top:.25rem}@keyframes _donutSegment_wxr92_1{0%{stroke-dasharray:0 100}}._segment_wxr92_35{animation:_donutSegment_wxr92_1 .8s ease forwards}@media(max-width:768px){._chart_wxr92_1{width:140px;height:140px}}@media(max-width:480px){._chart_wxr92_1{width:120px;height:120px}}._panel_dp2i7_1{background:hsl(var(--card));border-radius:var(--radius);border:1px solid hsl(var(--border));box-shadow:var(--shadow-card);padding:1.5rem;position:sticky;top:1rem;animation:_fadeSlideIn_dp2i7_1 .4s ease both}._panel__chartWrapper_dp2i7_12{display:flex;justify-content:center;margin-bottom:1.5rem}._panel__legend_dp2i7_18{list-style:none;display:flex;flex-direction:column;gap:.25rem}@keyframes _fadeSlideIn_dp2i7_1{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@media(max-width:768px){._panel_dp2i7_1{position:static;display:grid;grid-template-columns:auto 1fr;gap:1rem;align-items:start}._panel__chartWrapper_dp2i7_12{margin-bottom:0}}@media(max-width:480px){._panel_dp2i7_1{grid-template-columns:1fr}}._featured_fn5hb_1{background:var(--gradient-header);padding:1rem 1.25rem;display:flex;align-items:center;justify-content:space-between;gap:1rem}._featured__info_fn5hb_10{min-width:0}._featured__name_fn5hb_14{font-family:var(--font-display);font-size:1rem;font-weight:600;color:#fff;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._featured__client_fn5hb_24{font-size:.75rem;color:#ffffffbf;margin-top:.125rem}._featured__actions_fn5hb_30{display:flex;align-items:center;gap:.75rem;flex-shrink:0}@media(max-width:768px){._featured__name_fn5hb_14{font-size:.875rem}}@media(max-width:480px){._featured_fn5hb_1{flex-direction:column;align-items:flex-start;gap:.5rem}._featured__actions_fn5hb_30{align-self:flex-end}}._table_15o0h_1{width:100%;border-collapse:collapse}._table__head_15o0h_6{position:sticky;top:0;z-index:1}._table__headerRow_15o0h_12{border-bottom:1px solid hsl(var(--border))}._table__th_15o0h_16{padding:.625rem 1rem;font-size:.625rem;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:hsl(var(--muted-foreground));text-align:left;background:hsl(var(--secondary))}._table__th--actions_15o0h_27{width:3rem;text-align:center}._table__row_15o0h_32{border-bottom:1px solid hsl(var(--border));transition:background-color .1s ease;animation:_fadeSlideIn_15o0h_1 .3s ease both}._table__row_15o0h_32:last-child{border-bottom:none}._table__row_15o0h_32:hover{background-color:hsl(var(--sidebar-accent))}._table__row_15o0h_32[data-favorite=true]{background-color:hsl(var(--score-medium) / .04)}._table__row_15o0h_32[data-favorite=true]:hover{background-color:hsl(var(--score-medium) / .07)}._table__cell_15o0h_54{padding:.75rem 1rem;vertical-align:middle}._table__cell--name_15o0h_59{font-weight:500;color:hsl(var(--foreground))}._table__cell--client_15o0h_64,._table__cell--app_15o0h_65{color:hsl(var(--muted-foreground))}._table__cell--status_15o0h_69{white-space:nowrap}._table__cell--actions_15o0h_73{text-align:center}@keyframes _fadeSlideIn_15o0h_1{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}@media(max-width:768px){._table__th_15o0h_16,._table__cell_15o0h_54{padding:.5rem .625rem;font-size:.75rem}._table__cell--app_15o0h_65,._table__th--app_15o0h_99{display:none}}@media(max-width:480px){._table__cell--client_15o0h_64,._table__th--client_15o0h_109{display:none}}")),document.head.appendChild(e)}}catch(r){console.error("vite-plugin-css-injected-by-js",r)}})();
2
+ import { jsxs as o, jsx as t } from "react/jsx-runtime";
3
+ import h from "react";
4
+ function w(e) {
5
+ var r, l, a = "";
6
+ if (typeof e == "string" || typeof e == "number") a += e;
7
+ else if (typeof e == "object") if (Array.isArray(e)) {
8
+ var _ = e.length;
9
+ for (r = 0; r < _; r++) e[r] && (l = w(e[r])) && (a && (a += " "), a += l);
10
+ } else for (l in e) e[l] && (a && (a += " "), a += l);
11
+ return a;
12
+ }
13
+ function c() {
14
+ for (var e, r, l = 0, a = "", _ = arguments.length; l < _; l++) (e = arguments[l]) && (r = w(e)) && (a && (a += " "), a += r);
15
+ return a;
16
+ }
17
+ const j = "_badge_982rt_1", $ = "_badge__dot_982rt_14", p = {
18
+ badge: j,
19
+ badge__dot: $,
20
+ "badge--neu": "_badge--neu_982rt_20",
21
+ "badge--offen": "_badge--offen_982rt_26",
22
+ "badge--pruefung": "_badge--pruefung_982rt_32",
23
+ "badge--validierung": "_badge--validierung_982rt_38",
24
+ "badge--abgeschlossen": "_badge--abgeschlossen_982rt_44",
25
+ "badge--featured": "_badge--featured_982rt_50"
26
+ }, N = h.forwardRef(
27
+ ({ status: e, label: r, variant: l = "default", className: a }, _) => /* @__PURE__ */ o(
28
+ "span",
29
+ {
30
+ ref: _,
31
+ className: c(
32
+ p.badge,
33
+ p[`badge--${e}`],
34
+ { [p["badge--featured"]]: l === "featured" },
35
+ a
36
+ ),
37
+ children: [
38
+ /* @__PURE__ */ t("span", { className: p.badge__dot, "aria-hidden": "true" }),
39
+ r
40
+ ]
41
+ }
42
+ )
43
+ );
44
+ N.displayName = "StatusBadge";
45
+ const R = "_btn_1uvto_1", y = {
46
+ btn: R,
47
+ "btn--featured": "_btn--featured_1uvto_20"
48
+ }, v = h.forwardRef(
49
+ ({ pressed: e, projectName: r, variant: l = "default", onToggle: a, className: _ }, i) => {
50
+ const s = e ? `Favorit entfernen: ${r}` : `Favorit hinzufügen: ${r}`;
51
+ return /* @__PURE__ */ t(
52
+ "button",
53
+ {
54
+ ref: i,
55
+ type: "button",
56
+ className: c(
57
+ y.btn,
58
+ { [y["btn--featured"]]: l === "featured" },
59
+ _
60
+ ),
61
+ "aria-pressed": e,
62
+ "aria-label": s,
63
+ onClick: () => a?.(!e),
64
+ children: /* @__PURE__ */ t(
65
+ "svg",
66
+ {
67
+ xmlns: "http://www.w3.org/2000/svg",
68
+ viewBox: "0 0 24 24",
69
+ fill: e ? "currentColor" : "none",
70
+ stroke: e ? void 0 : "currentColor",
71
+ strokeWidth: e ? void 0 : 2,
72
+ "aria-hidden": "true",
73
+ children: /* @__PURE__ */ t("path", { d: "M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" })
74
+ }
75
+ )
76
+ }
77
+ );
78
+ }
79
+ );
80
+ v.displayName = "FavoriteButton";
81
+ const L = "_item_2eawr_1", P = "_item__dot_2eawr_21", D = "_item__label_2eawr_35", S = "_item__count_2eawr_41", m = {
82
+ item: L,
83
+ item__dot: P,
84
+ "item__dot--alle": "_item__dot--alle_2eawr_28",
85
+ "item__dot--neu": "_item__dot--neu_2eawr_29",
86
+ "item__dot--offen": "_item__dot--offen_2eawr_30",
87
+ "item__dot--pruefung": "_item__dot--pruefung_2eawr_31",
88
+ "item__dot--validierung": "_item__dot--validierung_2eawr_32",
89
+ "item__dot--abgeschlossen": "_item__dot--abgeschlossen_2eawr_33",
90
+ item__label: D,
91
+ item__count: S
92
+ }, k = h.forwardRef(
93
+ ({ filter: e, label: r, count: l, pressed: a, onSelect: _, className: i }, s) => /* @__PURE__ */ o(
94
+ "button",
95
+ {
96
+ ref: s,
97
+ type: "button",
98
+ role: "option",
99
+ className: c(m.item, i),
100
+ "aria-pressed": a,
101
+ "data-filter": e,
102
+ onClick: () => _(e),
103
+ children: [
104
+ /* @__PURE__ */ t(
105
+ "span",
106
+ {
107
+ className: c(m.item__dot, m[`item__dot--${e}`]),
108
+ "aria-hidden": "true"
109
+ }
110
+ ),
111
+ /* @__PURE__ */ t("span", { className: m.item__label, children: r }),
112
+ /* @__PURE__ */ t("span", { className: m.item__count, children: l })
113
+ ]
114
+ }
115
+ )
116
+ );
117
+ k.displayName = "LegendItem";
118
+ const W = "_chart_wxr92_1", A = "_chart__center_wxr92_7", B = "_chart__total_wxr92_15", C = "_chart__label_wxr92_23", F = "_segment_wxr92_35", u = {
119
+ chart: W,
120
+ chart__center: A,
121
+ chart__total: B,
122
+ chart__label: C,
123
+ segment: F
124
+ }, x = h.forwardRef(
125
+ ({ total: e, totalLabel: r, segments: l, ariaLabel: a, className: _ }, i) => /* @__PURE__ */ o("div", { ref: i, className: c(u.chart, _), role: "img", "aria-label": a, children: [
126
+ /* @__PURE__ */ o("svg", { viewBox: "0 0 42 42", width: "100%", height: "100%", children: [
127
+ /* @__PURE__ */ t(
128
+ "circle",
129
+ {
130
+ cx: "21",
131
+ cy: "21",
132
+ r: "15.915",
133
+ fill: "none",
134
+ stroke: "hsl(var(--muted))",
135
+ strokeWidth: "5"
136
+ }
137
+ ),
138
+ l.map((s, b) => /* @__PURE__ */ t(
139
+ "circle",
140
+ {
141
+ className: u.segment,
142
+ cx: "21",
143
+ cy: "21",
144
+ r: "15.915",
145
+ fill: "none",
146
+ stroke: s.color,
147
+ strokeWidth: "5",
148
+ strokeDasharray: s.dashArray,
149
+ strokeDashoffset: s.dashOffset,
150
+ strokeLinecap: "round",
151
+ style: { animationDelay: s.animationDelay }
152
+ },
153
+ b
154
+ ))
155
+ ] }),
156
+ /* @__PURE__ */ o("div", { className: u.chart__center, children: [
157
+ /* @__PURE__ */ t("div", { className: u.chart__total, children: e }),
158
+ /* @__PURE__ */ t("div", { className: u.chart__label, children: r })
159
+ ] })
160
+ ] })
161
+ );
162
+ x.displayName = "DonutChart";
163
+ const T = "_panel_dp2i7_1", z = "_panel__chartWrapper_dp2i7_12", I = "_panel__legend_dp2i7_18", g = {
164
+ panel: T,
165
+ panel__chartWrapper: z,
166
+ panel__legend: I
167
+ }, K = h.forwardRef(
168
+ ({ total: e, segments: r, legend: l, activeFilter: a, onFilterChange: _, className: i }, s) => {
169
+ const b = `Donut-Diagramm: ${l.filter((d) => d.filter !== "alle").map((d) => `${d.count} ${d.label}`).join(", ")}`;
170
+ return /* @__PURE__ */ o(
171
+ "aside",
172
+ {
173
+ ref: s,
174
+ className: c(g.panel, i),
175
+ "aria-label": "Projektstatistiken",
176
+ children: [
177
+ /* @__PURE__ */ t("div", { className: g.panel__chartWrapper, children: /* @__PURE__ */ t(
178
+ x,
179
+ {
180
+ total: e,
181
+ totalLabel: "Projekte",
182
+ segments: r,
183
+ ariaLabel: b
184
+ }
185
+ ) }),
186
+ /* @__PURE__ */ t(
187
+ "ul",
188
+ {
189
+ className: g.panel__legend,
190
+ role: "listbox",
191
+ "aria-label": "Projekte nach Status filtern",
192
+ children: l.map((d) => /* @__PURE__ */ t("li", { children: /* @__PURE__ */ t(
193
+ k,
194
+ {
195
+ filter: d.filter,
196
+ label: d.label,
197
+ count: d.count,
198
+ pressed: a === d.filter,
199
+ onSelect: _
200
+ }
201
+ ) }, d.filter))
202
+ }
203
+ )
204
+ ]
205
+ }
206
+ );
207
+ }
208
+ );
209
+ K.displayName = "StatsPanel";
210
+ const M = "_featured_fn5hb_1", O = "_featured__info_fn5hb_10", q = "_featured__name_fn5hb_14", E = "_featured__client_fn5hb_24", G = "_featured__actions_fn5hb_30", f = {
211
+ featured: M,
212
+ featured__info: O,
213
+ featured__name: q,
214
+ featured__client: E,
215
+ featured__actions: G
216
+ }, H = h.forwardRef(
217
+ ({ name: e, client: r, status: l, statusLabel: a, favorite: _, onFavoriteToggle: i, className: s }, b) => /* @__PURE__ */ o("div", { ref: b, className: c(f.featured, s), children: [
218
+ /* @__PURE__ */ o("div", { className: f.featured__info, children: [
219
+ /* @__PURE__ */ t("div", { className: f.featured__name, children: e }),
220
+ /* @__PURE__ */ t("div", { className: f.featured__client, children: r })
221
+ ] }),
222
+ /* @__PURE__ */ o("div", { className: f.featured__actions, children: [
223
+ /* @__PURE__ */ t(N, { status: l, label: a, variant: "featured" }),
224
+ /* @__PURE__ */ t(
225
+ v,
226
+ {
227
+ pressed: _,
228
+ projectName: e,
229
+ variant: "featured",
230
+ onToggle: i
231
+ }
232
+ )
233
+ ] })
234
+ ] })
235
+ );
236
+ H.displayName = "ProjectFeatured";
237
+ const J = "_table_15o0h_1", Q = "_table__head_15o0h_6", U = "_table__headerRow_15o0h_12", V = "_table__th_15o0h_16", X = "_table__row_15o0h_32", Y = "_table__cell_15o0h_54", n = {
238
+ table: J,
239
+ table__head: Q,
240
+ table__headerRow: U,
241
+ table__th: V,
242
+ "table__th--actions": "_table__th--actions_15o0h_27",
243
+ table__row: X,
244
+ table__cell: Y,
245
+ "table__cell--name": "_table__cell--name_15o0h_59",
246
+ "table__cell--client": "_table__cell--client_15o0h_64",
247
+ "table__cell--app": "_table__cell--app_15o0h_65",
248
+ "table__cell--status": "_table__cell--status_15o0h_69",
249
+ "table__cell--actions": "_table__cell--actions_15o0h_73",
250
+ "table__th--app": "_table__th--app_15o0h_99",
251
+ "table__th--client": "_table__th--client_15o0h_109"
252
+ }, Z = h.forwardRef(
253
+ ({ rows: e, onFavoriteToggle: r, className: l }, a) => /* @__PURE__ */ o("table", { ref: a, className: c(n.table, l), "aria-label": "Projekte", children: [
254
+ /* @__PURE__ */ t("thead", { className: n.table__head, children: /* @__PURE__ */ o("tr", { className: n.table__headerRow, children: [
255
+ /* @__PURE__ */ t("th", { className: n.table__th, scope: "col", children: "Projekt" }),
256
+ /* @__PURE__ */ t("th", { className: c(n.table__th, n["table__th--client"]), scope: "col", children: "Kunde" }),
257
+ /* @__PURE__ */ t("th", { className: c(n.table__th, n["table__th--app"]), scope: "col", children: "Applikation" }),
258
+ /* @__PURE__ */ t("th", { className: n.table__th, scope: "col", children: "Status" }),
259
+ /* @__PURE__ */ t("th", { className: c(n.table__th, n["table__th--actions"]), scope: "col", children: /* @__PURE__ */ t("span", { className: "sr-only", children: "Aktionen" }) })
260
+ ] }) }),
261
+ /* @__PURE__ */ t("tbody", { children: e.map((_, i) => /* @__PURE__ */ o(
262
+ "tr",
263
+ {
264
+ className: n.table__row,
265
+ "data-status": _.status,
266
+ "data-favorite": _.favorite,
267
+ style: { animationDelay: `${0.15 + i * 0.03}s` },
268
+ children: [
269
+ /* @__PURE__ */ t("td", { className: c(n.table__cell, n["table__cell--name"]), children: _.name }),
270
+ /* @__PURE__ */ t("td", { className: c(n.table__cell, n["table__cell--client"]), children: _.client }),
271
+ /* @__PURE__ */ t("td", { className: c(n.table__cell, n["table__cell--app"]), children: _.app }),
272
+ /* @__PURE__ */ t("td", { className: c(n.table__cell, n["table__cell--status"]), children: /* @__PURE__ */ t(N, { status: _.status, label: _.statusLabel }) }),
273
+ /* @__PURE__ */ t("td", { className: c(n.table__cell, n["table__cell--actions"]), children: /* @__PURE__ */ t(
274
+ v,
275
+ {
276
+ pressed: _.favorite,
277
+ projectName: _.name,
278
+ onToggle: (s) => r?.(_.id, s)
279
+ }
280
+ ) })
281
+ ]
282
+ },
283
+ _.id
284
+ )) })
285
+ ] })
286
+ );
287
+ Z.displayName = "ProjectTable";
288
+ export {
289
+ x as DonutChart,
290
+ v as FavoriteButton,
291
+ k as LegendItem,
292
+ H as ProjectFeatured,
293
+ Z as ProjectTable,
294
+ K as StatsPanel,
295
+ N as StatusBadge
296
+ };
@@ -0,0 +1,2 @@
1
+ import './tokens.module.css';
2
+ export * from './components';
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@fastnd/components",
3
+ "version": "1.0.4",
4
+ "type": "module",
5
+ "main": "./dist/components.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/components.js",
10
+ "types": "./dist/index.d.ts"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "publishConfig": {
17
+ "registry": "https://registry.npmjs.org",
18
+ "access": "public"
19
+ },
20
+ "scripts": {
21
+ "build": "vite build && tsc -p tsconfig.build.json",
22
+ "storybook": "storybook dev -p 6006",
23
+ "build-storybook": "storybook build",
24
+ "test": "vitest",
25
+ "test:run": "vitest run",
26
+ "test:ui": "vitest --ui"
27
+ },
28
+ "peerDependencies": {
29
+ "react": "^18.0.0 || ^19.0.0",
30
+ "react-dom": "^18.0.0 || ^19.0.0"
31
+ },
32
+ "dependencies": {
33
+ "clsx": "2.1.1"
34
+ },
35
+ "devDependencies": {
36
+ "@storybook/react-vite": "^10.2.15",
37
+ "@testing-library/dom": "^10.4.0",
38
+ "@testing-library/jest-dom": "^6.6.3",
39
+ "@testing-library/react": "^16.3.2",
40
+ "@testing-library/user-event": "^14.6.1",
41
+ "@types/react": "^19.1.0",
42
+ "@types/react-dom": "^19.1.0",
43
+ "@vitejs/plugin-react-swc": "^4.2.3",
44
+ "jsdom": "^28.1.0",
45
+ "react": "19.2.0",
46
+ "react-dom": "19.2.0",
47
+ "storybook": "^10.2.15",
48
+ "typescript": "^5.9.3",
49
+ "vite": "^7.3.1",
50
+ "vite-plugin-css-injected-by-js": "^3.5.2",
51
+ "vitest": "^4.0.18"
52
+ }
53
+ }