@cosmicdrift/kumiko-renderer-web 0.141.0 → 0.143.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.141.0",
3
+ "version": "0.143.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.141.0",
20
- "@cosmicdrift/kumiko-headless": "0.141.0",
21
- "@cosmicdrift/kumiko-renderer": "0.141.0",
19
+ "@cosmicdrift/kumiko-dispatcher-live": "0.143.0",
20
+ "@cosmicdrift/kumiko-headless": "0.143.0",
21
+ "@cosmicdrift/kumiko-renderer": "0.143.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",
@@ -0,0 +1,45 @@
1
+ // #950 — Input forwardet testId (→ data-testid) + readOnly ans echte <input>,
2
+ // damit App-Tests getByTestId(...) + .readOnly/.disabled assertieren können.
3
+ import { describe, expect, test } from "bun:test";
4
+ import { render, screen } from "@testing-library/react";
5
+ import { defaultPrimitives } from "../index";
6
+
7
+ const { Input } = defaultPrimitives;
8
+ const noop = () => {};
9
+
10
+ describe("DefaultInput testId/readOnly forwarding (#950)", () => {
11
+ test("text: testId → data-testid, readOnly durchgereicht", () => {
12
+ render(
13
+ <Input
14
+ kind="text"
15
+ id="subdomain"
16
+ name="subdomain"
17
+ value="acme"
18
+ onChange={noop}
19
+ testId="url-settings-subdomain"
20
+ readOnly
21
+ />,
22
+ );
23
+ const input = screen.getByTestId("url-settings-subdomain");
24
+ expect(input.tagName).toBe("INPUT");
25
+ expect((input as HTMLInputElement).readOnly).toBe(true);
26
+ });
27
+
28
+ test("readOnly default false (nicht gesetzt = editierbar)", () => {
29
+ render(<Input kind="text" id="x" name="x" value="" onChange={noop} testId="plain" />);
30
+ expect((screen.getByTestId("plain") as HTMLInputElement).readOnly).toBe(false);
31
+ });
32
+
33
+ test("email/password/number: testId erreicht das Element", () => {
34
+ render(
35
+ <>
36
+ <Input kind="email" id="e" name="e" value="" onChange={noop} testId="tid-email" />
37
+ <Input kind="password" id="p" name="p" value="" onChange={noop} testId="tid-pw" />
38
+ <Input kind="number" id="n" name="n" value={1} onChange={noop} testId="tid-num" />
39
+ </>,
40
+ );
41
+ for (const tid of ["tid-email", "tid-pw", "tid-num"]) {
42
+ expect(screen.getByTestId(tid).tagName).toBe("INPUT");
43
+ }
44
+ });
45
+ });
@@ -267,6 +267,8 @@ function DefaultInput(props: InputProps): ReactNode {
267
267
  <UiInput
268
268
  type="text"
269
269
  {...common}
270
+ data-testid={props.testId}
271
+ readOnly={props.readOnly}
270
272
  value={props.value}
271
273
  onChange={(e: ChangeEvent<HTMLInputElement>) => props.onChange(e.target.value)}
272
274
  {...(props.placeholder !== undefined && { placeholder: props.placeholder })}
@@ -278,6 +280,7 @@ function DefaultInput(props: InputProps): ReactNode {
278
280
  <UiInput
279
281
  type="email"
280
282
  {...common}
283
+ data-testid={props.testId}
281
284
  value={props.value}
282
285
  onChange={(e: ChangeEvent<HTMLInputElement>) => props.onChange(e.target.value)}
283
286
  {...(props.placeholder !== undefined && { placeholder: props.placeholder })}
@@ -289,6 +292,7 @@ function DefaultInput(props: InputProps): ReactNode {
289
292
  <UiInput
290
293
  type="password"
291
294
  {...common}
295
+ data-testid={props.testId}
292
296
  value={props.value}
293
297
  onChange={(e: ChangeEvent<HTMLInputElement>) => props.onChange(e.target.value)}
294
298
  autoComplete={props.autoComplete ?? "current-password"}
@@ -299,6 +303,7 @@ function DefaultInput(props: InputProps): ReactNode {
299
303
  <UiInput
300
304
  type="number"
301
305
  {...common}
306
+ data-testid={props.testId}
302
307
  value={props.value}
303
308
  onChange={(e: ChangeEvent<HTMLInputElement>) => {
304
309
  const v = e.target.value;
@@ -63,15 +63,17 @@ export function ResultTable<Row>({
63
63
  rows,
64
64
  rowKey,
65
65
  testId,
66
+ className,
66
67
  }: {
67
68
  readonly columns: readonly ResultColumn<Row>[];
68
69
  readonly rows: readonly Row[];
69
70
  readonly rowKey: (row: Row, index: number) => string;
70
71
  readonly testId?: string;
72
+ readonly className?: string;
71
73
  }): ReactNode {
72
74
  return (
73
75
  <div className="overflow-x-auto">
74
- <table data-testid={testId} className="w-full text-sm">
76
+ <table data-testid={testId} className={cn("w-full text-sm", className)}>
75
77
  <thead>
76
78
  <tr className="border-b text-left text-muted-foreground">
77
79
  {columns.map((col) => (
@@ -120,6 +122,7 @@ export function ComparisonTable<Col>({
120
122
  metrics,
121
123
  metricLabel,
122
124
  testId,
125
+ className,
123
126
  }: {
124
127
  readonly columns: readonly Col[];
125
128
  readonly columnHeader: (col: Col, index: number) => string;
@@ -127,10 +130,11 @@ export function ComparisonTable<Col>({
127
130
  readonly metrics: readonly ComparisonMetric<Col>[];
128
131
  readonly metricLabel: string;
129
132
  readonly testId?: string;
133
+ readonly className?: string;
130
134
  }): ReactNode {
131
135
  return (
132
136
  <div className="overflow-x-auto">
133
- <table data-testid={testId} className="w-full min-w-[24rem] text-sm">
137
+ <table data-testid={testId} className={cn("w-full min-w-[24rem] text-sm", className)}>
134
138
  <thead>
135
139
  <tr className="border-b text-left text-muted-foreground">
136
140
  <th className="py-1.5 font-medium">{metricLabel}</th>