@agent-native/toolkit 0.15.0 → 0.16.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/README.md +26 -0
- package/agent-native.eject.json +35 -1
- package/dist/chat-history.css +3 -1
- package/dist/composer/PromptComposer.d.ts +7 -1
- package/dist/composer/PromptComposer.d.ts.map +1 -1
- package/dist/composer/PromptComposer.js +2 -2
- package/dist/composer/PromptComposer.js.map +1 -1
- package/dist/composer/TiptapComposer.d.ts +19 -1
- package/dist/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/composer/TiptapComposer.js +27 -4
- package/dist/composer/TiptapComposer.js.map +1 -1
- package/dist/data-grid/DataGrid.d.ts +92 -0
- package/dist/data-grid/DataGrid.d.ts.map +1 -0
- package/dist/data-grid/DataGrid.js +315 -0
- package/dist/data-grid/DataGrid.js.map +1 -0
- package/dist/data-grid/DataGrid.spec.d.ts +2 -0
- package/dist/data-grid/DataGrid.spec.d.ts.map +1 -0
- package/dist/data-grid/DataGrid.spec.js +134 -0
- package/dist/data-grid/DataGrid.spec.js.map +1 -0
- package/dist/data-grid/index.d.ts +2 -0
- package/dist/data-grid/index.d.ts.map +1 -0
- package/dist/data-grid/index.js +2 -0
- package/dist/data-grid/index.js.map +1 -0
- package/dist/design-system/default-adapter.d.ts.map +1 -1
- package/dist/design-system/default-adapter.js +4 -1
- package/dist/design-system/default-adapter.js.map +1 -1
- package/dist/design-system/default-adapter.spec.js +12 -0
- package/dist/design-system/default-adapter.spec.js.map +1 -1
- package/dist/design-system/types.d.ts +2 -0
- package/dist/design-system/types.d.ts.map +1 -1
- package/dist/provider.d.ts.map +1 -1
- package/dist/provider.js +5 -2
- package/dist/provider.js.map +1 -1
- package/dist/sharing/SharePrimitives.d.ts +42 -0
- package/dist/sharing/SharePrimitives.d.ts.map +1 -0
- package/dist/sharing/SharePrimitives.js +53 -0
- package/dist/sharing/SharePrimitives.js.map +1 -0
- package/dist/sharing/index.d.ts +1 -0
- package/dist/sharing/index.d.ts.map +1 -1
- package/dist/sharing/index.js +1 -0
- package/dist/sharing/index.js.map +1 -1
- package/package.json +15 -1
- package/src/chat-history.css +3 -1
- package/src/composer/PromptComposer.tsx +13 -0
- package/src/composer/TiptapComposer.tsx +107 -1
- package/src/data-grid/DataGrid.spec.tsx +243 -0
- package/src/data-grid/DataGrid.tsx +754 -0
- package/src/data-grid/index.ts +15 -0
- package/src/design-system/default-adapter.spec.tsx +15 -0
- package/src/design-system/default-adapter.tsx +5 -1
- package/src/design-system/types.ts +2 -0
- package/src/provider.tsx +9 -1
- package/src/sharing/SharePrimitives.tsx +224 -0
- package/src/sharing/index.ts +12 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
// @vitest-environment happy-dom
|
|
2
|
+
|
|
3
|
+
import { act } from "react";
|
|
4
|
+
import { createRoot, type Root } from "react-dom/client";
|
|
5
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
DataGrid,
|
|
9
|
+
dataGridColumnTemplate,
|
|
10
|
+
type DataGridColumn,
|
|
11
|
+
} from "./index.js";
|
|
12
|
+
|
|
13
|
+
interface Row {
|
|
14
|
+
id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
status: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const columns: readonly DataGridColumn<Row>[] = [
|
|
20
|
+
{
|
|
21
|
+
id: "name",
|
|
22
|
+
label: "Name",
|
|
23
|
+
width: 180,
|
|
24
|
+
getValue: (row) => row.name,
|
|
25
|
+
renderCell: ({ value }) => String(value ?? ""),
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: "status",
|
|
29
|
+
label: "Status",
|
|
30
|
+
width: 120,
|
|
31
|
+
getValue: (row) => row.status,
|
|
32
|
+
renderCell: ({ value }) => String(value ?? ""),
|
|
33
|
+
renderEditor: ({ value, onCommit }) => (
|
|
34
|
+
<input
|
|
35
|
+
aria-label="Status editor"
|
|
36
|
+
defaultValue={String(value ?? "")}
|
|
37
|
+
onKeyDown={(event) => {
|
|
38
|
+
if (event.key === "Enter") onCommit(event.currentTarget.value);
|
|
39
|
+
}}
|
|
40
|
+
/>
|
|
41
|
+
),
|
|
42
|
+
},
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
const rows: readonly Row[] = [
|
|
46
|
+
{ id: "row-1", name: "First", status: "Open" },
|
|
47
|
+
{ id: "row-2", name: "Second", status: "Closed" },
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
describe("data-grid", () => {
|
|
51
|
+
it("builds a bounded template and includes the selection column only when requested", () => {
|
|
52
|
+
expect(dataGridColumnTemplate(columns, { name: 40 }, "none")).toBe(
|
|
53
|
+
"96px 120px",
|
|
54
|
+
);
|
|
55
|
+
expect(dataGridColumnTemplate(columns, { name: 220 }, "multiple")).toBe(
|
|
56
|
+
"40px 220px 120px",
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
describe("DataGrid", () => {
|
|
61
|
+
let container: HTMLDivElement;
|
|
62
|
+
let root: Root;
|
|
63
|
+
|
|
64
|
+
beforeEach(() => {
|
|
65
|
+
vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);
|
|
66
|
+
container = document.createElement("div");
|
|
67
|
+
document.body.appendChild(container);
|
|
68
|
+
root = createRoot(container);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
afterEach(() => {
|
|
72
|
+
act(() => root.unmount());
|
|
73
|
+
container.remove();
|
|
74
|
+
vi.restoreAllMocks();
|
|
75
|
+
vi.unstubAllGlobals();
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("moves the active cell with arrows and commits an editor value", () => {
|
|
79
|
+
const onActiveCellChange = vi.fn();
|
|
80
|
+
const onCellCommit = vi.fn();
|
|
81
|
+
|
|
82
|
+
act(() => {
|
|
83
|
+
root.render(
|
|
84
|
+
<DataGrid
|
|
85
|
+
rows={rows}
|
|
86
|
+
columns={columns}
|
|
87
|
+
getRowId={(row) => row.id}
|
|
88
|
+
onActiveCellChange={onActiveCellChange}
|
|
89
|
+
onCellCommit={onCellCommit}
|
|
90
|
+
/>,
|
|
91
|
+
);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const firstNameCell = container.querySelector<HTMLElement>(
|
|
95
|
+
'[data-data-grid-row-id="row-1"][data-data-grid-column-id="name"]',
|
|
96
|
+
);
|
|
97
|
+
expect(firstNameCell?.getAttribute("tabindex")).toBe("0");
|
|
98
|
+
|
|
99
|
+
act(() => {
|
|
100
|
+
firstNameCell?.dispatchEvent(
|
|
101
|
+
new KeyboardEvent("keydown", { bubbles: true, key: "ArrowRight" }),
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
expect(onActiveCellChange).toHaveBeenCalledWith({
|
|
105
|
+
rowId: "row-1",
|
|
106
|
+
columnId: "status",
|
|
107
|
+
editing: false,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const statusCell = container.querySelector<HTMLElement>(
|
|
111
|
+
'[data-data-grid-row-id="row-1"][data-data-grid-column-id="status"]',
|
|
112
|
+
);
|
|
113
|
+
act(() => {
|
|
114
|
+
statusCell?.dispatchEvent(
|
|
115
|
+
new KeyboardEvent("keydown", { bubbles: true, key: "Enter" }),
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
expect(
|
|
119
|
+
container.querySelector('input[aria-label="Status editor"]'),
|
|
120
|
+
).not.toBeNull();
|
|
121
|
+
|
|
122
|
+
const input = container.querySelector<HTMLInputElement>(
|
|
123
|
+
'input[aria-label="Status editor"]',
|
|
124
|
+
);
|
|
125
|
+
expect(input).not.toBeNull();
|
|
126
|
+
if (input) {
|
|
127
|
+
input.value = "In progress";
|
|
128
|
+
act(() => {
|
|
129
|
+
input.dispatchEvent(
|
|
130
|
+
new KeyboardEvent("keydown", { bubbles: true, key: "Enter" }),
|
|
131
|
+
);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
expect(onCellCommit).toHaveBeenCalledWith({
|
|
135
|
+
row: rows[0],
|
|
136
|
+
rowIndex: 0,
|
|
137
|
+
column: columns[1],
|
|
138
|
+
previousValue: "Open",
|
|
139
|
+
value: "In progress",
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it("supports controlled multi-row selection", () => {
|
|
144
|
+
const onSelectedRowIdsChange = vi.fn();
|
|
145
|
+
|
|
146
|
+
act(() => {
|
|
147
|
+
root.render(
|
|
148
|
+
<DataGrid
|
|
149
|
+
rows={rows}
|
|
150
|
+
columns={columns}
|
|
151
|
+
getRowId={(row) => row.id}
|
|
152
|
+
selection="multiple"
|
|
153
|
+
onSelectedRowIdsChange={onSelectedRowIdsChange}
|
|
154
|
+
/>,
|
|
155
|
+
);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const rowCheckbox = container.querySelector<HTMLInputElement>(
|
|
159
|
+
'[aria-label="Select row row-1"]',
|
|
160
|
+
);
|
|
161
|
+
act(() => rowCheckbox?.click());
|
|
162
|
+
expect(onSelectedRowIdsChange).toHaveBeenCalledTimes(1);
|
|
163
|
+
expect(Array.from(onSelectedRowIdsChange.mock.calls[0][0])).toEqual([
|
|
164
|
+
"row-1",
|
|
165
|
+
]);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it("reports pointer-based column resizing through the app callback", () => {
|
|
169
|
+
const onColumnWidthsChange = vi.fn();
|
|
170
|
+
|
|
171
|
+
act(() => {
|
|
172
|
+
root.render(
|
|
173
|
+
<DataGrid
|
|
174
|
+
rows={rows}
|
|
175
|
+
columns={columns}
|
|
176
|
+
getRowId={(row) => row.id}
|
|
177
|
+
onColumnWidthsChange={onColumnWidthsChange}
|
|
178
|
+
/>,
|
|
179
|
+
);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
const resizeHandle = container.querySelector<HTMLButtonElement>(
|
|
183
|
+
'[aria-label="Resize name column"]',
|
|
184
|
+
);
|
|
185
|
+
expect(resizeHandle).not.toBeNull();
|
|
186
|
+
|
|
187
|
+
act(() => {
|
|
188
|
+
resizeHandle?.dispatchEvent(
|
|
189
|
+
new PointerEvent("pointerdown", {
|
|
190
|
+
bubbles: true,
|
|
191
|
+
button: 0,
|
|
192
|
+
clientX: 100,
|
|
193
|
+
}),
|
|
194
|
+
);
|
|
195
|
+
document.dispatchEvent(
|
|
196
|
+
new PointerEvent("pointermove", {
|
|
197
|
+
bubbles: true,
|
|
198
|
+
clientX: 180,
|
|
199
|
+
}),
|
|
200
|
+
);
|
|
201
|
+
document.dispatchEvent(
|
|
202
|
+
new PointerEvent("pointerup", { bubbles: true, clientX: 180 }),
|
|
203
|
+
);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
expect(onColumnWidthsChange).toHaveBeenLastCalledWith({ name: 260 });
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it("lets an app own the outer header and body while sharing the grid template", () => {
|
|
210
|
+
const renderHeader = vi.fn(({ gridTemplateColumns }) => (
|
|
211
|
+
<div data-testid="custom-header" style={{ gridTemplateColumns }} />
|
|
212
|
+
));
|
|
213
|
+
const renderBody = vi.fn(({ gridTemplateColumns }) => (
|
|
214
|
+
<div data-testid="custom-body" style={{ gridTemplateColumns }} />
|
|
215
|
+
));
|
|
216
|
+
|
|
217
|
+
act(() => {
|
|
218
|
+
root.render(
|
|
219
|
+
<DataGrid
|
|
220
|
+
rows={rows}
|
|
221
|
+
columns={columns}
|
|
222
|
+
getRowId={(row) => row.id}
|
|
223
|
+
renderHeader={renderHeader}
|
|
224
|
+
renderBody={renderBody}
|
|
225
|
+
/>,
|
|
226
|
+
);
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
expect(
|
|
230
|
+
container.querySelector("[data-testid=custom-header]"),
|
|
231
|
+
).not.toBeNull();
|
|
232
|
+
expect(
|
|
233
|
+
container.querySelector("[data-testid=custom-body]"),
|
|
234
|
+
).not.toBeNull();
|
|
235
|
+
expect(renderHeader).toHaveBeenCalledWith(
|
|
236
|
+
expect.objectContaining({ gridTemplateColumns: "180px 120px" }),
|
|
237
|
+
);
|
|
238
|
+
expect(renderBody).toHaveBeenCalledWith(
|
|
239
|
+
expect.objectContaining({ rows, columns }),
|
|
240
|
+
);
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
});
|