@marimo-team/islands 0.23.2-dev3 → 0.23.2-dev30
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/_basePickBy-C-mod5Dp.js +34 -0
- package/dist/{_baseUniq-C87CckHL.js → _baseUniq-Be_p_Ty6.js} +2 -2
- package/dist/{architecture-7HQA4BMR-BHdkAMvZ.js → architecture-7HQA4BMR-kNyKQXbB.js} +2 -2
- package/dist/{architectureDiagram-VXUJARFQ-B3YQo9At.js → architectureDiagram-VXUJARFQ-Dx_Dniiw.js} +11 -11
- package/dist/{blockDiagram-VD42YOAC-CpQ3TKEN.js → blockDiagram-VD42YOAC-D3hGPvEt.js} +4 -4
- package/dist/{c4Diagram-YG6GDRKO-CZSU4uqU.js → c4Diagram-YG6GDRKO-CtY1WMbV.js} +1 -1
- package/dist/{chat-ui-CNHw9Osh.js → chat-ui-CQtPb6Dj.js} +4 -4
- package/dist/{chunk-4F5CHEZ2-D5mClyDv.js → chunk-4F5CHEZ2-oWcaQSBe.js} +1 -1
- package/dist/{chunk-B2363JML-Br0eA2T3.js → chunk-B2363JML-72CRxZbk.js} +1 -1
- package/dist/{chunk-B4BG7PRW-4BjV11Br.js → chunk-B4BG7PRW-ChYfc4rf.js} +2 -2
- package/dist/{chunk-DI55MBZ5-DITY3EyP.js → chunk-DI55MBZ5-CYNE3N2j.js} +2 -2
- package/dist/{chunk-FRFDVMJY-DnEvEFRR.js → chunk-FRFDVMJY-Dgl-7l0K.js} +1 -1
- package/dist/{chunk-JA3XYJ7Z-BcPEfxk_.js → chunk-JA3XYJ7Z-B2BoMdpr.js} +1 -1
- package/dist/{chunk-JZLCHNYA-2bnLL3xL.js → chunk-JZLCHNYA-CkHD9mQU.js} +2 -2
- package/dist/{chunk-N4CR4FBY-CpZSuGSU.js → chunk-N4CR4FBY-DDeXUk3y.js} +4 -4
- package/dist/{chunk-PL6DKKU2-DnId6G-x.js → chunk-PL6DKKU2-CpBHhdj8.js} +1 -1
- package/dist/{chunk-QXUST7PY-Ch6F5Obl.js → chunk-QXUST7PY-BnSZbSK7.js} +3 -3
- package/dist/{chunk-S3R3BYOJ-B0UOFJwq.js → chunk-S3R3BYOJ-DVdRer7T.js} +1 -1
- package/dist/{chunk-SJTYNZTY-BsBZnJUj.js → chunk-SJTYNZTY-DPOwAZc-.js} +1 -1
- package/dist/{chunk-TCCFYFTB-Clbl-fTg.js → chunk-TCCFYFTB-BdE6BTq1.js} +6 -6
- package/dist/{chunk-TQ3KTPDO-CFkSQ30e.js → chunk-TQ3KTPDO-BCXCq8f2.js} +1 -1
- package/dist/{chunk-UMXZTB3W-D-A834Bq.js → chunk-UMXZTB3W-C5Hu2atA.js} +1 -1
- package/dist/{classDiagram-v2-WZHVMYZB-DrmbGANl.js → classDiagram-2ON5EDUG-sUXB0Obe.js} +6 -6
- package/dist/{classDiagram-2ON5EDUG-C8-zE3Zv.js → classDiagram-v2-WZHVMYZB-JeF9-idj.js} +6 -6
- package/dist/{clone-DZFQCtFJ.js → clone-B48LSK6I.js} +1 -1
- package/dist/{constants-CvyfaCvs.js → constants-CcdcOQyC.js} +2 -1
- package/dist/{dagre-6UL2VRFP-OMItEBnY.js → dagre-6UL2VRFP-Bs_DhCUk.js} +9 -9
- package/dist/{dagre-QVd-lCXU.js → dagre-BLW2E2fh.js} +19 -8
- package/dist/{diagram-PSM6KHXK-CkKbohWI.js → diagram-PSM6KHXK-VB3japmQ.js} +10 -10
- package/dist/{diagram-QEK2KX5R-DjUMpVcx.js → diagram-QEK2KX5R-B8nm2JL9.js} +10 -10
- package/dist/{diagram-S2PKOQOG-b-c0d-wZ.js → diagram-S2PKOQOG-D6PR_2iv.js} +10 -10
- package/dist/{erDiagram-Q2GNP2WA-CDhLaOZ1.js → erDiagram-Q2GNP2WA-gjAse7Jb.js} +5 -5
- package/dist/{flowDiagram-NV44I4VS-BDi4O4CL.js → flowDiagram-NV44I4VS-CQTSZWcI.js} +5 -5
- package/dist/{ganttDiagram-JELNMOA3-BpZE6kVp.js → ganttDiagram-JELNMOA3-aktqk_om.js} +1 -1
- package/dist/{gitGraph-G5XIXVHT-B_c6xFJv.js → gitGraph-G5XIXVHT-Cy06nzLg.js} +2 -2
- package/dist/{gitGraphDiagram-V2S2FVAM-iQnXzbPM.js → gitGraphDiagram-V2S2FVAM-C1ntKO33.js} +10 -10
- package/dist/{glide-data-editor-BFqEJGJW.js → glide-data-editor-DBgJAMqf.js} +2 -2
- package/dist/{graphlib-BV1_gi0C.js → graphlib-Cr691-na.js} +3 -3
- package/dist/{hasIn-DnfJcYpY.js → hasIn-BDDmuo1w.js} +1 -1
- package/dist/{info-VBDWY6EO-BTyzxmhr.js → info-VBDWY6EO-BIO6A8nW.js} +2 -2
- package/dist/{infoDiagram-HS3SLOUP-OYrX6uO3.js → infoDiagram-HS3SLOUP-CtfUf0g_.js} +9 -9
- package/dist/{input-CSVEkmaZ.js → input-Czatnqbz.js} +1 -1
- package/dist/{kanban-definition-3W4ZIXB7-DHEAKdZt.js → kanban-definition-3W4ZIXB7-C5FK4v7x.js} +3 -3
- package/dist/main.js +329 -179
- package/dist/{mermaid-BbhZNQeB.js → mermaid-CcM8GHeT.js} +29 -29
- package/dist/{mermaid-parser.core-ntCgyx0x.js → mermaid-parser.core-fZdPSYor.js} +8 -8
- package/dist/min-DAIOAwWK.js +102 -0
- package/dist/{mindmap-definition-VGOIOE7T-CxEUZZvY.js → mindmap-definition-VGOIOE7T-BvrQf8XZ.js} +5 -5
- package/dist/{packet-DYOGHKS2-BhvnpoGi.js → packet-DYOGHKS2-DDx1z7B-.js} +2 -2
- package/dist/pick-DfX21dj2.js +18 -0
- package/dist/{pie-VRWISCQL-dILuA3iG.js → pie-VRWISCQL-BgRtyDMT.js} +2 -2
- package/dist/{pieDiagram-ADFJNKIX-U3LrUqAS.js → pieDiagram-ADFJNKIX-DAhjFwJD.js} +10 -10
- package/dist/{process-output-Bekznt_B.js → process-output-CzeGyEyz.js} +2138 -2124
- package/dist/{radar-ZZBFDIW7-DwFrOJDj.js → radar-ZZBFDIW7-xwh47Yzn.js} +2 -2
- package/dist/{requirementDiagram-UZGBJVZJ-D0zpQnKC.js → requirementDiagram-UZGBJVZJ-B3nnp0VG.js} +5 -5
- package/dist/{sequenceDiagram-WL72ISMW-D1BJxLjH.js → sequenceDiagram-WL72ISMW-D2mpRRG2.js} +1 -1
- package/dist/{stateDiagram-FKZM4ZOC-B1S8jGMn.js → stateDiagram-FKZM4ZOC-QD9Wuca0.js} +8 -8
- package/dist/{stateDiagram-v2-4FDKWEC3-BH5ozUbc.js → stateDiagram-v2-4FDKWEC3-DnUhJ525.js} +6 -6
- package/dist/{toDate-B1AzlBoW.js → toDate-BxaMtnNb.js} +1 -1
- package/dist/{treemap-GDKQZRPO-bx2ngsgN.js → treemap-GDKQZRPO-5ZsmvXgc.js} +2 -2
- package/dist/{types-pwjdK009.js → types-DZvw9zQT.js} +1 -1
- package/dist/{useDeepCompareMemoize-CsyOnnjc.js → useDeepCompareMemoize-BOrrcIxj.js} +1 -1
- package/dist/{vega-component-KBJXEDZz.js → vega-component-CrVeizNZ.js} +3 -3
- package/dist/{xychartDiagram-PRI3JC2R-CuAZiqHS.js → xychartDiagram-PRI3JC2R-BMsB7VdF.js} +2 -2
- package/package.json +2 -2
- package/src/components/data-table/TableBottomBar.tsx +5 -1
- package/src/components/data-table/__tests__/filters.test.ts +304 -0
- package/src/components/data-table/__tests__/pagination.test.tsx +46 -132
- package/src/components/data-table/column-explorer-panel/column-explorer.tsx +1 -1
- package/src/components/data-table/filters.ts +87 -33
- package/src/components/data-table/pagination.tsx +189 -76
- package/src/components/data-table/types.ts +0 -4
- package/src/components/editor/Output.tsx +1 -1
- package/src/components/editor/actions/useNotebookActions.tsx +12 -0
- package/src/components/editor/cell/code/cell-editor.tsx +1 -0
- package/src/core/cells/__tests__/apply-transaction.test.ts +42 -0
- package/src/core/cells/__tests__/logs.test.ts +101 -0
- package/src/core/cells/logs.ts +9 -1
- package/src/core/codemirror/__tests__/__snapshots__/setup.test.ts.snap +4 -14
- package/src/core/codemirror/cells/extensions.ts +0 -4
- package/src/core/codemirror/keymaps/keymaps.ts +69 -2
- package/src/core/codemirror/language/languages/python.ts +9 -9
- package/src/core/codemirror/lsp/__tests__/notebook-lsp.test.ts +8 -1
- package/src/core/codemirror/lsp/federated-lsp.ts +2 -2
- package/src/core/codemirror/lsp/notebook-lsp.ts +2 -2
- package/src/core/codemirror/lsp/utils.ts +21 -6
- package/src/core/constants.ts +1 -0
- package/src/plugins/impl/DataTablePlugin.tsx +7 -20
- package/src/plugins/impl/TabsPlugin.tsx +18 -12
- package/src/plugins/impl/data-frames/DataFramePlugin.tsx +4 -4
- package/src/plugins/impl/data-frames/schema.ts +41 -9
- package/src/plugins/impl/data-frames/utils/operators.ts +2 -0
- package/src/plugins/impl/matplotlib/matplotlib-renderer.ts +16 -0
- package/dist/_basePickBy-Sow3pJjS.js +0 -41
- package/dist/min-Ds3gG0Ff.js +0 -96
- package/dist/range-fJeId9Ri.js +0 -30
- /package/dist/{isEmpty-B7FX9wKt.js → isEmpty-D3lf6gH3.js} +0 -0
- /package/dist/{memoize-CSTI9eOX.js → memoize-DEvRzlwP.js} +0 -0
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
+
cursorCharLeft,
|
|
5
|
+
cursorCharRight,
|
|
6
|
+
cursorLineDown,
|
|
7
|
+
cursorLineUp,
|
|
4
8
|
insertNewlineAndIndent,
|
|
5
9
|
defaultKeymap as originalDefaultKeymap,
|
|
10
|
+
selectCharLeft,
|
|
11
|
+
selectCharRight,
|
|
12
|
+
selectLineDown,
|
|
13
|
+
selectLineUp,
|
|
6
14
|
toggleBlockComment,
|
|
7
15
|
toggleComment,
|
|
8
16
|
} from "@codemirror/commands";
|
|
@@ -13,7 +21,7 @@ import {
|
|
|
13
21
|
type KeyBinding,
|
|
14
22
|
keymap,
|
|
15
23
|
} from "@codemirror/view";
|
|
16
|
-
import { getCM, vim } from "@replit/codemirror-vim";
|
|
24
|
+
import { type CodeMirror, getCM, vim } from "@replit/codemirror-vim";
|
|
17
25
|
import type { KeymapConfig } from "@/core/config/config-schema";
|
|
18
26
|
import type { HotkeyProvider } from "@/core/hotkeys/hotkeys";
|
|
19
27
|
import { logNever } from "@/utils/assertNever";
|
|
@@ -62,6 +70,12 @@ export function keymapBundle(
|
|
|
62
70
|
},
|
|
63
71
|
),
|
|
64
72
|
),
|
|
73
|
+
// Arrow keys: use CodeMirror's cursor movement except in vim visual
|
|
74
|
+
// mode, where vim must handle them to maintain selection.
|
|
75
|
+
// The original cursorLineUp/Down bindings from the default keymap are
|
|
76
|
+
// filtered out (see defaultVimKeymap) because their preventDefault
|
|
77
|
+
// flag blocks vim's handler even when their run function returns false.
|
|
78
|
+
keymap.of(vimVisualModeArrowKeyBindings()),
|
|
65
79
|
// Base vim mode
|
|
66
80
|
vim({ status: false }),
|
|
67
81
|
// Custom vim keymaps for cell navigation
|
|
@@ -101,12 +115,22 @@ const overrideKeymap = (keymap: HotkeyProvider): readonly KeyBinding[] => {
|
|
|
101
115
|
};
|
|
102
116
|
|
|
103
117
|
const defaultVimKeymap = once(() => {
|
|
104
|
-
const toRemove = new Set([
|
|
118
|
+
const toRemove = new Set([
|
|
119
|
+
"Enter",
|
|
120
|
+
"Ctrl-v",
|
|
121
|
+
"ArrowUp",
|
|
122
|
+
"ArrowDown",
|
|
123
|
+
"ArrowLeft",
|
|
124
|
+
"ArrowRight",
|
|
125
|
+
]);
|
|
105
126
|
// Remove conflicting keys from the keymap
|
|
106
127
|
// Enter (<CR>) adds a new line
|
|
107
128
|
// - it should just go to the next line
|
|
108
129
|
// Ctrl-v goes to the bottom of the cell
|
|
109
130
|
// - should enter blockwise visual mode
|
|
131
|
+
// ArrowUp/ArrowDown (cursorLineUp/Down) always handle the event and have
|
|
132
|
+
// preventDefault, which blocks vim's handler from processing arrow keys.
|
|
133
|
+
// Replaced with visual-mode-aware wrappers in keymapBundle.
|
|
110
134
|
return defaultKeymap().filter(
|
|
111
135
|
(k) => !toRemove.has(k.key || k.mac || k.linux || k.win || ""),
|
|
112
136
|
);
|
|
@@ -155,6 +179,49 @@ function doubleCharacterListener(
|
|
|
155
179
|
]);
|
|
156
180
|
}
|
|
157
181
|
|
|
182
|
+
function isInVimVisualMode(cm: CodeMirror | undefined | null): boolean {
|
|
183
|
+
return cm?.state.vim?.visualMode === true;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* In vim visual mode, arrow keys must be handled by vim to maintain selection.
|
|
188
|
+
* Wrap each arrow key's run and shift so they defer to vim in visual mode,
|
|
189
|
+
* but use CodeMirror's cursor commands in all other modes.
|
|
190
|
+
*/
|
|
191
|
+
function vimVisualModeArrowKeyBindings(): KeyBinding[] {
|
|
192
|
+
const wrap =
|
|
193
|
+
(cmd: Command): Command =>
|
|
194
|
+
(view) => {
|
|
195
|
+
if (isInVimVisualMode(getCM(view))) {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
return cmd(view);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
return [
|
|
202
|
+
{
|
|
203
|
+
key: "ArrowDown",
|
|
204
|
+
run: wrap(cursorLineDown),
|
|
205
|
+
shift: wrap(selectLineDown),
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
key: "ArrowUp",
|
|
209
|
+
run: wrap(cursorLineUp),
|
|
210
|
+
shift: wrap(selectLineUp),
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
key: "ArrowLeft",
|
|
214
|
+
run: wrap(cursorCharLeft),
|
|
215
|
+
shift: wrap(selectCharLeft),
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
key: "ArrowRight",
|
|
219
|
+
run: wrap(cursorCharRight),
|
|
220
|
+
shift: wrap(selectCharRight),
|
|
221
|
+
},
|
|
222
|
+
];
|
|
223
|
+
}
|
|
224
|
+
|
|
158
225
|
export const visibleForTesting = {
|
|
159
226
|
defaultKeymap,
|
|
160
227
|
defaultVimKeymap,
|
|
@@ -36,7 +36,7 @@ import { FederatedLanguageServerClient } from "../../lsp/federated-lsp";
|
|
|
36
36
|
import { NotebookLanguageServerClient } from "../../lsp/notebook-lsp";
|
|
37
37
|
import { createTransport } from "../../lsp/transports";
|
|
38
38
|
import { CellDocumentUri, type ILanguageServerClient } from "../../lsp/types";
|
|
39
|
-
import {
|
|
39
|
+
import { getLspRootUri, getLspWorkspaceFolders } from "../../lsp/utils";
|
|
40
40
|
import {
|
|
41
41
|
clickablePlaceholderExtension,
|
|
42
42
|
smartPlaceholderExtension,
|
|
@@ -54,8 +54,8 @@ const pylspClient = once((lspConfig: LSPConfig) => {
|
|
|
54
54
|
|
|
55
55
|
const lspClientOpts = {
|
|
56
56
|
transport,
|
|
57
|
-
rootUri:
|
|
58
|
-
workspaceFolders:
|
|
57
|
+
rootUri: getLspRootUri(),
|
|
58
|
+
workspaceFolders: getLspWorkspaceFolders(),
|
|
59
59
|
};
|
|
60
60
|
const config = lspConfig?.pylsp;
|
|
61
61
|
|
|
@@ -161,8 +161,8 @@ const tyLspClient = once((_: LSPConfig) => {
|
|
|
161
161
|
|
|
162
162
|
const lspClientOpts = {
|
|
163
163
|
transport,
|
|
164
|
-
rootUri:
|
|
165
|
-
workspaceFolders:
|
|
164
|
+
rootUri: getLspRootUri(),
|
|
165
|
+
workspaceFolders: getLspWorkspaceFolders(),
|
|
166
166
|
};
|
|
167
167
|
|
|
168
168
|
// We wrap the client in a NotebookLanguageServerClient to add some
|
|
@@ -192,8 +192,8 @@ const pyreflyClient = once(
|
|
|
192
192
|
|
|
193
193
|
const lspClientOpts = {
|
|
194
194
|
transport,
|
|
195
|
-
rootUri:
|
|
196
|
-
workspaceFolders:
|
|
195
|
+
rootUri: getLspRootUri(),
|
|
196
|
+
workspaceFolders: getLspWorkspaceFolders(),
|
|
197
197
|
};
|
|
198
198
|
|
|
199
199
|
// We wrap the client in a NotebookLanguageServerClient to add some
|
|
@@ -230,8 +230,8 @@ const pyrightClient = once((_: LSPConfig) => {
|
|
|
230
230
|
|
|
231
231
|
const lspClientOpts = {
|
|
232
232
|
transport,
|
|
233
|
-
rootUri:
|
|
234
|
-
workspaceFolders:
|
|
233
|
+
rootUri: getLspRootUri(),
|
|
234
|
+
workspaceFolders: getLspWorkspaceFolders(),
|
|
235
235
|
};
|
|
236
236
|
|
|
237
237
|
// We wrap the client in a NotebookLanguageServerClient to add some
|
|
@@ -12,6 +12,7 @@ import { cellId } from "@/__tests__/branded";
|
|
|
12
12
|
import type { CellId } from "@/core/cells/ids";
|
|
13
13
|
import { store } from "@/core/state/jotai";
|
|
14
14
|
import { topologicalCodesAtom } from "../../copilot/getCodes";
|
|
15
|
+
import { lspWorkspaceAtom } from "@/core/saving/file-state";
|
|
15
16
|
import { languageAdapterState } from "../../language/extension";
|
|
16
17
|
import { PythonLanguageAdapter } from "../../language/languages/python";
|
|
17
18
|
import { languageMetadataField } from "../../language/metadata";
|
|
@@ -285,6 +286,12 @@ describe("NotebookLanguageServerClient", () => {
|
|
|
285
286
|
},
|
|
286
287
|
};
|
|
287
288
|
}
|
|
289
|
+
if (atom === lspWorkspaceAtom) {
|
|
290
|
+
return {
|
|
291
|
+
rootUri: "file:///project",
|
|
292
|
+
documentUri: "file:///project/__marimo_notebook__.py",
|
|
293
|
+
};
|
|
294
|
+
}
|
|
288
295
|
return undefined;
|
|
289
296
|
});
|
|
290
297
|
|
|
@@ -421,7 +428,7 @@ describe("NotebookLanguageServerClient", () => {
|
|
|
421
428
|
expect(result).toEqual(mockCompletionResponse);
|
|
422
429
|
expect(mockClient.textDocumentCompletion).toHaveBeenCalledWith(
|
|
423
430
|
expect.objectContaining({
|
|
424
|
-
textDocument: { uri: "file:///__marimo_notebook__.py" },
|
|
431
|
+
textDocument: { uri: "file:///project/__marimo_notebook__.py" },
|
|
425
432
|
}),
|
|
426
433
|
);
|
|
427
434
|
});
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import type * as LSP from "vscode-languageserver-protocol";
|
|
4
4
|
import { Objects } from "@/utils/objects";
|
|
5
5
|
import type { ILanguageServerClient } from "./types";
|
|
6
|
-
import {
|
|
6
|
+
import { getLspDocumentUri } from "./utils";
|
|
7
7
|
|
|
8
8
|
function removeFalseyValues<T extends object>(obj: T): T {
|
|
9
9
|
return Objects.filter(obj, (value) => value !== false && value !== null) as T;
|
|
@@ -20,7 +20,7 @@ export class FederatedLanguageServerClient implements ILanguageServerClient {
|
|
|
20
20
|
|
|
21
21
|
constructor(clients: ILanguageServerClient[]) {
|
|
22
22
|
this.clients = clients;
|
|
23
|
-
this.documentUri =
|
|
23
|
+
this.documentUri = getLspDocumentUri();
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
onNotification(
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
type ILanguageServerClient,
|
|
23
23
|
isClientWithNotify,
|
|
24
24
|
} from "./types";
|
|
25
|
-
import {
|
|
25
|
+
import { getLspDocumentUri } from "./utils";
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Check if a variable name is private (starts with underscore but not dunder).
|
|
@@ -189,7 +189,7 @@ export class NotebookLanguageServerClient implements ILanguageServerClient {
|
|
|
189
189
|
EditorView | null | undefined
|
|
190
190
|
> = defaultGetNotebookEditors,
|
|
191
191
|
) {
|
|
192
|
-
this.documentUri =
|
|
192
|
+
this.documentUri = getLspDocumentUri();
|
|
193
193
|
this.getNotebookEditors = getNotebookEditors;
|
|
194
194
|
this.initialSettings = initialSettings;
|
|
195
195
|
this.client = client;
|
|
@@ -1,11 +1,26 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { lspWorkspaceAtom } from "@/core/saving/file-state";
|
|
3
|
+
import { store } from "@/core/state/jotai";
|
|
4
4
|
|
|
5
|
-
export function
|
|
6
|
-
|
|
5
|
+
export function getLspRootUri() {
|
|
6
|
+
const lspWorkspace = store.get(lspWorkspaceAtom);
|
|
7
|
+
// The backend provides rootUri for active notebook sessions.
|
|
8
|
+
// For non-notebook pages (home, gallery), lspWorkspace is null,
|
|
9
|
+
// so return a valid file URI fallback.
|
|
10
|
+
return lspWorkspace?.rootUri ?? "file:///";
|
|
7
11
|
}
|
|
8
12
|
|
|
9
|
-
export function
|
|
10
|
-
|
|
13
|
+
export function getLspWorkspaceFolders() {
|
|
14
|
+
const lspWorkspace = store.get(lspWorkspaceAtom);
|
|
15
|
+
const rootUri = lspWorkspace?.rootUri;
|
|
16
|
+
// Return workspace folders only if rootUri is set; empty array otherwise.
|
|
17
|
+
return rootUri ? [{ uri: rootUri, name: "marimo" }] : [];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function getLspDocumentUri() {
|
|
21
|
+
const lspWorkspace = store.get(lspWorkspaceAtom);
|
|
22
|
+
// The backend provides documentUri for active notebook sessions.
|
|
23
|
+
// For non-notebook pages (home, gallery), lspWorkspace is null,
|
|
24
|
+
// so return a valid file URI fallback.
|
|
25
|
+
return lspWorkspace?.documentUri ?? "file:///__marimo_notebook__.py";
|
|
11
26
|
}
|
package/src/core/constants.ts
CHANGED
|
@@ -28,10 +28,7 @@ import { TablePanel } from "@/components/data-table/charts/charts";
|
|
|
28
28
|
import { hasChart } from "@/components/data-table/charts/storage";
|
|
29
29
|
import { ColumnChartSpecModel } from "@/components/data-table/column-summary/chart-spec-model";
|
|
30
30
|
import { ColumnChartContext } from "@/components/data-table/column-summary/column-summary";
|
|
31
|
-
import {
|
|
32
|
-
type ColumnFilterValue,
|
|
33
|
-
filterToFilterCondition,
|
|
34
|
-
} from "@/components/data-table/filters";
|
|
31
|
+
import { filtersToFilterGroup } from "@/components/data-table/filters";
|
|
35
32
|
import { usePanelOwnership } from "@/components/data-table/hooks/use-panel-ownership";
|
|
36
33
|
import { LoadingTable } from "@/components/data-table/loading-table";
|
|
37
34
|
import {
|
|
@@ -86,8 +83,8 @@ import { rpc } from "../core/rpc";
|
|
|
86
83
|
import { Banner } from "./common/error-banner";
|
|
87
84
|
import { Labeled } from "./common/labeled";
|
|
88
85
|
import {
|
|
89
|
-
|
|
90
|
-
type
|
|
86
|
+
FilterGroupSchema,
|
|
87
|
+
type FilterGroupType,
|
|
91
88
|
columnToFieldTypesSchema,
|
|
92
89
|
} from "./data-frames/schema";
|
|
93
90
|
|
|
@@ -213,7 +210,7 @@ type DataTableFunctions = {
|
|
|
213
210
|
descending: boolean;
|
|
214
211
|
}[];
|
|
215
212
|
query?: string;
|
|
216
|
-
filters?:
|
|
213
|
+
filters?: FilterGroupType;
|
|
217
214
|
page_number: number;
|
|
218
215
|
page_size: number;
|
|
219
216
|
max_columns?: number | null;
|
|
@@ -312,7 +309,7 @@ export const DataTablePlugin = createPlugin<S>("marimo-table")
|
|
|
312
309
|
)
|
|
313
310
|
.optional(),
|
|
314
311
|
query: z.string().optional(),
|
|
315
|
-
filters:
|
|
312
|
+
filters: FilterGroupSchema.optional(),
|
|
316
313
|
page_number: z.number(),
|
|
317
314
|
page_size: z.number(),
|
|
318
315
|
max_columns: z.number().nullable().optional(),
|
|
@@ -578,12 +575,7 @@ export const LoadingDataTableComponent = memo(
|
|
|
578
575
|
query: searchQuery,
|
|
579
576
|
page_number: paginationState.pageIndex,
|
|
580
577
|
page_size: paginationState.pageSize,
|
|
581
|
-
filters: filters
|
|
582
|
-
return filterToFilterCondition(
|
|
583
|
-
filter.id,
|
|
584
|
-
filter.value as ColumnFilterValue,
|
|
585
|
-
);
|
|
586
|
-
}),
|
|
578
|
+
filters: filtersToFilterGroup(filters),
|
|
587
579
|
});
|
|
588
580
|
|
|
589
581
|
if (canShowInitialPage) {
|
|
@@ -641,12 +633,7 @@ export const LoadingDataTableComponent = memo(
|
|
|
641
633
|
page_size: 1,
|
|
642
634
|
sort: sortArgs,
|
|
643
635
|
query: searchQuery,
|
|
644
|
-
filters: filters
|
|
645
|
-
return filterToFilterCondition(
|
|
646
|
-
filter.id,
|
|
647
|
-
filter.value as ColumnFilterValue,
|
|
648
|
-
);
|
|
649
|
-
}),
|
|
636
|
+
filters: filtersToFilterGroup(filters),
|
|
650
637
|
// Do not clamp number of columns since we are viewing a single row
|
|
651
638
|
max_columns: null,
|
|
652
639
|
});
|
|
@@ -9,12 +9,14 @@ import {
|
|
|
9
9
|
} from "../../components/ui/tabs";
|
|
10
10
|
import { renderHTML } from "../core/RenderHTML";
|
|
11
11
|
import type { IPlugin, IPluginProps } from "../types";
|
|
12
|
+
import { Labeled } from "./common/labeled";
|
|
12
13
|
|
|
13
14
|
interface Data {
|
|
14
15
|
/**
|
|
15
16
|
* The labels for each tab; raw HTML.
|
|
16
17
|
*/
|
|
17
18
|
tabs: string[];
|
|
19
|
+
label: string | null;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
// Selected tab index
|
|
@@ -25,6 +27,7 @@ export class TabsPlugin implements IPlugin<T, Data> {
|
|
|
25
27
|
|
|
26
28
|
validator = z.object({
|
|
27
29
|
tabs: z.array(z.string()),
|
|
30
|
+
label: z.string().nullable(),
|
|
28
31
|
});
|
|
29
32
|
|
|
30
33
|
render(props: IPluginProps<T, Data>): JSX.Element {
|
|
@@ -47,6 +50,7 @@ interface TabComponentProps extends Data {
|
|
|
47
50
|
|
|
48
51
|
const TabComponent = ({
|
|
49
52
|
tabs,
|
|
53
|
+
label,
|
|
50
54
|
value,
|
|
51
55
|
setValue,
|
|
52
56
|
children,
|
|
@@ -67,17 +71,19 @@ const TabComponent = ({
|
|
|
67
71
|
}
|
|
68
72
|
|
|
69
73
|
return (
|
|
70
|
-
<
|
|
71
|
-
<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
{
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
74
|
+
<Labeled label={label} align="top">
|
|
75
|
+
<Tabs value={internalValue} onValueChange={handleChange}>
|
|
76
|
+
<TabsList>
|
|
77
|
+
{tabs.map((tab, index) => (
|
|
78
|
+
<TabsTrigger key={index} value={index.toString()}>
|
|
79
|
+
{renderHTML({ html: tab })}
|
|
80
|
+
</TabsTrigger>
|
|
81
|
+
))}
|
|
82
|
+
</TabsList>
|
|
83
|
+
{React.Children.map(children, (child, index) => {
|
|
84
|
+
return <TabsContent value={index.toString()}>{child}</TabsContent>;
|
|
85
|
+
})}
|
|
86
|
+
</Tabs>
|
|
87
|
+
</Labeled>
|
|
82
88
|
);
|
|
83
89
|
};
|
|
@@ -29,8 +29,8 @@ import { LoadingDataTableComponent, TableProviders } from "../DataTablePlugin";
|
|
|
29
29
|
import type { DataType } from "../vega/vega-loader";
|
|
30
30
|
import { TransformPanel, type TransformPanelHandle } from "./panel";
|
|
31
31
|
import {
|
|
32
|
-
|
|
33
|
-
type
|
|
32
|
+
FilterGroupSchema,
|
|
33
|
+
type FilterGroupType,
|
|
34
34
|
columnToFieldTypesSchema,
|
|
35
35
|
type Transformations,
|
|
36
36
|
} from "./schema";
|
|
@@ -75,7 +75,7 @@ type PluginFunctions = {
|
|
|
75
75
|
descending: boolean;
|
|
76
76
|
}[];
|
|
77
77
|
query?: string;
|
|
78
|
-
filters?:
|
|
78
|
+
filters?: FilterGroupType;
|
|
79
79
|
page_number: number;
|
|
80
80
|
page_size: number;
|
|
81
81
|
}) => Promise<{
|
|
@@ -138,7 +138,7 @@ export const DataFramePlugin = createPlugin<S>("marimo-dataframe")
|
|
|
138
138
|
)
|
|
139
139
|
.optional(),
|
|
140
140
|
query: z.string().optional(),
|
|
141
|
-
filters:
|
|
141
|
+
filters: FilterGroupSchema.optional(),
|
|
142
142
|
page_number: z.number(),
|
|
143
143
|
page_size: z.number(),
|
|
144
144
|
}),
|
|
@@ -73,16 +73,36 @@ const SortColumnTransformSchema = z.object({
|
|
|
73
73
|
.default("last"),
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
-
export const
|
|
76
|
+
export const FilterConditionSchema = z
|
|
77
77
|
.object({
|
|
78
78
|
column_id: column_id,
|
|
79
79
|
operator: z
|
|
80
80
|
.enum(Object.keys(ALL_OPERATORS) as [OperatorType, ...OperatorType[]])
|
|
81
81
|
.describe(FieldOptions.of({ label: " " })),
|
|
82
|
+
type: z.literal("condition").default("condition"),
|
|
82
83
|
value: z.any().describe(FieldOptions.of({ label: "Value" })),
|
|
84
|
+
negate: z.boolean().default(false),
|
|
83
85
|
})
|
|
84
86
|
.describe(FieldOptions.of({ direction: "row", special: "column_filter" }));
|
|
85
|
-
export type
|
|
87
|
+
export type FilterConditionType = z.infer<typeof FilterConditionSchema>;
|
|
88
|
+
|
|
89
|
+
export interface FilterGroupType {
|
|
90
|
+
type: "group";
|
|
91
|
+
operator: "and" | "or";
|
|
92
|
+
children: (FilterConditionType | FilterGroupType)[];
|
|
93
|
+
negate: boolean;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export const FilterGroupSchema: z.ZodType<FilterGroupType> = z.lazy(() =>
|
|
97
|
+
z.object({
|
|
98
|
+
type: z.literal("group").default("group"),
|
|
99
|
+
operator: z.enum(["and", "or"]).default("and"),
|
|
100
|
+
children: z
|
|
101
|
+
.array(z.union([FilterConditionSchema, FilterGroupSchema]))
|
|
102
|
+
.default([]),
|
|
103
|
+
negate: z.boolean().default(false),
|
|
104
|
+
}),
|
|
105
|
+
);
|
|
86
106
|
|
|
87
107
|
const FilterRowsTransformSchema = z.object({
|
|
88
108
|
type: z.literal("filter_rows"),
|
|
@@ -91,17 +111,29 @@ const FilterRowsTransformSchema = z.object({
|
|
|
91
111
|
.default("keep_rows")
|
|
92
112
|
.describe(FieldOptions.of({ special: "radio_group" })),
|
|
93
113
|
where: z
|
|
94
|
-
.array(
|
|
114
|
+
.array(FilterConditionSchema)
|
|
95
115
|
.min(1)
|
|
96
116
|
.describe(FieldOptions.of({ label: "Value", minLength: 1 }))
|
|
97
|
-
.
|
|
98
|
-
|
|
117
|
+
.default(() => [
|
|
118
|
+
{
|
|
119
|
+
column_id: "" as ColumnId,
|
|
120
|
+
operator: "==" as const,
|
|
121
|
+
value: "",
|
|
122
|
+
type: "condition" as const,
|
|
123
|
+
negate: false,
|
|
124
|
+
},
|
|
125
|
+
])
|
|
126
|
+
.transform((value): FilterGroupType => {
|
|
127
|
+
const validConditions = value.filter((condition) => {
|
|
99
128
|
return isConditionValueValid(condition.operator, condition.value);
|
|
100
129
|
});
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
130
|
+
return {
|
|
131
|
+
type: "group",
|
|
132
|
+
operator: "and",
|
|
133
|
+
children: validConditions,
|
|
134
|
+
negate: false,
|
|
135
|
+
};
|
|
136
|
+
}),
|
|
105
137
|
});
|
|
106
138
|
|
|
107
139
|
const GroupByTransformSchema = z
|
|
@@ -41,6 +41,7 @@ const createComparisonOperators = (schema: z.ZodType) => ({
|
|
|
41
41
|
">=": [schema],
|
|
42
42
|
"<": [schema],
|
|
43
43
|
"<=": [schema],
|
|
44
|
+
between: [z.object({ min: schema, max: schema })],
|
|
44
45
|
is_null: [],
|
|
45
46
|
is_not_null: [],
|
|
46
47
|
});
|
|
@@ -59,6 +60,7 @@ export const STRING_OPERATORS = {
|
|
|
59
60
|
ends_with: [Schema.string],
|
|
60
61
|
in: [Schema.stringMultiColumnValues],
|
|
61
62
|
not_in: [Schema.stringMultiColumnValues],
|
|
63
|
+
is_empty: [],
|
|
62
64
|
is_null: [],
|
|
63
65
|
is_not_null: [],
|
|
64
66
|
};
|
|
@@ -380,6 +380,18 @@ export class MatplotlibRenderer {
|
|
|
380
380
|
return;
|
|
381
381
|
}
|
|
382
382
|
|
|
383
|
+
// Restore selection from backend when the value changed and the user
|
|
384
|
+
// is not actively drawing/dragging/resizing. During active interactions
|
|
385
|
+
// the renderer owns the interaction state — overwriting it would fight
|
|
386
|
+
// the user's pointer.
|
|
387
|
+
const isUserInteracting =
|
|
388
|
+
this.#interaction.type !== "idle" && this.#interaction.action !== null;
|
|
389
|
+
if (state.value !== prev.value && !isUserInteracting) {
|
|
390
|
+
this.#restoreSelection(state.value);
|
|
391
|
+
// #restoreSelection already schedules a redraw
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
|
|
383
395
|
// Redraw if style props changed or dimensions changed
|
|
384
396
|
if (
|
|
385
397
|
needsRedraw ||
|
|
@@ -576,6 +588,10 @@ export class MatplotlibRenderer {
|
|
|
576
588
|
|
|
577
589
|
#restoreSelection = (value: SelectionValue): void => {
|
|
578
590
|
if (!value || !("has_selection" in value) || !value.has_selection) {
|
|
591
|
+
if (this.#interaction.type !== "idle") {
|
|
592
|
+
this.#interaction = { type: "idle" };
|
|
593
|
+
this.#scheduleRedraw();
|
|
594
|
+
}
|
|
579
595
|
return;
|
|
580
596
|
}
|
|
581
597
|
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { O as _assignValue_default, j as _isIndex_default, z as isObject_default } from "./isArrayLikeObject-LXbTYiBa.js";
|
|
2
|
-
import { c as _castPath_default, o as _baseGet_default, r as _baseFlatten_default, s as _toKey_default } from "./hasIn-DnfJcYpY.js";
|
|
3
|
-
import { t as toNumber_default } from "./toNumber-55tjPCWr.js";
|
|
4
|
-
var INFINITY = Infinity, MAX_INTEGER = 17976931348623157e292;
|
|
5
|
-
function toFinite(e) {
|
|
6
|
-
return e ? (e = toNumber_default(e), e === INFINITY || e === -INFINITY ? (e < 0 ? -1 : 1) * MAX_INTEGER : e === e ? e : 0) : e === 0 ? e : 0;
|
|
7
|
-
}
|
|
8
|
-
var toFinite_default = toFinite;
|
|
9
|
-
function flatten(e) {
|
|
10
|
-
return e != null && e.length ? _baseFlatten_default(e, 1) : [];
|
|
11
|
-
}
|
|
12
|
-
var flatten_default = flatten;
|
|
13
|
-
function baseSet(o, s, l, u) {
|
|
14
|
-
if (!isObject_default(o)) return o;
|
|
15
|
-
s = _castPath_default(s, o);
|
|
16
|
-
for (var d = -1, f = s.length, p = f - 1, m = o; m != null && ++d < f; ) {
|
|
17
|
-
var h = _toKey_default(s[d]), g = l;
|
|
18
|
-
if (h === "__proto__" || h === "constructor" || h === "prototype") return o;
|
|
19
|
-
if (d != p) {
|
|
20
|
-
var _ = m[h];
|
|
21
|
-
g = u ? u(_, h, m) : void 0, g === void 0 && (g = isObject_default(_) ? _ : _isIndex_default(s[d + 1]) ? [] : {});
|
|
22
|
-
}
|
|
23
|
-
_assignValue_default(m, h, g), m = m[h];
|
|
24
|
-
}
|
|
25
|
-
return o;
|
|
26
|
-
}
|
|
27
|
-
var _baseSet_default = baseSet;
|
|
28
|
-
function basePickBy(e, i, a) {
|
|
29
|
-
for (var s = -1, c = i.length, l = {}; ++s < c; ) {
|
|
30
|
-
var u = i[s], d = _baseGet_default(e, u);
|
|
31
|
-
a(d, u) && _baseSet_default(l, _castPath_default(u, e), d);
|
|
32
|
-
}
|
|
33
|
-
return l;
|
|
34
|
-
}
|
|
35
|
-
var _basePickBy_default = basePickBy;
|
|
36
|
-
export {
|
|
37
|
-
toFinite_default as i,
|
|
38
|
-
_baseSet_default as n,
|
|
39
|
-
flatten_default as r,
|
|
40
|
-
_basePickBy_default as t
|
|
41
|
-
};
|