@react-text-game/ui 0.2.3 → 0.3.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.
Files changed (75) hide show
  1. package/README.md +67 -0
  2. package/dist/components/GameProvider/GameProvider.d.ts.map +1 -1
  3. package/dist/components/GameProvider/GameProvider.js +2 -1
  4. package/dist/components/GameProvider/GameProvider.js.map +1 -1
  5. package/dist/components/LanguageToggle.d.ts +47 -0
  6. package/dist/components/LanguageToggle.d.ts.map +1 -0
  7. package/dist/components/LanguageToggle.js +56 -0
  8. package/dist/components/LanguageToggle.js.map +1 -0
  9. package/dist/components/MainMenu.d.ts.map +1 -1
  10. package/dist/components/MainMenu.js +6 -5
  11. package/dist/components/MainMenu.js.map +1 -1
  12. package/dist/components/ReloadButton.d.ts.map +1 -1
  13. package/dist/components/ReloadButton.js +1 -0
  14. package/dist/components/ReloadButton.js.map +1 -1
  15. package/dist/components/SaveButton.d.ts.map +1 -1
  16. package/dist/components/SaveButton.js +1 -0
  17. package/dist/components/SaveButton.js.map +1 -1
  18. package/dist/components/SaveLoadModal/SaveLoadModal.d.ts +1 -1
  19. package/dist/components/SaveLoadModal/SaveLoadModal.d.ts.map +1 -1
  20. package/dist/components/SaveLoadModal/SaveLoadModal.js +11 -3
  21. package/dist/components/SaveLoadModal/SaveLoadModal.js.map +1 -1
  22. package/dist/components/SaveLoadModal/SaveSlot.d.ts +16 -0
  23. package/dist/components/SaveLoadModal/SaveSlot.d.ts.map +1 -0
  24. package/dist/components/SaveLoadModal/SaveSlot.js +21 -0
  25. package/dist/components/SaveLoadModal/SaveSlot.js.map +1 -0
  26. package/dist/components/StoryComponent/StoryComponent.d.ts.map +1 -1
  27. package/dist/components/StoryComponent/StoryComponent.js +25 -4
  28. package/dist/components/StoryComponent/StoryComponent.js.map +1 -1
  29. package/dist/components/StoryComponent/components/Conversation.d.ts.map +1 -1
  30. package/dist/components/StoryComponent/components/Conversation.js +32 -6
  31. package/dist/components/StoryComponent/components/Conversation.js.map +1 -1
  32. package/dist/components/index.d.ts +2 -1
  33. package/dist/components/index.d.ts.map +1 -1
  34. package/dist/components/index.js +2 -1
  35. package/dist/components/index.js.map +1 -1
  36. package/dist/context/ComponentsContext/ComponentsContext.d.ts.map +1 -1
  37. package/dist/context/ComponentsContext/ComponentsContext.js +1 -0
  38. package/dist/context/ComponentsContext/ComponentsContext.js.map +1 -1
  39. package/dist/context/ComponentsContext/types.d.ts.map +1 -1
  40. package/dist/context/ConversationClickContext/ConversationClickContext.d.ts +8 -0
  41. package/dist/context/ConversationClickContext/ConversationClickContext.d.ts.map +1 -0
  42. package/dist/context/ConversationClickContext/ConversationClickContext.js +4 -0
  43. package/dist/context/ConversationClickContext/ConversationClickContext.js.map +1 -0
  44. package/dist/context/ConversationClickContext/ConversationClickProvider.d.ts +3 -0
  45. package/dist/context/ConversationClickContext/ConversationClickProvider.d.ts.map +1 -0
  46. package/dist/context/ConversationClickContext/ConversationClickProvider.js +25 -0
  47. package/dist/context/ConversationClickContext/ConversationClickProvider.js.map +1 -0
  48. package/dist/context/ConversationClickContext/index.d.ts +4 -0
  49. package/dist/context/ConversationClickContext/index.d.ts.map +1 -0
  50. package/dist/context/ConversationClickContext/index.js +4 -0
  51. package/dist/context/ConversationClickContext/index.js.map +1 -0
  52. package/dist/context/ConversationClickContext/useConversationClickContext.d.ts +2 -0
  53. package/dist/context/ConversationClickContext/useConversationClickContext.d.ts.map +1 -0
  54. package/dist/context/ConversationClickContext/useConversationClickContext.js +10 -0
  55. package/dist/context/ConversationClickContext/useConversationClickContext.js.map +1 -0
  56. package/dist/hooks/index.d.ts +1 -1
  57. package/dist/hooks/index.js +1 -1
  58. package/dist/i18n/index.d.ts +37 -0
  59. package/dist/i18n/index.d.ts.map +1 -0
  60. package/dist/i18n/index.js +5 -0
  61. package/dist/i18n/index.js.map +1 -0
  62. package/dist/i18n/locales/en/ui.json +32 -0
  63. package/dist/index.d.ts +2 -2
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js.map +1 -1
  66. package/dist/styles/index.css +50 -35
  67. package/dist/tests/GameProvider.test.d.ts +2 -0
  68. package/dist/tests/GameProvider.test.d.ts.map +1 -0
  69. package/dist/tests/GameProvider.test.js +178 -0
  70. package/dist/tests/GameProvider.test.js.map +1 -0
  71. package/dist/tests/StoryComponent/Conversation.test.d.ts +2 -0
  72. package/dist/tests/StoryComponent/Conversation.test.d.ts.map +1 -0
  73. package/dist/tests/StoryComponent/Conversation.test.js +306 -0
  74. package/dist/tests/StoryComponent/Conversation.test.js.map +1 -0
  75. package/package.json +12 -3
@@ -0,0 +1,178 @@
1
+ import { Game, Passage, SYSTEM_PASSAGE_NAMES } from "@react-text-game/core";
2
+ import { cleanup, render, screen, waitFor } from "@testing-library/react";
3
+ import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test";
4
+ import { createElement } from "react";
5
+ import { GameProvider } from "../components/GameProvider";
6
+ // Test passage class
7
+ class TestPassage extends Passage {
8
+ constructor(id) {
9
+ super(id, "widget");
10
+ }
11
+ display() {
12
+ return { content: `Passage: ${this.id}` };
13
+ }
14
+ }
15
+ describe("GameProvider", () => {
16
+ beforeEach(() => {
17
+ // Clear any previous game state
18
+ Game._resetForTesting();
19
+ });
20
+ afterEach(() => {
21
+ cleanup();
22
+ });
23
+ describe("Initialization", () => {
24
+ test("initializes Game with provided options", async () => {
25
+ const options = {
26
+ gameName: "Test Game",
27
+ gameId: "test-game-id",
28
+ description: "A test game",
29
+ gameVersion: "1.0.0",
30
+ author: "Test Author",
31
+ };
32
+ render(createElement(GameProvider, { options }, createElement("div", null, "Test content")));
33
+ await waitFor(() => {
34
+ expect(Game.options.gameName).toBe("Test Game");
35
+ expect(Game.options.gameId).toBe("test-game-id");
36
+ expect(Game.options.description).toBe("A test game");
37
+ expect(Game.options.gameVersion).toBe("1.0.0");
38
+ expect(Game.options.author).toBe("Test Author");
39
+ });
40
+ });
41
+ test("returns null before initialization is complete", () => {
42
+ const { container } = render(createElement(GameProvider, { options: { gameName: "test" } }, createElement("div", null, "Test content")));
43
+ // Before initialization, nothing should be rendered
44
+ expect(container.innerHTML).toBe("");
45
+ });
46
+ test("renders children after initialization", async () => {
47
+ render(createElement(GameProvider, { options: { gameName: "test" } }, createElement("div", { "data-testid": "child" }, "Test content")));
48
+ await waitFor(() => {
49
+ expect(screen.getByTestId("child")).toBeTruthy();
50
+ expect(screen.getByText("Test content")).toBeTruthy();
51
+ });
52
+ });
53
+ });
54
+ describe("Start Passage Handling", () => {
55
+ test("sets currentPassage to provided startPassage option", async () => {
56
+ const testPassageId = "test-value";
57
+ // Initialize Game first
58
+ await Game.init({ gameName: "test", startPassage: testPassageId });
59
+ // Create the test passage before rendering
60
+ new TestPassage(testPassageId);
61
+ render(createElement(GameProvider, { options: { gameName: "test", startPassage: testPassageId } }, createElement("div", null, "Test content")));
62
+ await waitFor(() => {
63
+ expect(Game.currentPassage?.id).toBe(testPassageId);
64
+ }, { timeout: 1000 });
65
+ });
66
+ test("sets currentPassage to START_MENU when startPassage is not provided", async () => {
67
+ render(createElement(GameProvider, { options: { gameName: "test" } }, createElement("div", null, "Test content")));
68
+ await waitFor(() => {
69
+ expect(Game.currentPassage?.id).toBe(SYSTEM_PASSAGE_NAMES.START_MENU);
70
+ });
71
+ });
72
+ });
73
+ describe("Custom Components", () => {
74
+ test("uses custom MainMenu component when provided", async () => {
75
+ const CustomMainMenu = () => createElement("div", { "data-testid": "custom-menu" }, "Custom Menu");
76
+ const components = {
77
+ MainMenu: () => createElement(CustomMainMenu),
78
+ };
79
+ render(createElement(GameProvider, { options: { gameName: "test" }, components }, createElement("div", null, "Test content")));
80
+ await waitFor(() => {
81
+ expect(screen.getByText("Test content")).toBeTruthy();
82
+ });
83
+ });
84
+ test("uses default MainMenu when custom component is not provided", async () => {
85
+ render(createElement(GameProvider, { options: { gameName: "test" } }, createElement("div", null, "Test content")));
86
+ await waitFor(() => {
87
+ expect(screen.getByText("Test content")).toBeTruthy();
88
+ });
89
+ });
90
+ });
91
+ describe("Dev Mode Features", () => {
92
+ test("renders dev mode components when isDevMode is true", async () => {
93
+ render(createElement(GameProvider, { options: { gameName: "test", isDevMode: true } }, createElement("div", null, "Test content")));
94
+ await waitFor(() => {
95
+ expect(screen.getByText("Test content")).toBeTruthy();
96
+ // Dev mode components should be rendered
97
+ // Note: We can't easily test AppIconMenu and DevModeDrawer without more setup
98
+ });
99
+ });
100
+ test("does not render dev mode components when isDevMode is false", async () => {
101
+ render(createElement(GameProvider, { options: { gameName: "test", isDevMode: false } }, createElement("div", null, "Test content")));
102
+ await waitFor(() => {
103
+ expect(screen.getByText("Test content")).toBeTruthy();
104
+ });
105
+ });
106
+ test("does not render dev mode components when isDevMode is undefined", async () => {
107
+ render(createElement(GameProvider, { options: { gameName: "test" } }, createElement("div", null, "Test content")));
108
+ await waitFor(() => {
109
+ expect(screen.getByText("Test content")).toBeTruthy();
110
+ });
111
+ });
112
+ });
113
+ describe("Context Providers", () => {
114
+ test("wraps children with ErrorBoundary", async () => {
115
+ render(createElement(GameProvider, { options: { gameName: "test" } }, createElement("div", null, "Test content")));
116
+ await waitFor(() => {
117
+ expect(screen.getByText("Test content")).toBeTruthy();
118
+ });
119
+ // If ErrorBoundary wasn't present, errors would crash the test
120
+ });
121
+ test("wraps children with ComponentsProvider", async () => {
122
+ render(createElement(GameProvider, { options: { gameName: "test" } }, createElement("div", null, "Test content")));
123
+ await waitFor(() => {
124
+ expect(screen.getByText("Test content")).toBeTruthy();
125
+ });
126
+ });
127
+ test("wraps children with SaveLoadMenuProvider", async () => {
128
+ render(createElement(GameProvider, { options: { gameName: "test" } }, createElement("div", null, "Test content")));
129
+ await waitFor(() => {
130
+ expect(screen.getByText("Test content")).toBeTruthy();
131
+ });
132
+ });
133
+ });
134
+ describe("Options Update", () => {
135
+ test("updates Game options when internalOptions change", async () => {
136
+ Game.updateOptions = mock(Game.updateOptions.bind(Game));
137
+ render(createElement(GameProvider, { options: { gameName: "test" } }, createElement("div", null, "Test content")));
138
+ await waitFor(() => {
139
+ expect(screen.getByText("Test content")).toBeTruthy();
140
+ });
141
+ // Note: Testing internal option updates would require exposing setInternalOptions
142
+ // or triggering it through AppIconMenu interactions
143
+ });
144
+ });
145
+ describe("Widget Registration", () => {
146
+ test("registers START_MENU widget during initialization", async () => {
147
+ render(createElement(GameProvider, { options: { gameName: "test" } }, createElement("div", null, "Test content")));
148
+ await waitFor(() => {
149
+ expect(Game.currentPassage?.id).toBe(SYSTEM_PASSAGE_NAMES.START_MENU);
150
+ });
151
+ });
152
+ test("registers custom MainMenu widget when provided", async () => {
153
+ const CustomMainMenu = () => createElement("div", null, "Custom Menu");
154
+ const components = {
155
+ MainMenu: () => createElement(CustomMainMenu),
156
+ };
157
+ render(createElement(GameProvider, { options: { gameName: "test" }, components }, createElement("div", null, "Test content")));
158
+ await waitFor(() => {
159
+ expect(Game.currentPassage?.id).toBe(SYSTEM_PASSAGE_NAMES.START_MENU);
160
+ });
161
+ });
162
+ });
163
+ describe("Multiple Instances", () => {
164
+ test("handles re-initialization when options change", async () => {
165
+ const { rerender } = render(createElement(GameProvider, { options: { gameName: "test1" } }, createElement("div", null, "Test content 1")));
166
+ await waitFor(() => {
167
+ expect(screen.getByText("Test content 1")).toBeTruthy();
168
+ expect(Game.options.gameName).toBe("test1");
169
+ });
170
+ // Re-render with different options
171
+ rerender(createElement(GameProvider, { options: { gameName: "test2" } }, createElement("div", null, "Test content 2")));
172
+ await waitFor(() => {
173
+ expect(screen.getByText("Test content 2")).toBeTruthy();
174
+ });
175
+ });
176
+ });
177
+ });
178
+ //# sourceMappingURL=GameProvider.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GameProvider.test.js","sourceRoot":"","sources":["../../src/tests/GameProvider.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=Conversation.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Conversation.test.d.ts","sourceRoot":"","sources":["../../../src/tests/StoryComponent/Conversation.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,306 @@
1
+ import { cleanup, render, screen, waitFor } from "@testing-library/react";
2
+ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
3
+ import { createElement } from "react";
4
+ import { Conversation } from "../../components/StoryComponent/components/Conversation";
5
+ describe("Conversation", () => {
6
+ beforeEach(() => {
7
+ // Any setup if needed
8
+ });
9
+ afterEach(() => {
10
+ cleanup();
11
+ });
12
+ describe("Appearance: atOnce", () => {
13
+ test("renders all conversation bubbles immediately", () => {
14
+ const component = {
15
+ type: "conversation",
16
+ appearance: "atOnce",
17
+ content: [
18
+ { content: "Hello there!", side: "left" },
19
+ { content: "Hi! How are you?", side: "right" },
20
+ { content: "I'm doing great!", side: "left" },
21
+ ],
22
+ };
23
+ render(createElement(Conversation, { component }));
24
+ expect(screen.getByText("Hello there!")).toBeTruthy();
25
+ expect(screen.getByText("Hi! How are you?")).toBeTruthy();
26
+ expect(screen.getByText("I'm doing great!")).toBeTruthy();
27
+ });
28
+ test("displays avatars with images correctly", () => {
29
+ const component = {
30
+ type: "conversation",
31
+ appearance: "atOnce",
32
+ content: [
33
+ {
34
+ content: "Hello!",
35
+ who: {
36
+ name: "NPC",
37
+ avatar: "/avatar.png",
38
+ },
39
+ side: "left",
40
+ },
41
+ ],
42
+ };
43
+ render(createElement(Conversation, { component }));
44
+ const avatar = screen.getByAltText("NPC");
45
+ expect(avatar).toBeTruthy();
46
+ expect(avatar.getAttribute("src")).toBe("/avatar.png");
47
+ });
48
+ test("displays fallback avatar with first letter of name", () => {
49
+ const component = {
50
+ type: "conversation",
51
+ appearance: "atOnce",
52
+ content: [
53
+ {
54
+ content: "Hello!",
55
+ who: {
56
+ name: "John",
57
+ },
58
+ side: "left",
59
+ },
60
+ ],
61
+ };
62
+ render(createElement(Conversation, { component }));
63
+ expect(screen.getByText("J")).toBeTruthy();
64
+ });
65
+ test("displays question mark when no name provided", () => {
66
+ const component = {
67
+ type: "conversation",
68
+ appearance: "atOnce",
69
+ content: [
70
+ {
71
+ content: "Anonymous message",
72
+ side: "left",
73
+ },
74
+ ],
75
+ };
76
+ render(createElement(Conversation, { component }));
77
+ expect(screen.getByText("?")).toBeTruthy();
78
+ });
79
+ test("renders left and right side bubbles correctly", () => {
80
+ const component = {
81
+ type: "conversation",
82
+ appearance: "atOnce",
83
+ content: [
84
+ { content: "Left message", side: "left" },
85
+ { content: "Right message", side: "right" },
86
+ ],
87
+ };
88
+ render(createElement(Conversation, { component }));
89
+ expect(screen.getByText("Left message")).toBeTruthy();
90
+ expect(screen.getByText("Right message")).toBeTruthy();
91
+ // Check that different styles are applied based on side
92
+ const leftBubble = screen
93
+ .getByText("Left message")
94
+ .closest("div");
95
+ const rightBubble = screen
96
+ .getByText("Right message")
97
+ .closest("div");
98
+ expect(leftBubble).toBeTruthy();
99
+ expect(rightBubble).toBeTruthy();
100
+ });
101
+ test("applies custom className from props", () => {
102
+ const component = {
103
+ type: "conversation",
104
+ appearance: "atOnce",
105
+ content: [{ content: "Test", side: "left" }],
106
+ props: {
107
+ className: "custom-conversation-class",
108
+ },
109
+ };
110
+ const { container } = render(createElement(Conversation, { component }));
111
+ const conversationContainer = container.querySelector(".custom-conversation-class");
112
+ expect(conversationContainer).toBeTruthy();
113
+ });
114
+ test("renders with chat variant (default)", () => {
115
+ const component = {
116
+ type: "conversation",
117
+ appearance: "atOnce",
118
+ content: [{ content: "Chat message", side: "left" }],
119
+ };
120
+ render(createElement(Conversation, { component }));
121
+ expect(screen.getByText("Chat message")).toBeTruthy();
122
+ });
123
+ test("renders with messenger variant", () => {
124
+ const component = {
125
+ type: "conversation",
126
+ appearance: "atOnce",
127
+ content: [{ content: "Messenger message", side: "left" }],
128
+ props: {
129
+ variant: "messenger",
130
+ },
131
+ };
132
+ render(createElement(Conversation, { component }));
133
+ expect(screen.getByText("Messenger message")).toBeTruthy();
134
+ });
135
+ });
136
+ describe("Appearance: byClick", () => {
137
+ test("shows first bubble immediately", () => {
138
+ const component = {
139
+ type: "conversation",
140
+ appearance: "byClick",
141
+ content: [
142
+ { content: "First message", side: "left" },
143
+ { content: "Second message", side: "left" },
144
+ { content: "Third message", side: "left" },
145
+ ],
146
+ };
147
+ render(createElement(Conversation, { component }));
148
+ // First bubble should be visible immediately
149
+ expect(screen.getByText("First message")).toBeTruthy();
150
+ // Other bubbles should not be visible yet
151
+ expect(screen.queryByText("Second message")).toBeNull();
152
+ expect(screen.queryByText("Third message")).toBeNull();
153
+ });
154
+ test("shows next bubble on click", async () => {
155
+ const component = {
156
+ type: "conversation",
157
+ appearance: "byClick",
158
+ content: [
159
+ { content: "First message", side: "left" },
160
+ { content: "Second message", side: "left" },
161
+ ],
162
+ };
163
+ render(createElement(Conversation, { component }));
164
+ // First bubble should be visible
165
+ expect(screen.getByText("First message")).toBeTruthy();
166
+ expect(screen.queryByText("Second message")).toBeNull();
167
+ // Click on the first bubble
168
+ const firstBubble = screen.getByText("First message");
169
+ firstBubble.click();
170
+ // Second bubble should now be visible
171
+ await waitFor(() => {
172
+ expect(screen.getByText("Second message")).toBeTruthy();
173
+ });
174
+ });
175
+ test("shows all bubbles sequentially with multiple clicks", async () => {
176
+ const component = {
177
+ type: "conversation",
178
+ appearance: "byClick",
179
+ content: [
180
+ { content: "First", side: "left" },
181
+ { content: "Second", side: "left" },
182
+ { content: "Third", side: "left" },
183
+ ],
184
+ };
185
+ render(createElement(Conversation, { component }));
186
+ // First is visible
187
+ expect(screen.getByText("First")).toBeTruthy();
188
+ expect(screen.queryByText("Second")).toBeNull();
189
+ // Click to show second
190
+ screen.getByText("First").click();
191
+ await waitFor(() => {
192
+ expect(screen.getByText("Second")).toBeTruthy();
193
+ });
194
+ // Click to show third
195
+ screen.getByText("First").click();
196
+ await waitFor(() => {
197
+ expect(screen.getByText("Third")).toBeTruthy();
198
+ });
199
+ });
200
+ test("doesn't add more bubbles after all are shown", async () => {
201
+ const component = {
202
+ type: "conversation",
203
+ appearance: "byClick",
204
+ content: [
205
+ { content: "First", side: "left" },
206
+ { content: "Second", side: "left" },
207
+ ],
208
+ };
209
+ const { container } = render(createElement(Conversation, { component }));
210
+ // Show all bubbles
211
+ screen.getByText("First").click();
212
+ await waitFor(() => {
213
+ expect(screen.getByText("Second")).toBeTruthy();
214
+ });
215
+ // Count bubbles
216
+ const bubblesBefore = container.querySelectorAll("div").length;
217
+ // Click again
218
+ screen.getByText("First").click();
219
+ // Should have same number of bubbles
220
+ const bubblesAfter = container.querySelectorAll("div").length;
221
+ expect(bubblesAfter).toBe(bubblesBefore);
222
+ });
223
+ test("handles single bubble conversation", () => {
224
+ const component = {
225
+ type: "conversation",
226
+ appearance: "byClick",
227
+ content: [{ content: "Only message", side: "left" }],
228
+ };
229
+ render(createElement(Conversation, { component }));
230
+ expect(screen.getByText("Only message")).toBeTruthy();
231
+ });
232
+ });
233
+ describe("Edge Cases", () => {
234
+ test("handles empty conversation content", () => {
235
+ const component = {
236
+ type: "conversation",
237
+ appearance: "atOnce",
238
+ content: [],
239
+ };
240
+ const { container } = render(createElement(Conversation, { component }));
241
+ // Should render without errors, just empty
242
+ expect(container.innerHTML).toBeTruthy();
243
+ });
244
+ test("handles conversation with missing who data", () => {
245
+ const component = {
246
+ type: "conversation",
247
+ appearance: "atOnce",
248
+ content: [
249
+ {
250
+ content: "Message without who",
251
+ side: "left",
252
+ },
253
+ ],
254
+ };
255
+ render(createElement(Conversation, { component }));
256
+ expect(screen.getByText("Message without who")).toBeTruthy();
257
+ expect(screen.getByText("?")).toBeTruthy(); // Fallback avatar
258
+ });
259
+ test("handles conversation with custom bubble classNames", () => {
260
+ const component = {
261
+ type: "conversation",
262
+ appearance: "atOnce",
263
+ content: [
264
+ {
265
+ content: "Custom styled",
266
+ side: "left",
267
+ props: {
268
+ classNames: {
269
+ base: "custom-base",
270
+ content: "custom-content",
271
+ avatar: "custom-avatar",
272
+ },
273
+ },
274
+ },
275
+ ],
276
+ };
277
+ const { container } = render(createElement(Conversation, { component }));
278
+ expect(screen.getByText("Custom styled")).toBeTruthy();
279
+ // Check that custom classes are applied
280
+ const baseElement = container.querySelector(".custom-base");
281
+ const contentElement = container.querySelector(".custom-content");
282
+ const avatarElement = container.querySelector(".custom-avatar");
283
+ expect(baseElement).toBeTruthy();
284
+ expect(contentElement).toBeTruthy();
285
+ expect(avatarElement).toBeTruthy();
286
+ });
287
+ test("handles mixed sides in conversation", () => {
288
+ const component = {
289
+ type: "conversation",
290
+ appearance: "atOnce",
291
+ content: [
292
+ { content: "Left 1", side: "left" },
293
+ { content: "Right 1", side: "right" },
294
+ { content: "Left 2", side: "left" },
295
+ { content: "Right 2", side: "right" },
296
+ ],
297
+ };
298
+ render(createElement(Conversation, { component }));
299
+ expect(screen.getByText("Left 1")).toBeTruthy();
300
+ expect(screen.getByText("Right 1")).toBeTruthy();
301
+ expect(screen.getByText("Left 2")).toBeTruthy();
302
+ expect(screen.getByText("Right 2")).toBeTruthy();
303
+ });
304
+ });
305
+ });
306
+ //# sourceMappingURL=Conversation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Conversation.test.js","sourceRoot":"","sources":["../../../src/tests/StoryComponent/Conversation.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-text-game/ui",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "description": "Themeable React UI component library for text-based games with Tailwind CSS v4, featuring story passages, interactive maps, and customizable game interfaces",
5
5
  "private": false,
6
6
  "type": "module",
@@ -13,6 +13,8 @@
13
13
  "dev": "tsc --watch & tsc-alias --watch & bun run build:css --watch",
14
14
  "build": "tsc && tsc-alias && bun run build:css",
15
15
  "build:css": "mkdir -p dist/styles && bunx @tailwindcss/cli@latest -i src/styles/index.css -o dist/styles/index.css",
16
+ "check-types": "tsc --noEmit",
17
+ "lint": "eslint .",
16
18
  "prepack": "rm -rf dist && bun run build",
17
19
  "test-pack": "npm pack --dry-run && bunx publint"
18
20
  },
@@ -26,6 +28,8 @@
26
28
  "dist"
27
29
  ],
28
30
  "dependencies": {
31
+ "i18next": "^25.6.0",
32
+ "react-i18next": "^16.1.0",
29
33
  "tailwind-merge": "^3.3.1"
30
34
  },
31
35
  "peerDependencies": {
@@ -40,10 +44,11 @@
40
44
  "@types/bun": "^1.2.23",
41
45
  "@types/react": "^19.0.10",
42
46
  "@types/react-dom": "^19.0.5",
47
+ "eslint": "^9.37.0",
43
48
  "tsc-alias": "^1.8.16",
44
49
  "@tailwindcss/postcss": "^4.0.0",
45
50
  "postcss": "^8.4.49",
46
- "@react-text-game/core": "0.2.0"
51
+ "@react-text-game/core": "0.3.0"
47
52
  },
48
53
  "imports": {
49
54
  "#*": "./dist/*"
@@ -53,6 +58,10 @@
53
58
  "types": "./dist/index.d.ts",
54
59
  "import": "./dist/index.js"
55
60
  },
56
- "./styles": "./dist/styles/index.css"
61
+ "./styles": "./dist/styles/index.css",
62
+ "./i18n": {
63
+ "types": "./dist/i18n/index.d.ts",
64
+ "import": "./dist/i18n/index.js"
65
+ }
57
66
  }
58
67
  }