@marimo-team/islands 0.25.3-dev173 → 0.25.3-dev176
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/dist/{ErrorBoundary-wT3f3iJ1.js → ErrorBoundary-D66f-xAE.js} +1 -1
- package/dist/{any-language-editor-B92WMzoC.js → any-language-editor-BVFHDDQ3.js} +2 -2
- package/dist/{chat-ui-CuORr6fL.js → chat-ui-X-cWrL9u.js} +1222 -1222
- package/dist/{code-visibility-ZReaeMaF.js → code-visibility-CVVeTAwi.js} +2 -2
- package/dist/{common-DCevHg1m.js → common-DNlm9Cdj.js} +1074 -1078
- package/dist/{data-grid-overlay-editor-CTC-bJus.js → data-grid-overlay-editor-BArE3_zi.js} +1 -1
- package/dist/{dist-F8Ep36rk.js → dist-B1M0bGO3.js} +1 -1
- package/dist/{dist-D6d86eNJ.js → dist-BA13RJj5.js} +1 -1
- package/dist/{dist-Bvs24R_E.js → dist-BJtmSgcE.js} +48 -48
- package/dist/{dist-CN_BeG2I.js → dist-Ba2VIn1K.js} +53 -53
- package/dist/{dist-PXYI_yuP.js → dist-Bj4bmwUm.js} +12 -12
- package/dist/{dist-DoE4XJBC.js → dist-BmS-ZGjl.js} +8626 -8626
- package/dist/{dist-BorMD-uX.js → dist-Bzogh7CW.js} +87 -87
- package/dist/{dist-CN8zI-XC.js → dist-CThPVKaP.js} +1385 -1382
- package/dist/{dist-DiDibOYr.js → dist-CTi5FTiV.js} +87 -87
- package/dist/{dist-diIx5qJW.js → dist-Ck_C32ye.js} +2 -2
- package/dist/{dist-BLfKmR-l.js → dist-D1fnFp1J.js} +1 -1
- package/dist/{dist-OR1OnN-y.js → dist-D3x9__Fu.js} +46 -46
- package/dist/{dist-BMQf5zIS.js → dist-D7mrh5sO.js} +36 -36
- package/dist/{dist-CSJ0MDRw.js → dist-D9Q3xjiP.js} +1 -1
- package/dist/{dist-BuaRHxOc.js → dist-DP60Ubh8.js} +2 -2
- package/dist/{dist-CSbh1PNP.js → dist-DTv9KkpW.js} +12 -12
- package/dist/{dist-D-wwqlzJ.js → dist-DVVwOfrD.js} +109 -109
- package/dist/{dist-C8fAKSH1.js → dist-DYXM73-k.js} +36 -36
- package/dist/{dist-DBtSl3sf.js → dist-DjeybPOb.js} +1 -1
- package/dist/{dist-CrSP_H1M.js → dist-DtGn9N4h.js} +197 -197
- package/dist/{dist-CLdpGQVr.js → dist-KN80qWCP.js} +2 -2
- package/dist/{dist-Cg7gzw-a.js → dist-O0qFpEJh.js} +56 -56
- package/dist/{dist-CkTTIdBe.js → dist-OUle2RT7.js} +207 -207
- package/dist/{dist-BK4Oj99o.js → dist-T5rh6JvL.js} +1 -1
- package/dist/{error-entries-CmWMEsY_.js → error-entries-mpoD5t79.js} +4939 -4983
- package/dist/{esm-D2gTsXEV.js → esm-Bbw_Njjx.js} +575 -575
- package/dist/{esm-AMFssoNp.js → esm-mDQNEFe_.js} +354 -354
- package/dist/{feedback-button-DwXkmewo.js → feedback-button-CyvqdxXN.js} +21 -21
- package/dist/{glide-data-editor-BlmcP-lw.js → glide-data-editor-BxvYRMC3.js} +3 -3
- package/dist/{globals-BdRitZ4p.js → globals-BJla9q8e.js} +1 -1
- package/dist/{html-to-image-bpiQh7ND.js → html-to-image-BoZthB4P.js} +454 -445
- package/dist/main.js +3587 -3587
- package/dist/{number-overlay-editor-DQG-hFHT.js → number-overlay-editor-BWg7xiRF.js} +1 -1
- package/dist/{process-output-BzloOI7F.js → process-output-DLS4Mqg_.js} +2 -2
- package/dist/{reveal-component-D3r3vSTK.js → reveal-component-feAltY24.js} +3 -3
- package/package.json +1 -1
- package/src/__mocks__/document.tsx +54 -0
- package/src/__mocks__/notebook.ts +2 -1
- package/src/__mocks__/requests.ts +0 -2
- package/src/components/chat/chat-panel.tsx +3 -3
- package/src/components/datasources/__tests__/column-preview.test.tsx +6 -8
- package/src/components/datasources/column-preview.tsx +4 -8
- package/src/components/datasources/datasources.tsx +4 -3
- package/src/components/dependency-graph/minimap-content.tsx +2 -6
- package/src/components/dependency-graph/panels.tsx +2 -1
- package/src/components/editor/__tests__/Output.test.tsx +50 -32
- package/src/components/editor/__tests__/data-attributes.test.tsx +22 -11
- package/src/components/editor/__tests__/output-persistence.test.tsx +6 -1
- package/src/components/editor/actions/__tests__/name-cell-input.test.tsx +69 -0
- package/src/components/editor/actions/name-cell-input.tsx +4 -3
- package/src/components/editor/actions/useCellActionButton.tsx +20 -26
- package/src/components/editor/actions/useNotebookActions.tsx +13 -18
- package/src/components/editor/actions/useSetCodeVisibility.ts +10 -11
- package/src/components/editor/actions/useSetOutputsExpanded.ts +13 -18
- package/src/components/editor/cell/CreateCellButton.tsx +5 -9
- package/src/components/editor/cell/__tests__/StagedAICell.test.tsx +3 -1
- package/src/components/editor/cell/code/cell-editor.tsx +13 -20
- package/src/components/editor/cell/useAddCell.ts +4 -8
- package/src/components/editor/cell/useDeleteCell.tsx +10 -36
- package/src/components/editor/cell/useRunCells.ts +2 -5
- package/src/components/editor/cell/useSplitCell.tsx +2 -1
- package/src/components/editor/chrome/panels/logs-panel.tsx +2 -1
- package/src/components/editor/chrome/panels/snippets-panel.tsx +5 -11
- package/src/components/editor/chrome/wrapper/__tests__/pending-ai-cells.test.tsx +3 -1
- package/src/components/editor/columns/sortable-column.tsx +1 -1
- package/src/components/editor/connections/components.tsx +4 -9
- package/src/components/editor/controls/Controls.tsx +1 -1
- package/src/components/editor/controls/__tests__/notebook-menu-dropdown.test.tsx +9 -3
- package/src/components/editor/documentation.css +34 -11
- package/src/components/editor/errors/auto-fix.tsx +4 -8
- package/src/components/editor/file-tree/file-explorer.tsx +3 -7
- package/src/components/editor/links/__tests__/cell-link.test.tsx +3 -1
- package/src/components/editor/links/cell-link.tsx +2 -1
- package/src/components/editor/navigation/__tests__/clipboard.test.ts +60 -38
- package/src/components/editor/navigation/__tests__/navigation.test.ts +73 -64
- package/src/components/editor/navigation/clipboard.ts +12 -11
- package/src/components/editor/navigation/multi-cell-action-toolbar.tsx +11 -20
- package/src/components/editor/navigation/navigation.ts +20 -28
- package/src/components/editor/notebook-cell.tsx +7 -10
- package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +125 -69
- package/src/components/editor/renderers/cell-array.tsx +10 -17
- package/src/components/markdown/markdown-renderer.tsx +4 -8
- package/src/components/pages/edit-page.tsx +32 -17
- package/src/components/scratchpad/scratchpad.test.tsx +3 -1
- package/src/components/scratchpad/scratchpad.tsx +4 -7
- package/src/components/slides/__tests__/minimap-actions.test.tsx +9 -25
- package/src/components/slides/minimap.tsx +7 -3
- package/src/components/slides/slide-cell-view.tsx +3 -3
- package/src/components/sort/SortableCellsProvider.tsx +2 -1
- package/src/core/ai/__tests__/staged-cells.test.ts +18 -20
- package/src/core/ai/staged-cells.ts +8 -16
- package/src/core/ai/tools/__tests__/edit-notebook-tool.test.ts +2 -2
- package/src/core/ai/tools/__tests__/run-cells-tool.test.ts +2 -2
- package/src/core/ai/tools/base.ts +2 -2
- package/src/core/ai/tools/edit-notebook-tool.ts +13 -21
- package/src/core/cells/__tests__/actions.test.ts +474 -34
- package/src/core/cells/__tests__/add-missing-import.test.ts +7 -8
- package/src/core/cells/__tests__/cells.test.ts +171 -813
- package/src/core/cells/__tests__/document.test.ts +5 -35
- package/src/core/cells/__tests__/notebook-outline.test.ts +7 -1
- package/src/core/cells/__tests__/outputs.test.tsx +71 -53
- package/src/core/cells/actions.ts +391 -3
- package/src/core/cells/add-missing-import.ts +46 -42
- package/src/core/cells/cells.ts +38 -413
- package/src/core/cells/document.ts +7 -4
- package/src/core/cells/outputs.ts +12 -28
- package/src/core/codemirror/cells/extensions.ts +6 -6
- package/src/core/codemirror/cells/state.ts +1 -1
- package/src/core/codemirror/keymaps/vim.ts +2 -2
- package/src/core/edit-app.tsx +19 -27
- package/src/core/islands/bridge.ts +0 -2
- package/src/core/kernel/handlers.ts +3 -3
- package/src/core/network/__tests__/requests-lazy.test.ts +1 -3
- package/src/core/network/requests-lazy.ts +0 -2
- package/src/core/network/requests-network.ts +0 -16
- package/src/core/network/requests-static.ts +0 -2
- package/src/core/network/requests-toasting.tsx +0 -2
- package/src/core/network/types.ts +0 -7
- package/src/core/notebook/document/__tests__/codemirror.test.ts +5 -0
- package/src/core/notebook/document/__tests__/draft.test.ts +41 -0
- package/src/core/notebook/document/__tests__/state.test.ts +21 -0
- package/src/core/notebook/document/draft.ts +35 -5
- package/src/core/notebook/document/index.ts +1 -0
- package/src/core/notebook/document/state.ts +6 -2
- package/src/core/session/useNotebookSession.tsx +6 -2
- package/src/core/wasm/bridge.ts +0 -16
- package/src/css/globals.css +56 -22
- package/src/stories/runtime-story.tsx +22 -15
|
@@ -3,15 +3,37 @@
|
|
|
3
3
|
|
|
4
4
|
import type { EditorView } from "@codemirror/view";
|
|
5
5
|
import { act, renderHook } from "@testing-library/react";
|
|
6
|
-
import { Provider } from "jotai";
|
|
7
6
|
import React, { createRef } from "react";
|
|
8
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
afterAll,
|
|
9
|
+
afterEach,
|
|
10
|
+
beforeEach,
|
|
11
|
+
describe,
|
|
12
|
+
expect,
|
|
13
|
+
it,
|
|
14
|
+
vi,
|
|
15
|
+
} from "vitest";
|
|
9
16
|
import { Mocks } from "@/__mocks__/common";
|
|
17
|
+
|
|
18
|
+
const { mockCreateCell, mockMoveToNextCell } = vi.hoisted(() => ({
|
|
19
|
+
mockCreateCell: vi.fn(),
|
|
20
|
+
mockMoveToNextCell: vi.fn(),
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
import { DocumentWrapper, mockDocumentModel } from "@/__mocks__/document";
|
|
10
24
|
import { MockNotebook } from "@/__mocks__/notebook";
|
|
11
25
|
import { MockRequestClient } from "@/__mocks__/requests";
|
|
12
26
|
import { aiCompletionCellAtom } from "@/core/ai/state";
|
|
13
|
-
import type { CellActions } from "@/core/cells/
|
|
27
|
+
import type { CellActions } from "@/core/cells/actions";
|
|
14
28
|
import { notebookAtom } from "@/core/cells/cells";
|
|
29
|
+
import type { CellId } from "@/core/cells/ids";
|
|
30
|
+
import type { DocumentModel } from "@/core/notebook/document";
|
|
31
|
+
import {
|
|
32
|
+
cell,
|
|
33
|
+
CONFIG,
|
|
34
|
+
document as documentOf,
|
|
35
|
+
withCells,
|
|
36
|
+
} from "@/core/notebook/document/__tests__/fixtures";
|
|
15
37
|
import { LanguageAdapters } from "@/core/codemirror/language/LanguageAdapters";
|
|
16
38
|
import { signatureHintField } from "@/core/codemirror/completion/signature-hint";
|
|
17
39
|
import {
|
|
@@ -30,9 +52,11 @@ import {
|
|
|
30
52
|
} from "../navigation";
|
|
31
53
|
|
|
32
54
|
// Mock only the essential dependencies that we need to control
|
|
55
|
+
vi.mock("@/core/cells/actions", () => ({
|
|
56
|
+
useCellActions: vi.fn(),
|
|
57
|
+
}));
|
|
33
58
|
vi.mock("@/core/cells/cells", async (importOriginal) => ({
|
|
34
59
|
...(await importOriginal()),
|
|
35
|
-
useCellActions: vi.fn(),
|
|
36
60
|
}));
|
|
37
61
|
|
|
38
62
|
vi.mock("@/core/cells/focus", async (importOriginal) => ({
|
|
@@ -80,7 +104,7 @@ vi.mock("@codemirror/autocomplete", () => ({
|
|
|
80
104
|
|
|
81
105
|
// Get mocked functions
|
|
82
106
|
const mockUseCellActions = vi.mocked(
|
|
83
|
-
await import("@/core/cells/
|
|
107
|
+
await import("@/core/cells/actions"),
|
|
84
108
|
).useCellActions;
|
|
85
109
|
|
|
86
110
|
const mockUseSaveNotebook = vi.mocked(
|
|
@@ -93,6 +117,8 @@ const mockUseCellClipboard = vi.mocked(
|
|
|
93
117
|
await import("../clipboard"),
|
|
94
118
|
).useCellClipboard;
|
|
95
119
|
|
|
120
|
+
afterEach(() => stopModel());
|
|
121
|
+
|
|
96
122
|
afterAll(() => {
|
|
97
123
|
vi.resetAllMocks();
|
|
98
124
|
});
|
|
@@ -107,11 +133,17 @@ import {
|
|
|
107
133
|
useIsCellSelected,
|
|
108
134
|
} from "../selection";
|
|
109
135
|
|
|
136
|
+
// The document the hooks edit, with cellId3's code hidden
|
|
137
|
+
let model: DocumentModel;
|
|
138
|
+
let stopModel = () => {};
|
|
139
|
+
const hideCodeOf = (id: CellId) =>
|
|
140
|
+
store.get(model.documentAtom)?.cells.get(id)?.config.hide_code;
|
|
141
|
+
|
|
110
142
|
// Shared render helper
|
|
111
143
|
const renderWithProvider = <T>(hook: () => T) => {
|
|
112
144
|
return renderHook(hook, {
|
|
113
145
|
wrapper: ({ children }) =>
|
|
114
|
-
React.createElement(
|
|
146
|
+
React.createElement(DocumentWrapper, { store, model }, children),
|
|
115
147
|
});
|
|
116
148
|
};
|
|
117
149
|
|
|
@@ -125,17 +157,16 @@ const mockCutCell = vi.fn().mockResolvedValue(undefined);
|
|
|
125
157
|
const mockPasteCell = vi.fn();
|
|
126
158
|
|
|
127
159
|
const mockCellActions = MockNotebook.cellActions({
|
|
160
|
+
createCell: mockCreateCell,
|
|
161
|
+
moveToNextCell: mockMoveToNextCell,
|
|
128
162
|
focusCell: vi.fn(),
|
|
129
|
-
moveToNextCell: vi.fn(),
|
|
130
163
|
focusTopCell: vi.fn(),
|
|
131
164
|
focusBottomCell: vi.fn(),
|
|
132
|
-
createNewCell: vi.fn(),
|
|
133
165
|
moveCell: vi.fn(),
|
|
134
166
|
sendToTop: vi.fn(),
|
|
135
167
|
sendToBottom: vi.fn(),
|
|
136
|
-
updateCellConfig: vi.fn(),
|
|
137
168
|
markTouched: vi.fn(),
|
|
138
|
-
|
|
169
|
+
deleteCells: vi.fn(),
|
|
139
170
|
undoDeleteCell: vi.fn(),
|
|
140
171
|
});
|
|
141
172
|
|
|
@@ -207,6 +238,23 @@ describe("useCellNavigationProps", () => {
|
|
|
207
238
|
},
|
|
208
239
|
});
|
|
209
240
|
store.set(notebookAtom, notebookState);
|
|
241
|
+
stopModel();
|
|
242
|
+
({ model, stop: stopModel } = mockDocumentModel(
|
|
243
|
+
store,
|
|
244
|
+
withCells(
|
|
245
|
+
documentOf(),
|
|
246
|
+
{
|
|
247
|
+
c1: null,
|
|
248
|
+
c2: null,
|
|
249
|
+
[cellId1]: cell(cellId1, ""),
|
|
250
|
+
[cellId2]: cell(cellId2, ""),
|
|
251
|
+
[cellId3]: cell(cellId3, "", {
|
|
252
|
+
config: { ...CONFIG, hide_code: true },
|
|
253
|
+
}),
|
|
254
|
+
},
|
|
255
|
+
[cellId1, cellId2, cellId3],
|
|
256
|
+
),
|
|
257
|
+
));
|
|
210
258
|
|
|
211
259
|
// Clear AI completion state
|
|
212
260
|
store.set(aiCompletionCellAtom, null);
|
|
@@ -367,7 +415,7 @@ describe("useCellNavigationProps", () => {
|
|
|
367
415
|
});
|
|
368
416
|
|
|
369
417
|
expect(mockRunCell).toHaveBeenCalled();
|
|
370
|
-
expect(
|
|
418
|
+
expect(mockMoveToNextCell).toHaveBeenCalledWith({
|
|
371
419
|
cellId: mockCellId,
|
|
372
420
|
before: false,
|
|
373
421
|
});
|
|
@@ -399,11 +447,7 @@ describe("useCellNavigationProps", () => {
|
|
|
399
447
|
result.current.onKeyDown?.(mockEvent);
|
|
400
448
|
});
|
|
401
449
|
|
|
402
|
-
expect(
|
|
403
|
-
cellId: mockCellId,
|
|
404
|
-
before: true,
|
|
405
|
-
autoFocus: true,
|
|
406
|
-
});
|
|
450
|
+
expect(mockCreateCell).toHaveBeenCalledWith({ before: mockCellId });
|
|
407
451
|
});
|
|
408
452
|
|
|
409
453
|
it("should create cell after when 'b' key is pressed", () => {
|
|
@@ -417,11 +461,7 @@ describe("useCellNavigationProps", () => {
|
|
|
417
461
|
result.current.onKeyDown?.(mockEvent);
|
|
418
462
|
});
|
|
419
463
|
|
|
420
|
-
expect(
|
|
421
|
-
cellId: mockCellId,
|
|
422
|
-
before: false,
|
|
423
|
-
autoFocus: true,
|
|
424
|
-
});
|
|
464
|
+
expect(mockCreateCell).toHaveBeenCalledWith({ after: mockCellId });
|
|
425
465
|
});
|
|
426
466
|
|
|
427
467
|
it("should add an import before and a SQL cell after when 'q' is pressed", () => {
|
|
@@ -435,18 +475,15 @@ describe("useCellNavigationProps", () => {
|
|
|
435
475
|
result.current.onKeyDown?.(Mocks.keyboardEvent({ key: "q" }));
|
|
436
476
|
});
|
|
437
477
|
|
|
438
|
-
expect(
|
|
478
|
+
expect(mockCreateCell).toHaveBeenNthCalledWith(
|
|
439
479
|
1,
|
|
440
480
|
expect.objectContaining({
|
|
441
|
-
|
|
442
|
-
before: true,
|
|
481
|
+
before: mockCellId,
|
|
443
482
|
code: "import marimo as mo",
|
|
444
483
|
}),
|
|
445
484
|
);
|
|
446
|
-
expect(
|
|
447
|
-
|
|
448
|
-
before: false,
|
|
449
|
-
autoFocus: true,
|
|
485
|
+
expect(mockCreateCell).toHaveBeenNthCalledWith(2, {
|
|
486
|
+
after: mockCellId,
|
|
450
487
|
code: LanguageAdapters.sql.defaultCode,
|
|
451
488
|
});
|
|
452
489
|
});
|
|
@@ -1034,7 +1071,7 @@ describe("useCellNavigationProps", () => {
|
|
|
1034
1071
|
|
|
1035
1072
|
expect(mockRunCell).toHaveBeenCalledWith([cellId1, cellId2]);
|
|
1036
1073
|
// Should move to next cell after the last selected cell
|
|
1037
|
-
expect(
|
|
1074
|
+
expect(mockMoveToNextCell).toHaveBeenCalledWith({
|
|
1038
1075
|
cellId: cellId2,
|
|
1039
1076
|
before: false,
|
|
1040
1077
|
});
|
|
@@ -1066,7 +1103,7 @@ describe("useCellNavigationProps", () => {
|
|
|
1066
1103
|
|
|
1067
1104
|
expect(mockRunCell).toHaveBeenCalledWith([cellId2, cellId3]);
|
|
1068
1105
|
// Should move to previous cell before the first selected cell
|
|
1069
|
-
expect(
|
|
1106
|
+
expect(mockMoveToNextCell).toHaveBeenCalledWith({
|
|
1070
1107
|
cellId: cellId2,
|
|
1071
1108
|
before: true,
|
|
1072
1109
|
});
|
|
@@ -1167,15 +1204,7 @@ describe("useCellNavigationProps", () => {
|
|
|
1167
1204
|
result.current.onKeyDown?.(mockEvent);
|
|
1168
1205
|
});
|
|
1169
1206
|
|
|
1170
|
-
expect(
|
|
1171
|
-
configs: {
|
|
1172
|
-
[cellId1]: { hide_code: true },
|
|
1173
|
-
},
|
|
1174
|
-
});
|
|
1175
|
-
expect(mockCellActions.updateCellConfig).toHaveBeenCalledWith({
|
|
1176
|
-
cellId: cellId1,
|
|
1177
|
-
config: { hide_code: true },
|
|
1178
|
-
});
|
|
1207
|
+
expect(hideCodeOf(cellId1)).toBe(true);
|
|
1179
1208
|
expect(mockEvent.preventDefault).toHaveBeenCalled();
|
|
1180
1209
|
});
|
|
1181
1210
|
|
|
@@ -1190,15 +1219,7 @@ describe("useCellNavigationProps", () => {
|
|
|
1190
1219
|
result.current.onKeyDown?.(mockEvent);
|
|
1191
1220
|
});
|
|
1192
1221
|
|
|
1193
|
-
expect(
|
|
1194
|
-
configs: {
|
|
1195
|
-
[cellId3]: { hide_code: false },
|
|
1196
|
-
},
|
|
1197
|
-
});
|
|
1198
|
-
expect(mockCellActions.updateCellConfig).toHaveBeenCalledWith({
|
|
1199
|
-
cellId: cellId3,
|
|
1200
|
-
config: { hide_code: false },
|
|
1201
|
-
});
|
|
1222
|
+
expect(hideCodeOf(cellId3)).toBe(false);
|
|
1202
1223
|
});
|
|
1203
1224
|
|
|
1204
1225
|
it("should toggle hide code for multiple selected cells", () => {
|
|
@@ -1220,20 +1241,8 @@ describe("useCellNavigationProps", () => {
|
|
|
1220
1241
|
result.current.onKeyDown?.(mockEvent);
|
|
1221
1242
|
});
|
|
1222
1243
|
|
|
1223
|
-
expect(
|
|
1224
|
-
|
|
1225
|
-
[cellId1]: { hide_code: true },
|
|
1226
|
-
[cellId2]: { hide_code: true },
|
|
1227
|
-
},
|
|
1228
|
-
});
|
|
1229
|
-
expect(mockCellActions.updateCellConfig).toHaveBeenCalledWith({
|
|
1230
|
-
cellId: cellId1,
|
|
1231
|
-
config: { hide_code: true },
|
|
1232
|
-
});
|
|
1233
|
-
expect(mockCellActions.updateCellConfig).toHaveBeenCalledWith({
|
|
1234
|
-
cellId: cellId2,
|
|
1235
|
-
config: { hide_code: true },
|
|
1236
|
-
});
|
|
1244
|
+
expect(hideCodeOf(cellId1)).toBe(true);
|
|
1245
|
+
expect(hideCodeOf(cellId2)).toBe(true);
|
|
1237
1246
|
});
|
|
1238
1247
|
});
|
|
1239
1248
|
|
|
@@ -1701,7 +1710,7 @@ describe("useCellNavigationProps", () => {
|
|
|
1701
1710
|
result.current.onKeyDown?.(mockEvent);
|
|
1702
1711
|
});
|
|
1703
1712
|
|
|
1704
|
-
expect(
|
|
1713
|
+
expect(mockCreateCell).not.toHaveBeenCalled();
|
|
1705
1714
|
expect(mockEvent.preventDefault).not.toHaveBeenCalled();
|
|
1706
1715
|
});
|
|
1707
1716
|
|
|
@@ -1716,7 +1725,7 @@ describe("useCellNavigationProps", () => {
|
|
|
1716
1725
|
result.current.onKeyDown?.(mockEvent);
|
|
1717
1726
|
});
|
|
1718
1727
|
|
|
1719
|
-
expect(
|
|
1728
|
+
expect(mockCreateCell).not.toHaveBeenCalled();
|
|
1720
1729
|
expect(mockEvent.preventDefault).not.toHaveBeenCalled();
|
|
1721
1730
|
});
|
|
1722
1731
|
});
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
import useEvent from "react-use-event-hook";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import { toast } from "@/components/ui/use-toast";
|
|
6
|
-
import { getNotebook
|
|
6
|
+
import { getNotebook } from "@/core/cells/cells";
|
|
7
|
+
import { useCellActions } from "@/core/cells/actions";
|
|
7
8
|
import type { CellId } from "@/core/cells/ids";
|
|
8
9
|
import {
|
|
9
10
|
usePendingCutActions,
|
|
@@ -73,6 +74,7 @@ async function writeCellsToClipboard(
|
|
|
73
74
|
|
|
74
75
|
export function useCellClipboard() {
|
|
75
76
|
const actions = useCellActions();
|
|
77
|
+
const { createCell } = actions;
|
|
76
78
|
const pendingCutActions = usePendingCutActions();
|
|
77
79
|
const pendingCutState = usePendingCutState();
|
|
78
80
|
|
|
@@ -178,14 +180,15 @@ export function useCellClipboard() {
|
|
|
178
180
|
const currentCellId = cellId;
|
|
179
181
|
const reversedCells = clipboardData.cells.toReversed();
|
|
180
182
|
for (const cell of reversedCells) {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
183
|
+
// The pasted cell joins the column it is pasted into.
|
|
184
|
+
const { column: _column, ...config } = cell.config ?? {};
|
|
185
|
+
createCell({
|
|
186
|
+
...(before
|
|
187
|
+
? { before: currentCellId }
|
|
188
|
+
: { after: currentCellId }),
|
|
184
189
|
code: cell.code,
|
|
185
190
|
name: cell.name,
|
|
186
|
-
config
|
|
187
|
-
hideCode: cell.config?.hide_code,
|
|
188
|
-
autoFocus: true,
|
|
191
|
+
config,
|
|
189
192
|
});
|
|
190
193
|
}
|
|
191
194
|
|
|
@@ -199,11 +202,9 @@ export function useCellClipboard() {
|
|
|
199
202
|
// Fallback to plain text
|
|
200
203
|
const text = await navigator.clipboard.readText();
|
|
201
204
|
if (text.trim()) {
|
|
202
|
-
|
|
203
|
-
cellId,
|
|
204
|
-
before,
|
|
205
|
+
createCell({
|
|
206
|
+
...(before ? { before: cellId } : { after: cellId }),
|
|
205
207
|
code: text,
|
|
206
|
-
autoFocus: true,
|
|
207
208
|
});
|
|
208
209
|
} else {
|
|
209
210
|
toastNothingToPaste();
|
|
@@ -34,14 +34,14 @@ import {
|
|
|
34
34
|
getCellEditorView,
|
|
35
35
|
hasOnlyOneCellAtom,
|
|
36
36
|
notebookAtom,
|
|
37
|
-
useCellActions,
|
|
38
37
|
} from "@/core/cells/cells";
|
|
38
|
+
import { useCellActions } from "@/core/cells/actions";
|
|
39
|
+
import { useNotebookDocumentEdit } from "@/core/notebook/document";
|
|
39
40
|
import type { CellId } from "@/core/cells/ids";
|
|
40
41
|
import { usePendingDeleteService } from "@/core/cells/pending-delete-service";
|
|
41
42
|
import { formatEditorViews } from "@/core/codemirror/format";
|
|
42
43
|
import { userConfigAtom } from "@/core/config/config";
|
|
43
44
|
import type { HotkeyAction } from "@/core/hotkeys/hotkeys";
|
|
44
|
-
import { useRequestClient } from "@/core/network/requests";
|
|
45
45
|
import type { CellConfig } from "@/core/network/types";
|
|
46
46
|
import { store } from "@/core/state/jotai";
|
|
47
47
|
import { useEventListener } from "@/hooks/useEventListener";
|
|
@@ -112,20 +112,15 @@ const CellStateDropdown: React.FC<{
|
|
|
112
112
|
};
|
|
113
113
|
|
|
114
114
|
export function useMultiCellActionButtons(cellIds: CellId[]) {
|
|
115
|
-
const {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
clearCellOutput,
|
|
119
|
-
sendToTop,
|
|
120
|
-
sendToBottom,
|
|
121
|
-
} = useCellActions();
|
|
115
|
+
const { moveCell, clearCellOutput, sendToTop, sendToBottom } =
|
|
116
|
+
useCellActions();
|
|
117
|
+
const edit = useNotebookDocumentEdit();
|
|
122
118
|
const deleteCell = useDeleteManyCellsCallback();
|
|
123
119
|
const hasOnlyOneCell = useAtomValue(hasOnlyOneCellAtom);
|
|
124
120
|
const selectionActions = useCellSelectionActions();
|
|
125
121
|
const runCells = useRunCells();
|
|
126
122
|
const pendingDeleteService = usePendingDeleteService();
|
|
127
123
|
const userConfig = useAtomValue(userConfigAtom);
|
|
128
|
-
const { saveCellConfig } = useRequestClient();
|
|
129
124
|
|
|
130
125
|
const selectedCount = cellIds.length;
|
|
131
126
|
|
|
@@ -205,16 +200,12 @@ export function useMultiCellActionButtons(cellIds: CellId[]) {
|
|
|
205
200
|
});
|
|
206
201
|
|
|
207
202
|
const toggleSelectedCellsProperty = useEvent(
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
await saveCellConfig({ configs });
|
|
215
|
-
|
|
216
|
-
cellIds.forEach((cellId) => {
|
|
217
|
-
updateCellConfig({ cellId, config: configs[cellId] });
|
|
203
|
+
(cellIds: CellId[], property: keyof CellConfig, value: boolean) => {
|
|
204
|
+
edit((tx) => {
|
|
205
|
+
for (const cellId of cellIds) {
|
|
206
|
+
const config: Partial<CellConfig> = { [property]: value };
|
|
207
|
+
tx.updateConfig(cellId, config);
|
|
208
|
+
}
|
|
218
209
|
});
|
|
219
210
|
},
|
|
220
211
|
);
|
|
@@ -13,7 +13,9 @@ import { mergeProps, useFocusWithin, useKeyboard } from "react-aria";
|
|
|
13
13
|
import { DATA_FOR_CELL_ID } from "@/components/data-table/cell-utils";
|
|
14
14
|
import { aiCompletionCellAtom } from "@/core/ai/state";
|
|
15
15
|
import { maybeAddMarimoImport } from "@/core/cells/add-missing-import";
|
|
16
|
-
import { cellIdsAtom, notebookAtom
|
|
16
|
+
import { cellIdsAtom, notebookAtom } from "@/core/cells/cells";
|
|
17
|
+
import { useCellActions } from "@/core/cells/actions";
|
|
18
|
+
import { useNotebookDocumentEdit } from "@/core/notebook/document";
|
|
17
19
|
import { useCellFocusActions } from "@/core/cells/focus";
|
|
18
20
|
import type { CellId } from "@/core/cells/ids";
|
|
19
21
|
import { HTMLCellId } from "@/core/cells/ids";
|
|
@@ -36,7 +38,6 @@ import {
|
|
|
36
38
|
} from "@/core/config/config";
|
|
37
39
|
import type { HotkeyAction } from "@/core/hotkeys/hotkeys";
|
|
38
40
|
import { parseShortcut } from "@/core/hotkeys/shortcuts";
|
|
39
|
-
import { useRequestClient } from "@/core/network/requests";
|
|
40
41
|
import { useSaveNotebook } from "@/core/saving/save-component";
|
|
41
42
|
import { Events } from "@/utils/events";
|
|
42
43
|
import type { CollapsibleTree } from "@/utils/id-tree";
|
|
@@ -189,9 +190,10 @@ export function useCellNavigationProps(
|
|
|
189
190
|
},
|
|
190
191
|
) {
|
|
191
192
|
const { saveOrNameNotebook } = useSaveNotebook();
|
|
192
|
-
const
|
|
193
|
+
const edit = useNotebookDocumentEdit();
|
|
193
194
|
const setAiCompletionCell = useSetAtom(aiCompletionCellAtom);
|
|
194
195
|
const actions = useCellActions();
|
|
196
|
+
const { createCell, moveToNextCell } = useCellActions();
|
|
195
197
|
const store = useStore();
|
|
196
198
|
const temporarilyShownCodeActions = useTemporarilyShownCodeActions();
|
|
197
199
|
const runCells = useRunCells();
|
|
@@ -376,21 +378,21 @@ export function useCellNavigationProps(
|
|
|
376
378
|
"cell.runAndNewBelow": addSingleHandler((cellIds) => {
|
|
377
379
|
runCells(cellIds);
|
|
378
380
|
const lastCellId = cellIds[cellIds.length - 1];
|
|
379
|
-
|
|
381
|
+
moveToNextCell({ cellId: lastCellId, before: false });
|
|
380
382
|
return true;
|
|
381
383
|
}),
|
|
382
384
|
"cell.runAndNewAbove": addSingleHandler((cellIds) => {
|
|
383
385
|
runCells(cellIds);
|
|
384
386
|
const firstCellId = cellIds[0];
|
|
385
|
-
|
|
387
|
+
moveToNextCell({ cellId: firstCellId, before: true });
|
|
386
388
|
return true;
|
|
387
389
|
}),
|
|
388
390
|
"cell.createAbove": (cellId) => {
|
|
389
|
-
|
|
391
|
+
createCell({ before: cellId });
|
|
390
392
|
return true;
|
|
391
393
|
},
|
|
392
394
|
"cell.createBelow": (cellId) => {
|
|
393
|
-
|
|
395
|
+
createCell({ after: cellId });
|
|
394
396
|
return true;
|
|
395
397
|
},
|
|
396
398
|
"cell.moveUp": addSingleHandler((cellIds) => {
|
|
@@ -453,20 +455,12 @@ export function useCellNavigationProps(
|
|
|
453
455
|
(config) => config?.hide_code,
|
|
454
456
|
);
|
|
455
457
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
),
|
|
458
|
+
edit((tx) => {
|
|
459
|
+
for (const cellId of cellIds) {
|
|
460
|
+
tx.updateConfig(cellId, { hide_code: nextHideCode });
|
|
461
|
+
}
|
|
461
462
|
});
|
|
462
463
|
|
|
463
|
-
for (const cellId of cellIds) {
|
|
464
|
-
actions.updateCellConfig({
|
|
465
|
-
cellId,
|
|
466
|
-
config: { hide_code: nextHideCode },
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
|
|
470
464
|
// Only focus if it is a single cell
|
|
471
465
|
if (cellIds.length === 1) {
|
|
472
466
|
const cellId = cellIds[0];
|
|
@@ -543,14 +537,14 @@ export function useCellNavigationProps(
|
|
|
543
537
|
if (Events.hasModifier(evt)) {
|
|
544
538
|
return false;
|
|
545
539
|
}
|
|
546
|
-
|
|
540
|
+
createCell({ before: cellId });
|
|
547
541
|
return true;
|
|
548
542
|
},
|
|
549
543
|
"command.createCellAfter": (cellId) => {
|
|
550
544
|
if (Events.hasModifier(evt)) {
|
|
551
545
|
return false;
|
|
552
546
|
}
|
|
553
|
-
|
|
547
|
+
createCell({ after: cellId });
|
|
554
548
|
return true;
|
|
555
549
|
},
|
|
556
550
|
"command.createSqlCellAfter": (cellId) => {
|
|
@@ -559,14 +553,12 @@ export function useCellNavigationProps(
|
|
|
559
553
|
}
|
|
560
554
|
maybeAddMarimoImport({
|
|
561
555
|
autoInstantiate: true,
|
|
562
|
-
|
|
556
|
+
createCell: createCell,
|
|
563
557
|
fromCellId: cellId,
|
|
564
558
|
before: true,
|
|
565
559
|
});
|
|
566
|
-
|
|
567
|
-
cellId,
|
|
568
|
-
before: false,
|
|
569
|
-
autoFocus: true,
|
|
560
|
+
createCell({
|
|
561
|
+
after: cellId,
|
|
570
562
|
code: LanguageAdapters.sql.defaultCode,
|
|
571
563
|
});
|
|
572
564
|
return true;
|
|
@@ -635,11 +627,11 @@ export function useCellNavigationProps(
|
|
|
635
627
|
return true;
|
|
636
628
|
},
|
|
637
629
|
o: () => {
|
|
638
|
-
|
|
630
|
+
createCell({ after: cellId });
|
|
639
631
|
return true;
|
|
640
632
|
},
|
|
641
633
|
"shift+o": () => {
|
|
642
|
-
|
|
634
|
+
createCell({ before: cellId });
|
|
643
635
|
return true;
|
|
644
636
|
},
|
|
645
637
|
u: () => {
|
|
@@ -43,13 +43,12 @@ import { useResizeObserver } from "@/hooks/useResizeObserver";
|
|
|
43
43
|
import { cn } from "@/utils/cn";
|
|
44
44
|
import type { Milliseconds, Seconds } from "@/utils/time";
|
|
45
45
|
import {
|
|
46
|
-
type CellActions,
|
|
47
46
|
createUntouchedCellAtom,
|
|
48
|
-
useCellActions,
|
|
49
47
|
useCellData,
|
|
50
48
|
useCellHandle,
|
|
51
49
|
useCellRuntime,
|
|
52
50
|
} from "../../core/cells/cells";
|
|
51
|
+
import { type CellActions, useCellActions } from "../../core/cells/actions";
|
|
53
52
|
import { type CellId, SETUP_CELL_ID } from "../../core/cells/ids";
|
|
54
53
|
import {
|
|
55
54
|
cellNeedsRun,
|
|
@@ -216,13 +215,10 @@ function useCellHiddenLogic({
|
|
|
216
215
|
export type CellComponentActions = Pick<
|
|
217
216
|
CellActions,
|
|
218
217
|
| "updateCellCode"
|
|
219
|
-
| "createNewCell"
|
|
220
218
|
| "focusCell"
|
|
221
219
|
| "moveCell"
|
|
222
220
|
| "collapseCell"
|
|
223
221
|
| "expandCell"
|
|
224
|
-
| "moveToNextCell"
|
|
225
|
-
| "updateCellConfig"
|
|
226
222
|
| "clearSerializedEditorState"
|
|
227
223
|
| "setStdinResponse"
|
|
228
224
|
| "clearCellConsoleOutput"
|
|
@@ -928,15 +924,16 @@ const CellLeftSideActions = memo(
|
|
|
928
924
|
actions: CellComponentActions;
|
|
929
925
|
}) => {
|
|
930
926
|
const connection = useAtomValue(connectionAtom);
|
|
931
|
-
const { className,
|
|
927
|
+
const { className, cellId } = props;
|
|
928
|
+
const { createCell } = useCellActions();
|
|
932
929
|
|
|
933
930
|
const createBelow = useEvent(
|
|
934
|
-
(
|
|
935
|
-
|
|
931
|
+
({ code, hideCode }: { code?: string; hideCode?: boolean } = {}) =>
|
|
932
|
+
createCell({ after: cellId, code, config: { hide_code: hideCode } }),
|
|
936
933
|
);
|
|
937
934
|
const createAbove = useEvent(
|
|
938
|
-
(
|
|
939
|
-
|
|
935
|
+
({ code, hideCode }: { code?: string; hideCode?: boolean } = {}) =>
|
|
936
|
+
createCell({ before: cellId, code, config: { hide_code: hideCode } }),
|
|
940
937
|
);
|
|
941
938
|
|
|
942
939
|
const oneClickShortcut = "mod";
|