@cosmicdrift/kumiko-renderer-web 0.37.0 → 0.38.0
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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-renderer-web",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.38.0",
|
|
4
4
|
"description": "Web-platform bindings for @cosmicdrift/kumiko-renderer. HTML default-primitives, browser history-based navigation, EventSource-backed live events, and a one-call createKumikoApp that mounts the whole stack via react-dom.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
"./styles.css": "./src/styles.css"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@cosmicdrift/kumiko-dispatcher-live": "0.
|
|
20
|
-
"@cosmicdrift/kumiko-headless": "0.
|
|
21
|
-
"@cosmicdrift/kumiko-renderer": "0.
|
|
19
|
+
"@cosmicdrift/kumiko-dispatcher-live": "0.37.0",
|
|
20
|
+
"@cosmicdrift/kumiko-headless": "0.37.0",
|
|
21
|
+
"@cosmicdrift/kumiko-renderer": "0.37.0",
|
|
22
22
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
23
23
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
24
24
|
"@radix-ui/react-label": "^2.1.8",
|
|
@@ -5,7 +5,11 @@
|
|
|
5
5
|
// Nutzt useTranslation → über test-utils mit LocaleProvider gerendert.
|
|
6
6
|
|
|
7
7
|
import { describe, expect, mock, test } from "bun:test";
|
|
8
|
-
import
|
|
8
|
+
import {
|
|
9
|
+
createStaticLocaleResolver,
|
|
10
|
+
LocaleProvider,
|
|
11
|
+
type WorkspaceSchema,
|
|
12
|
+
} from "@cosmicdrift/kumiko-renderer";
|
|
9
13
|
import { fireEvent, render, screen } from "../../__tests__/test-utils";
|
|
10
14
|
import { WorkspaceSwitcher } from "../workspace-switcher";
|
|
11
15
|
|
|
@@ -48,3 +52,24 @@ describe("WorkspaceSwitcher — Render", () => {
|
|
|
48
52
|
expect(onSelect).toHaveBeenCalledWith("b");
|
|
49
53
|
});
|
|
50
54
|
});
|
|
55
|
+
|
|
56
|
+
describe("WorkspaceSwitcher — i18n-Labels (Punkt-Konvention)", () => {
|
|
57
|
+
test("Label mit Punkt geht durch t() und rendert die Übersetzung", () => {
|
|
58
|
+
const bundle = { en: { "nav.adminArea": "Admin Area" } };
|
|
59
|
+
const { getByTestId } = render(
|
|
60
|
+
<LocaleProvider
|
|
61
|
+
resolver={createStaticLocaleResolver({ locale: "en" })}
|
|
62
|
+
fallbackBundles={[bundle]}
|
|
63
|
+
>
|
|
64
|
+
<WorkspaceSwitcher
|
|
65
|
+
workspaces={[ws("a", "nav.adminArea"), ws("b", "Plain Label")]}
|
|
66
|
+
activeId="a"
|
|
67
|
+
onSelect={mock()}
|
|
68
|
+
/>
|
|
69
|
+
</LocaleProvider>,
|
|
70
|
+
);
|
|
71
|
+
expect(getByTestId("workspace-tab-a").textContent).toBe("Admin Area");
|
|
72
|
+
// ohne Punkt: verbatim, kein t()-Roundtrip
|
|
73
|
+
expect(getByTestId("workspace-tab-b").textContent).toBe("Plain Label");
|
|
74
|
+
});
|
|
75
|
+
});
|
package/src/layout/avatar.tsx
CHANGED
|
@@ -61,7 +61,7 @@ function pickColor(id: string): string {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
function extractInitials(label: string): string {
|
|
64
|
-
// "Daniel Hennig" → "DH". "alice@example.com" → "
|
|
64
|
+
// "Daniel Hennig" → "DH". "alice@example.com" → "AL". Single-word
|
|
65
65
|
// fällt auf erste 2 Buchstaben zurück ("Daniel" → "DA"). Alles
|
|
66
66
|
// upper-case.
|
|
67
67
|
const trimmed = label.trim();
|
|
@@ -38,6 +38,24 @@ describe("computeVisiblePages", () => {
|
|
|
38
38
|
test("page=5/20: Übergang Rand→Mitte (Ellipsis links erscheint)", () => {
|
|
39
39
|
expect(computeVisiblePages(5, 20)).toEqual([1, "ellipsis", 3, 4, 5, 6, 7, "ellipsis", 20]);
|
|
40
40
|
});
|
|
41
|
+
|
|
42
|
+
test("page=16/20: letzte Mitte-Position (Ellipsis rechts noch da)", () => {
|
|
43
|
+
expect(computeVisiblePages(16, 20)).toEqual([
|
|
44
|
+
1,
|
|
45
|
+
"ellipsis",
|
|
46
|
+
14,
|
|
47
|
+
15,
|
|
48
|
+
16,
|
|
49
|
+
17,
|
|
50
|
+
18,
|
|
51
|
+
"ellipsis",
|
|
52
|
+
20,
|
|
53
|
+
]);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test("page=17/20: Übergang Mitte→Rand (Ellipsis rechts verschwindet, 5er-Tail)", () => {
|
|
57
|
+
expect(computeVisiblePages(17, 20)).toEqual([1, "ellipsis", 16, 17, 18, 19, 20]);
|
|
58
|
+
});
|
|
41
59
|
});
|
|
42
60
|
|
|
43
61
|
describe("isComponentRendererRef", () => {
|
|
@@ -61,10 +79,10 @@ describe("isComponentRendererRef", () => {
|
|
|
61
79
|
});
|
|
62
80
|
|
|
63
81
|
describe("applyFormatSpec", () => {
|
|
64
|
-
test("null/undefined/leer → leerer String (
|
|
82
|
+
test("null/undefined/leer → leerer String (priority rendert stattdessen emptyLabel)", () => {
|
|
65
83
|
expect(applyFormatSpec({ format: "boolean" }, null)).toBe("");
|
|
66
84
|
expect(applyFormatSpec({ format: "currency", symbol: "€" }, undefined)).toBe("");
|
|
67
|
-
expect(applyFormatSpec({ format: "priority" }, "")).toBe("");
|
|
85
|
+
expect(applyFormatSpec({ format: "priority" }, "")).toBe("—");
|
|
68
86
|
});
|
|
69
87
|
|
|
70
88
|
test("boolean: true → ✓, false → leer (defaults)", () => {
|
|
@@ -101,12 +119,20 @@ describe("applyFormatSpec", () => {
|
|
|
101
119
|
});
|
|
102
120
|
|
|
103
121
|
test("unbekanntes format → String(value) fallback + dev-warning", () => {
|
|
122
|
+
// Warnung feuert nur bei NODE_ENV !== "production" — explizit setzen
|
|
123
|
+
// statt sich aufs Test-Runner-Preset zu verlassen.
|
|
124
|
+
const prevNodeEnv = process.env.NODE_ENV;
|
|
125
|
+
process.env.NODE_ENV = "development";
|
|
104
126
|
const warn = spyOn(console, "warn").mockImplementation(() => {});
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
127
|
+
try {
|
|
128
|
+
expect(applyFormatSpec({ format: "custom-app-format" }, 42)).toBe("42");
|
|
129
|
+
expect(applyFormatSpec({ format: "custom-app-format" }, "hello")).toBe("hello");
|
|
130
|
+
expect(warn).toHaveBeenCalledTimes(2);
|
|
131
|
+
expect(warn.mock.calls[0]?.[0]).toContain("custom-app-format");
|
|
132
|
+
} finally {
|
|
133
|
+
warn.mockRestore();
|
|
134
|
+
process.env.NODE_ENV = prevNodeEnv;
|
|
135
|
+
}
|
|
110
136
|
});
|
|
111
137
|
});
|
|
112
138
|
|