@marimo-team/frontend 0.19.10-dev9 → 0.19.10
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/assets/{CellStatus-BYjJCgaE.js → CellStatus-BAeLnQ68.js} +1 -1
- package/dist/assets/JsonOutput-EJizmc0Z.js +46 -0
- package/dist/assets/{LazyAnyLanguageCodeMirror-DgZ8iknE.js → LazyAnyLanguageCodeMirror-BTO7DS3k.js} +2 -2
- package/dist/assets/{MarimoErrorOutput-JyWZzx2m.js → MarimoErrorOutput-C90djx1V.js} +1 -1
- package/dist/assets/Plot-DolV1EVq.js +3789 -0
- package/dist/assets/{RenderHTML-CfzZdtCa.js → RenderHTML-ByTXWSgj.js} +1 -1
- package/dist/assets/{add-cell-with-ai-kak40OU9.js → add-cell-with-ai-CnyhGSdf.js} +2 -2
- package/dist/assets/{add-database-form-CFtfw8CL.js → add-database-form-DqVwhh_K.js} +1 -1
- package/dist/assets/{agent-panel-v3TnlrgF.js → agent-panel-Bh2AfKzA.js} +1 -1
- package/dist/assets/{ai-model-dropdown-BWLcucX9.js → ai-model-dropdown-C_pphOGv.js} +1 -1
- package/dist/assets/{any-language-editor-BODEG_5g.js → any-language-editor-BdrnE_3i.js} +1 -1
- package/dist/assets/{app-config-button-BZ_itkIb.js → app-config-button-BariZTN8.js} +1 -1
- package/dist/assets/{cell-editor-QlfCJVx8.js → cell-editor-DMwqDwss.js} +12 -12
- package/dist/assets/{cell-link-CrgPSA5u.js → cell-link-D46k36Xe.js} +1 -1
- package/dist/assets/{cells-B9Mw1aiY.js → cells-DG7rjkOQ.js} +14 -14
- package/dist/assets/{chat-display-dPv3uSbY.js → chat-display-hQ2Dy5fa.js} +1 -1
- package/dist/assets/{chat-panel-BH2bCr1s.js → chat-panel-D4Bcz2Sv.js} +1 -1
- package/dist/assets/{column-preview-JRDUZ_bG.js → column-preview-DZULCraY.js} +1 -1
- package/dist/assets/{command-Ch5r6r1Z.js → command-Djb6VJ8T.js} +1 -1
- package/dist/assets/{command-palette-BtxKt_L8.js → command-palette-CXYdoElD.js} +1 -1
- package/dist/assets/{common-Bpmeqynd.js → common-B9j0Q2gP.js} +1 -1
- package/dist/assets/{datasource-C-tSv_Wf.js → datasource-w1NuMzfo.js} +1 -1
- package/dist/assets/dependency-graph-panel-DED_3Q6I.js +4 -0
- package/dist/assets/dist--lWkNwLa.js +1 -0
- package/dist/assets/{dist-CRjEDsfC.js → dist-8qtC33as.js} +1 -1
- package/dist/assets/{dist-CsRJPnA9.js → dist-B0T008FI.js} +1 -1
- package/dist/assets/dist-B1Jd_IvQ.js +1 -0
- package/dist/assets/dist-B5vqrkGM.js +1 -0
- package/dist/assets/dist-BDTS_4tQ.js +1 -0
- package/dist/assets/{dist-C5H5qIvq.js → dist-BHxWJlYy.js} +1 -1
- package/dist/assets/{dist-sMh6mJ2d.js → dist-BNkRH34W.js} +2 -2
- package/dist/assets/{dist-tLOz534J.js → dist-BP9zs-JA.js} +1 -1
- package/dist/assets/dist-BeHHM5ER.js +1 -0
- package/dist/assets/dist-BkTLZYtq.js +1 -0
- package/dist/assets/dist-Bl-MdZlw.js +1 -0
- package/dist/assets/dist-Bouhdq2b.js +1 -0
- package/dist/assets/{dist-CtrmRz20.js → dist-BqBWjk9M.js} +3 -3
- package/dist/assets/{dist-Gqv0jSNr.js → dist-Bt3KRZho.js} +1 -1
- package/dist/assets/dist-BtnFSOCN.js +1 -0
- package/dist/assets/{dist-B62Xo7-b.js → dist-C0vFollF.js} +1 -1
- package/dist/assets/dist-CBgJfRVh.js +1 -0
- package/dist/assets/{dist-CEaOyZOW.js → dist-CCX32maQ.js} +1 -1
- package/dist/assets/dist-CDTDwVaL.js +1 -0
- package/dist/assets/dist-CF9gSfGe.js +2 -0
- package/dist/assets/{dist-BpuNldXk.js → dist-CShMY7yu.js} +1 -1
- package/dist/assets/{dist-vTtrExIU.js → dist-CUeuuHG_.js} +1 -1
- package/dist/assets/dist-CY47RP0T.js +1 -0
- package/dist/assets/dist-D1HV0xoM.js +1 -0
- package/dist/assets/{dist-BZWmfQbq.js → dist-DDhEwFtR.js} +1 -1
- package/dist/assets/{dist-BXnpRw3d.js → dist-DDoTyiJg.js} +1 -1
- package/dist/assets/{dist-DLgWirXg.js → dist-DKmfcej2.js} +1 -1
- package/dist/assets/{dist-Dv0MupEh.js → dist-DPQdWUrU.js} +1 -1
- package/dist/assets/dist-DYjR2ilN.js +1 -0
- package/dist/assets/{dist-8kKeYgOg.js → dist-D_DbFqxl.js} +1 -1
- package/dist/assets/dist-DdDowPeI.js +1 -0
- package/dist/assets/{dist-B83wRp_v.js → dist-Dt1by2kD.js} +1 -1
- package/dist/assets/dist-Dt_gLA9L.js +1 -0
- package/dist/assets/dist-DxWb3aMV.js +13 -0
- package/dist/assets/dist-Dz922FNY.js +1 -0
- package/dist/assets/dist-GRPM_OuL.js +1 -0
- package/dist/assets/{dist-CF4gkF4y.js → dist-K8bI26Ke.js} +1 -1
- package/dist/assets/{dist-Btv5Rh1v.js → dist-LUpffRIq.js} +1 -1
- package/dist/assets/{dist-bBwmhqty.js → dist-MyTWYTLd.js} +4 -4
- package/dist/assets/dist-NOntBqny.js +1 -0
- package/dist/assets/{dist-Dcqqg9UU.js → dist-PzrizfuL.js} +1 -1
- package/dist/assets/{dist-CNW1zLeq.js → dist-dnoBqBf0.js} +1 -1
- package/dist/assets/{dist-CLc5WXWw.js → dist-kjrKkhgz.js} +1 -1
- package/dist/assets/{dist-CoCQUAeM.js → dist-maX8rbyb.js} +1 -1
- package/dist/assets/{documentation-panel-DRZKFCxe.js → documentation-panel-CG2t9UyE.js} +1 -1
- package/dist/assets/{download-DcO8ZTeW.js → download-B6duieQs.js} +1 -1
- package/dist/assets/{edit-page-DFTXtpjP.js → edit-page-ab-pH9y6.js} +7 -7
- package/dist/assets/{error-panel-MncM7IO8.js → error-panel-CDGOPmKx.js} +1 -1
- package/dist/assets/{esm-D82gQH1f.js → esm-BeuExXY6.js} +1 -1
- package/dist/assets/{esm-Bmu2DhPy.js → esm-BqiVbELQ.js} +1 -1
- package/dist/assets/{file-explorer-panel-CIhpYw6d.js → file-explorer-panel-OefSIlIn.js} +1 -1
- package/dist/assets/{floating-outline-D7MmuvBX.js → floating-outline--UenxIj3.js} +1 -1
- package/dist/assets/{focus-Cfq7Qx9L.js → focus-n0WPxeOV.js} +1 -1
- package/dist/assets/{form-D6wq0yzP.js → form-C59_eE2a.js} +1 -1
- package/dist/assets/{globals-D08tPmbM.js → globals-CP-h_Os3.js} +1 -1
- package/dist/assets/{home-page-QeTbaVnU.js → home-page-DnqxPw6c.js} +1 -1
- package/dist/assets/{hooks-cYyUDg3L.js → hooks-cl29HCFx.js} +1 -1
- package/dist/assets/{html-to-image-DTn-asee.js → html-to-image-BXhYNOMC.js} +1 -1
- package/dist/assets/index-B5Sirmey.js +38 -0
- package/dist/assets/{kiosk-mode-DjIsTNjl.js → kiosk-mode-CPN0mq4M.js} +1 -1
- package/dist/assets/{layout-C7QMwOg5.js → layout-ZZ7iNZSi.js} +3 -3
- package/dist/assets/{logs-panel-DSlZEaRL.js → logs-panel-CZIVXROt.js} +1 -1
- package/dist/assets/{markdown-renderer-bMEFR0Vj.js → markdown-renderer-CnImn_qm.js} +1 -1
- package/dist/assets/{mode-DhrLOXrN.js → mode-a9XOBfse.js} +1 -1
- package/dist/assets/{name-cell-input-to4l2uJD.js → name-cell-input-BhJdGpGA.js} +1 -1
- package/dist/assets/{outline-panel-DKBT99sm.js → outline-panel-BGroTTXd.js} +1 -1
- package/dist/assets/{packages-panel-SNt0KIcg.js → packages-panel-CQGOcCdz.js} +1 -1
- package/dist/assets/{panels-CkoN1Cq9.js → panels-B3g436fI.js} +1 -1
- package/dist/assets/{process-output-CdFLcVbk.js → process-output-C4GYMI00.js} +1 -1
- package/dist/assets/{readonly-python-code-LF0diK_w.js → readonly-python-code-BvJmyMxd.js} +1 -1
- package/dist/assets/{run-page-B7sRqeMN.js → run-page-BGmNoipL.js} +1 -1
- package/dist/assets/{scratchpad-panel-SPOKVrq6.js → scratchpad-panel-BH-ZA_0Y.js} +1 -1
- package/dist/assets/{session-panel-DotS45sN.js → session-panel-Co_o0ALo.js} +1 -1
- package/dist/assets/{snippets-panel-tTRfQnC-.js → snippets-panel-Dg7V8q_w.js} +1 -1
- package/dist/assets/{state-zfxByMml.js → state-C-B637hX.js} +1 -1
- package/dist/assets/{switch-CT0cCQMS.js → switch-B-UXYPJj.js} +1 -1
- package/dist/assets/{textarea-e5AWinyy.js → textarea-gBSp2Bx0.js} +1 -1
- package/dist/assets/{tracing-BviqDXIW.js → tracing-Dy8UdLvI.js} +1 -1
- package/dist/assets/{tracing-panel-c7K0vhZ-.js → tracing-panel-BKDVrccB.js} +2 -2
- package/dist/assets/{types-BtZ02GBj.js → types-Cggdh96K.js} +1 -1
- package/dist/assets/{useAddCell-CGoO3J0l.js → useAddCell-CkxiWxI4.js} +1 -1
- package/dist/assets/{useCellActionButton-fszU9atc.js → useCellActionButton-BCYKogBW.js} +1 -1
- package/dist/assets/{useDeleteCell-Du1ML1VC.js → useDeleteCell-CU4wVnMY.js} +1 -1
- package/dist/assets/{useDependencyPanelTab-CU_8jikX.js → useDependencyPanelTab-Dc4i3G5R.js} +1 -1
- package/dist/assets/{useNotebookActions-DTWJT8eH.js → useNotebookActions-CeCCuvJT.js} +1 -1
- package/dist/assets/{useRunCells-CZG2blin.js → useRunCells-DnyQs7_N.js} +1 -1
- package/dist/assets/{useSplitCell-_kUqEKtd.js → useSplitCell-CSr3as14.js} +1 -1
- package/dist/assets/utilities.esm-CW5Mhtfu.js +3 -0
- package/dist/index.html +41 -41
- package/package.json +11 -11
- package/src/components/data-table/TableActions.tsx +8 -1
- package/src/components/data-table/data-table.tsx +2 -0
- package/src/components/data-table/download-actions.tsx +6 -1
- package/src/components/dependency-graph/dependency-graph-tree.tsx +10 -1
- package/src/components/dependency-graph/dependency-graph.tsx +1 -0
- package/src/components/dependency-graph/elements.ts +20 -9
- package/src/components/dependency-graph/panels.tsx +27 -11
- package/src/components/dependency-graph/types.ts +1 -0
- package/src/components/editor/chrome/wrapper/app-chrome.tsx +3 -0
- package/src/components/editor/package-alert.tsx +4 -4
- package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +3 -5
- package/src/core/codemirror/misc/__tests__/paste.test.ts +18 -0
- package/src/core/codemirror/misc/paste.ts +14 -10
- package/src/core/kernel/messages.ts +1 -0
- package/src/core/static/static-state.ts +5 -0
- package/src/core/static/types.ts +2 -0
- package/src/core/wasm/__tests__/store.test.ts +33 -0
- package/src/core/wasm/bridge.ts +2 -1
- package/src/core/wasm/store.ts +13 -1
- package/src/mount.tsx +23 -1
- package/src/plugins/impl/DataTablePlugin.tsx +4 -0
- package/src/plugins/impl/anywidget/AnyWidgetPlugin.tsx +7 -5
- package/src/plugins/impl/anywidget/__tests__/model.test.ts +53 -0
- package/src/plugins/impl/anywidget/model.ts +13 -10
- package/src/plugins/impl/chat/ChatPlugin.tsx +2 -0
- package/src/plugins/impl/chat/chat-ui.tsx +10 -1
- package/src/plugins/impl/data-frames/DataFramePlugin.tsx +4 -0
- package/src/plugins/impl/plotly/Plot.tsx +2 -0
- package/src/plugins/impl/plotly/PlotlyPlugin.tsx +36 -0
- package/src/theme/ThemeProvider.tsx +2 -0
- package/dist/assets/JsonOutput-CWXeFX63.js +0 -46
- package/dist/assets/Plot-CN9AM0tY.js +0 -4030
- package/dist/assets/dependency-graph-panel-BDtbA3R5.js +0 -4
- package/dist/assets/dist-4mAhUzty.js +0 -1
- package/dist/assets/dist-5CXgzdUa.js +0 -1
- package/dist/assets/dist-B27MCO52.js +0 -1
- package/dist/assets/dist-Bc7uxGRW.js +0 -1
- package/dist/assets/dist-BtJZmWkg.js +0 -1
- package/dist/assets/dist-ByjGU_ag.js +0 -1
- package/dist/assets/dist-C-V6lvxH.js +0 -1
- package/dist/assets/dist-C6SivM7z.js +0 -1
- package/dist/assets/dist-C9k2RMmO.js +0 -1
- package/dist/assets/dist-ChS0Dc_R.js +0 -1
- package/dist/assets/dist-CtsanegT.js +0 -2
- package/dist/assets/dist-Cx8mOJOB.js +0 -1
- package/dist/assets/dist-DBwNzi3C.js +0 -13
- package/dist/assets/dist-DOZ8nmkC.js +0 -1
- package/dist/assets/dist-DUlOLsKi.js +0 -1
- package/dist/assets/dist-OlCHPNfN.js +0 -1
- package/dist/assets/dist-Z4EybR_c.js +0 -1
- package/dist/assets/dist-fO1a06Tp.js +0 -1
- package/dist/assets/dist-iXB2pOUD.js +0 -1
- package/dist/assets/dist-lTwzYaMX.js +0 -1
- package/dist/assets/dist-wS1s8MYb.js +0 -1
- package/dist/assets/index-jlWJTe49.js +0 -38
- package/dist/assets/utilities.esm-JjvzgPvo.js +0 -3
|
@@ -31,6 +31,12 @@ vi.mock("@/core/network/requests", () => ({
|
|
|
31
31
|
}),
|
|
32
32
|
}));
|
|
33
33
|
|
|
34
|
+
// Mock isStaticNotebook — default to false (normal mode)
|
|
35
|
+
const mockIsStatic = vi.fn().mockReturnValue(false);
|
|
36
|
+
vi.mock("@/core/static/static-state", () => ({
|
|
37
|
+
isStaticNotebook: () => mockIsStatic(),
|
|
38
|
+
}));
|
|
39
|
+
|
|
34
40
|
// Helper to create a mock MarimoComm
|
|
35
41
|
function createMockComm<T>() {
|
|
36
42
|
return {
|
|
@@ -393,4 +399,51 @@ describe("ModelManager", () => {
|
|
|
393
399
|
|
|
394
400
|
expect(BINDING_MANAGER.has(testId)).toBe(false);
|
|
395
401
|
});
|
|
402
|
+
|
|
403
|
+
describe("static mode", () => {
|
|
404
|
+
beforeEach(() => {
|
|
405
|
+
mockIsStatic.mockReturnValue(true);
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
afterAll(() => {
|
|
409
|
+
mockIsStatic.mockReturnValue(false);
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
it("should create model with no-op comm in static mode", async () => {
|
|
413
|
+
await handleWidgetMessage(modelManager, {
|
|
414
|
+
model_id: testId,
|
|
415
|
+
message: {
|
|
416
|
+
method: "open",
|
|
417
|
+
state: { count: 42 },
|
|
418
|
+
buffer_paths: [],
|
|
419
|
+
buffers: [],
|
|
420
|
+
},
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
const model = await modelManager.get(testId);
|
|
424
|
+
expect(model.get("count")).toBe(42);
|
|
425
|
+
|
|
426
|
+
// save_changes should not call the real request client
|
|
427
|
+
model.set("count", 100);
|
|
428
|
+
model.save_changes();
|
|
429
|
+
expect(mockSendModelValue).not.toHaveBeenCalled();
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
it("should not throw on send in static mode", async () => {
|
|
433
|
+
await handleWidgetMessage(modelManager, {
|
|
434
|
+
model_id: testId,
|
|
435
|
+
message: {
|
|
436
|
+
method: "open",
|
|
437
|
+
state: { count: 0 },
|
|
438
|
+
buffer_paths: [],
|
|
439
|
+
buffers: [],
|
|
440
|
+
},
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
const model = await modelManager.get(testId);
|
|
444
|
+
// send() should silently no-op
|
|
445
|
+
await expect(model.send({ test: true })).resolves.toBeUndefined();
|
|
446
|
+
expect(mockSendModelValue).not.toHaveBeenCalled();
|
|
447
|
+
});
|
|
448
|
+
});
|
|
396
449
|
});
|
|
@@ -5,6 +5,7 @@ import type { AnyModel } from "@anywidget/types";
|
|
|
5
5
|
import { debounce } from "lodash-es";
|
|
6
6
|
import type { NotificationMessageData } from "@/core/kernel/messages";
|
|
7
7
|
import { getRequestClient } from "@/core/network/requests";
|
|
8
|
+
import { isStaticNotebook } from "@/core/static/static-state";
|
|
8
9
|
import {
|
|
9
10
|
decodeFromWire,
|
|
10
11
|
serializeBuffersToBase64,
|
|
@@ -343,12 +344,14 @@ export async function handleWidgetMessage(
|
|
|
343
344
|
return;
|
|
344
345
|
}
|
|
345
346
|
|
|
346
|
-
modelManager.create(
|
|
347
|
-
|
|
348
|
-
(
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
347
|
+
modelManager.create(modelId, (signal) => {
|
|
348
|
+
// In static exports there is no kernel, so comm calls are no-ops.
|
|
349
|
+
const comm: MarimoComm<ModelState> = isStaticNotebook()
|
|
350
|
+
? {
|
|
351
|
+
sendUpdate: async () => undefined,
|
|
352
|
+
sendCustomMessage: async () => undefined,
|
|
353
|
+
}
|
|
354
|
+
: {
|
|
352
355
|
async sendUpdate(changeData) {
|
|
353
356
|
if (signal.aborted) {
|
|
354
357
|
Logger.debug(
|
|
@@ -377,10 +380,10 @@ export async function handleWidgetMessage(
|
|
|
377
380
|
buffers: buffers.map(dataViewToBase64),
|
|
378
381
|
});
|
|
379
382
|
},
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
);
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
return new Model(stateWithBuffers, comm, signal);
|
|
386
|
+
});
|
|
384
387
|
return;
|
|
385
388
|
}
|
|
386
389
|
|
|
@@ -47,6 +47,7 @@ export const ChatPlugin = createPlugin<{ messages: UIMessage[] }>(
|
|
|
47
47
|
maxHeight: z.number().optional(),
|
|
48
48
|
config: configSchema,
|
|
49
49
|
allowAttachments: z.union([z.boolean(), z.string().array()]),
|
|
50
|
+
disabled: z.boolean().default(false),
|
|
50
51
|
}),
|
|
51
52
|
)
|
|
52
53
|
.withFunctions<PluginFunctions>({
|
|
@@ -76,6 +77,7 @@ export const ChatPlugin = createPlugin<{ messages: UIMessage[] }>(
|
|
|
76
77
|
showConfigurationControls={props.data.showConfigurationControls}
|
|
77
78
|
maxHeight={props.data.maxHeight}
|
|
78
79
|
allowAttachments={props.data.allowAttachments}
|
|
80
|
+
disabled={props.data.disabled}
|
|
79
81
|
config={props.data.config}
|
|
80
82
|
get_chat_history={props.functions.get_chat_history}
|
|
81
83
|
delete_chat_history={props.functions.delete_chat_history}
|
|
@@ -67,6 +67,7 @@ interface Props extends PluginFunctions {
|
|
|
67
67
|
showConfigurationControls: boolean;
|
|
68
68
|
maxHeight: number | undefined;
|
|
69
69
|
allowAttachments: boolean | string[];
|
|
70
|
+
disabled: boolean;
|
|
70
71
|
value: UIMessage[];
|
|
71
72
|
setValue: (messages: UIMessage[]) => void;
|
|
72
73
|
host: HTMLElement;
|
|
@@ -450,6 +451,9 @@ export const Chatbot: React.FC<Props> = (props) => {
|
|
|
450
451
|
<form
|
|
451
452
|
onSubmit={async (evt) => {
|
|
452
453
|
evt.preventDefault();
|
|
454
|
+
if (props.disabled) {
|
|
455
|
+
return;
|
|
456
|
+
}
|
|
453
457
|
|
|
454
458
|
const fileParts = files
|
|
455
459
|
? await convertToFileUIPart(files)
|
|
@@ -462,7 +466,12 @@ export const Chatbot: React.FC<Props> = (props) => {
|
|
|
462
466
|
resetInput();
|
|
463
467
|
}}
|
|
464
468
|
ref={formRef}
|
|
465
|
-
|
|
469
|
+
// biome-ignore lint/a11y/useSemanticElements: inert is used to disable the entire form
|
|
470
|
+
inert={props.disabled || undefined}
|
|
471
|
+
className={cn(
|
|
472
|
+
"flex w-full border-t border-(--slate-6) px-2 py-1 items-center",
|
|
473
|
+
props.disabled && "opacity-50 cursor-not-allowed",
|
|
474
|
+
)}
|
|
466
475
|
>
|
|
467
476
|
{props.showConfigurationControls && (
|
|
468
477
|
<ConfigPopup config={config} onChange={setConfig} />
|
|
@@ -48,6 +48,7 @@ type TableData<T> = T[] | CsvURL;
|
|
|
48
48
|
interface Data {
|
|
49
49
|
label?: string | null;
|
|
50
50
|
columns: ColumnDataTypes;
|
|
51
|
+
dataframeName?: string;
|
|
51
52
|
pageSize: number;
|
|
52
53
|
showDownload: boolean;
|
|
53
54
|
lazy: boolean;
|
|
@@ -93,6 +94,7 @@ export const DataFramePlugin = createPlugin<S>("marimo-dataframe")
|
|
|
93
94
|
label: z.string().nullish(),
|
|
94
95
|
pageSize: z.number().default(5),
|
|
95
96
|
showDownload: z.boolean().default(true),
|
|
97
|
+
dataframeName: z.string().optional(),
|
|
96
98
|
columns: z
|
|
97
99
|
.array(z.tuple([z.string().or(z.number()), z.string(), z.string()]))
|
|
98
100
|
.transform((value) => {
|
|
@@ -176,6 +178,7 @@ const EMPTY: Transformations = {
|
|
|
176
178
|
export const DataFrameComponent = memo(
|
|
177
179
|
({
|
|
178
180
|
columns,
|
|
181
|
+
dataframeName,
|
|
179
182
|
pageSize,
|
|
180
183
|
showDownload,
|
|
181
184
|
lazy,
|
|
@@ -326,6 +329,7 @@ export const DataFrameComponent = memo(
|
|
|
326
329
|
fieldTypes={field_types}
|
|
327
330
|
rowHeaders={row_headers || Arrays.EMPTY}
|
|
328
331
|
showDownload={showDownload}
|
|
332
|
+
downloadFileName={dataframeName}
|
|
329
333
|
download_as={download_as}
|
|
330
334
|
enableSearch={false}
|
|
331
335
|
showFilters={false}
|
|
@@ -35,6 +35,7 @@ export interface PlotProps {
|
|
|
35
35
|
onRelayouting?: (event: PlotlyTypes.PlotRelayoutEvent) => void;
|
|
36
36
|
onSelected?: (event: PlotlyTypes.PlotSelectionEvent) => void;
|
|
37
37
|
onDeselect?: () => void;
|
|
38
|
+
onClick?: (event: PlotlyTypes.PlotMouseEvent) => void;
|
|
38
39
|
onSunburstClick?: (event: PlotlyTypes.PlotMouseEvent) => void;
|
|
39
40
|
onTreemapClick?: (event: PlotlyTypes.PlotMouseEvent) => void;
|
|
40
41
|
onError?: (err: Error) => void;
|
|
@@ -48,6 +49,7 @@ const EVENT_NAMES = [
|
|
|
48
49
|
"Relayouting",
|
|
49
50
|
"Selected",
|
|
50
51
|
"Deselect",
|
|
52
|
+
"Click",
|
|
51
53
|
"SunburstClick",
|
|
52
54
|
"TreemapClick",
|
|
53
55
|
] as const;
|
|
@@ -193,6 +193,24 @@ export const PlotlyComponent = memo(
|
|
|
193
193
|
}));
|
|
194
194
|
})}
|
|
195
195
|
config={plotlyConfig}
|
|
196
|
+
onClick={useEvent((evt: Readonly<Plotly.PlotMouseEvent>) => {
|
|
197
|
+
if (!evt) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
// Only handle clicks for chart types where box/lasso selection
|
|
201
|
+
// (onSelected) doesn't work, such as heatmaps.
|
|
202
|
+
const isHeatmap = evt.points.some(
|
|
203
|
+
(point) => point.data?.type === "heatmap",
|
|
204
|
+
);
|
|
205
|
+
if (!isHeatmap) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
setValue((prev) => ({
|
|
209
|
+
...prev,
|
|
210
|
+
points: extractPoints(evt.points),
|
|
211
|
+
indices: evt.points.map((point) => point.pointIndex),
|
|
212
|
+
}));
|
|
213
|
+
})}
|
|
196
214
|
onSelected={useEvent((evt: Readonly<Plotly.PlotSelectionEvent>) => {
|
|
197
215
|
if (!evt) {
|
|
198
216
|
return;
|
|
@@ -224,6 +242,17 @@ PlotlyComponent.displayName = "PlotlyComponent";
|
|
|
224
242
|
* instead of the ones that Plotly uses internally,
|
|
225
243
|
* by using the hovertemplate.
|
|
226
244
|
*/
|
|
245
|
+
const STANDARD_POINT_KEYS: string[] = [
|
|
246
|
+
"x",
|
|
247
|
+
"y",
|
|
248
|
+
"z",
|
|
249
|
+
"lat",
|
|
250
|
+
"lon",
|
|
251
|
+
"curveNumber",
|
|
252
|
+
"pointNumber",
|
|
253
|
+
"pointIndex",
|
|
254
|
+
];
|
|
255
|
+
|
|
227
256
|
function extractPoints(
|
|
228
257
|
points: Plotly.PlotDatum[],
|
|
229
258
|
): Record<AxisName, AxisDatum>[] {
|
|
@@ -238,6 +267,13 @@ function extractPoints(
|
|
|
238
267
|
const hovertemplate = Array.isArray(point.data.hovertemplate)
|
|
239
268
|
? point.data.hovertemplate[0]
|
|
240
269
|
: point.data.hovertemplate;
|
|
270
|
+
|
|
271
|
+
// For chart types with standard point keys (e.g. heatmaps),
|
|
272
|
+
// or when there's no hovertemplate, pick keys directly from the point.
|
|
273
|
+
if (!hovertemplate || point.data?.type === "heatmap") {
|
|
274
|
+
return pick(point, STANDARD_POINT_KEYS);
|
|
275
|
+
}
|
|
276
|
+
|
|
241
277
|
// Update or create a parser
|
|
242
278
|
parser = parser
|
|
243
279
|
? parser.update(hovertemplate)
|
|
@@ -10,8 +10,10 @@ export const ThemeProvider: React.FC<PropsWithChildren> = memo(
|
|
|
10
10
|
const { theme } = useTheme();
|
|
11
11
|
useLayoutEffect(() => {
|
|
12
12
|
document.body.classList.add(theme, `${theme}-theme`);
|
|
13
|
+
document.body.dataset.theme = theme;
|
|
13
14
|
return () => {
|
|
14
15
|
document.body.classList.remove(theme, `${theme}-theme`);
|
|
16
|
+
delete document.body.dataset.theme;
|
|
15
17
|
};
|
|
16
18
|
}, [theme]);
|
|
17
19
|
|