@marimo-team/frontend 0.23.1-dev2 → 0.23.1-dev20
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-CNNGwOIK.js → CellStatus-zTcdYfqx.js} +1 -1
- package/dist/assets/{ConnectedDataExplorerComponent-CfU-ThkK.js → ConnectedDataExplorerComponent-B0Mh-Jhz.js} +1 -1
- package/dist/assets/{ErrorBoundary-dxChUL02.js → ErrorBoundary-CxTq44MI.js} +1 -1
- package/dist/assets/{ImperativeModal-DoGv2BXV.js → ImperativeModal-hsPVDTG-.js} +1 -1
- package/dist/assets/{JsonOutput-D_ORGqdz.js → JsonOutput-CavtrueA.js} +1 -1
- package/dist/assets/{LazyAnyLanguageCodeMirror-CoYqQxHb.js → LazyAnyLanguageCodeMirror-CsrwfW0n.js} +2 -2
- package/dist/assets/{MarimoErrorOutput-Bc9JufDr.js → MarimoErrorOutput-Bmp8DLLo.js} +1 -1
- package/dist/assets/{RSPContexts-LWFBF00h.js → RSPContexts-DzigvqmT.js} +1 -1
- package/dist/assets/RenderHTML-CM3WMmA8.js +1 -0
- package/dist/assets/{add-cell-with-ai-3_AIzd22.js → add-cell-with-ai-_Y6SqxBB.js} +1 -1
- package/dist/assets/{add-connection-dialog-DGgtN73u.js → add-connection-dialog-BGZvJkor.js} +1 -1
- package/dist/assets/{agent-panel-D7gqlew5.js → agent-panel-BvL9Lu9c.js} +1 -1
- package/dist/assets/{ai-model-dropdown-DWOGmhDj.js → ai-model-dropdown-Dyxi3_nW.js} +1 -1
- package/dist/assets/{alert-dialog-CXspBRlP.js → alert-dialog-C2mTH3GM.js} +1 -1
- package/dist/assets/{any-language-editor-DYgTL8eG.js → any-language-editor-DkEDDsUJ.js} +1 -1
- package/dist/assets/{app-config-button-BxCSZCVS.js → app-config-button-BT2Do4RJ.js} +1 -1
- package/dist/assets/button-COIw2x9i.js +1 -0
- package/dist/assets/{cache-panel-8E_Y5OSb.js → cache-panel-C3V9UubH.js} +1 -1
- package/dist/assets/{cell-editor-B2IIBFCB.js → cell-editor-B40o_zx_.js} +1 -1
- package/dist/assets/{cell-link-CcAqXeeg.js → cell-link-CRkrHl-y.js} +1 -1
- package/dist/assets/{cells-EJo3u4za.js → cells-BqYYXi6G.js} +69 -69
- package/dist/assets/{chat-display-DFUo2Riv.js → chat-display-M_nvYuHH.js} +1 -1
- package/dist/assets/{chat-panel-Dl4jq1Dp.js → chat-panel-BMOW93uQ.js} +1 -1
- package/dist/assets/{chat-ui-CysJeVE6.js → chat-ui-DyeimpVh.js} +1 -1
- package/dist/assets/{column-preview-DQBtRWJG.js → column-preview-AfcgbFG_.js} +1 -1
- package/dist/assets/{command-DvF_4mQa.js → command-DnzBp4l4.js} +1 -1
- package/dist/assets/{command-palette-BCrWwbIt.js → command-palette-BgvdyU3B.js} +1 -1
- package/dist/assets/{common-Bty2yo-n.js → common-DeoGL9rK.js} +1 -1
- package/dist/assets/{components-Dh-L-jYg.js → components-CDgxb-5o.js} +1 -1
- package/dist/assets/{components-B8TZ_vT_.js → components-DKHyHZBv.js} +1 -1
- package/dist/assets/{copy-icon-BGs1Pbai.js → copy-icon-Ci08KCdY.js} +1 -1
- package/dist/assets/{datasource-DY0N42ZB.js → datasource-COFRe84u.js} +1 -1
- package/dist/assets/{dependency-graph-panel-C23HsAdh.js → dependency-graph-panel-BXSe6z1R.js} +1 -1
- package/dist/assets/{dialog-BYjetQgE.js → dialog-H-hXtEOq.js} +1 -1
- package/dist/assets/{documentation-panel-okcEKCQM.js → documentation-panel-DUPcsi8P.js} +1 -1
- package/dist/assets/{download-TSo32ofd.js → download-5XbM3TL_.js} +1 -1
- package/dist/assets/edit-page-BDgzn0ig.js +9 -0
- package/dist/assets/{error-banner-bXc_9BBZ.js → error-banner-frvr6JXK.js} +1 -1
- package/dist/assets/{error-panel-aq2j0jIa.js → error-panel-DQOeSv5-.js} +1 -1
- package/dist/assets/{field-DTzXkFLZ.js → field-DaQqUJ5I.js} +1 -1
- package/dist/assets/{file-explorer-panel-bcSqGkbZ.js → file-explorer-panel-B67zjs2X.js} +1 -1
- package/dist/assets/{file-icons-DBaXCICA.js → file-icons-Bj5YoM7H.js} +1 -1
- package/dist/assets/{floating-outline-BTmyhMGv.js → floating-outline-XObNWtN8.js} +1 -1
- package/dist/assets/{focus-DXeddo75.js → focus-DzMo6UAI.js} +1 -1
- package/dist/assets/{form-30oC5z9y.js → form-BJ6VFU8l.js} +1 -1
- package/dist/assets/{gallery-page-XSrY7bw_.js → gallery-page-BDI9wEUZ.js} +1 -1
- package/dist/assets/{glide-data-editor-Bd4FOxvW.js → glide-data-editor-QI6B6uKw.js} +1 -1
- package/dist/assets/{globals-DQM2RvzM.js → globals-Bu6OEURn.js} +1 -1
- package/dist/assets/{home-page-CruHjoHv.js → home-page-BUdd5uTz.js} +1 -1
- package/dist/assets/{hooks-DLUrd-jH.js → hooks-DvwShzDb.js} +1 -1
- package/dist/assets/{html-to-image-BJiJlwQY.js → html-to-image-DGqJ93hW.js} +1 -1
- package/dist/assets/index-C9DyCFTe.js +42 -0
- package/dist/assets/index-CKRn_SiB.css +2 -0
- package/dist/assets/{input-Bg12i6qY.js → input-DNCT6U6R.js} +1 -1
- package/dist/assets/{kiosk-mode-JCcLyeoQ.js → kiosk-mode-DYHoqMaZ.js} +1 -1
- package/dist/assets/layout-erv8pLIP.js +9 -0
- package/dist/assets/{logs-panel-BzhPrie8.js → logs-panel-CRW4c2IL.js} +1 -1
- package/dist/assets/{markdown-renderer-B9RsGqHb.js → markdown-renderer-DNANigO8.js} +1 -1
- package/dist/assets/{mermaid-BJFSZcG6.js → mermaid-BPufPrIN.js} +1 -1
- package/dist/assets/{name-cell-input-CYsY4A1G.js → name-cell-input-3iKP6YTw.js} +1 -1
- package/dist/assets/{outline-panel-BCAWCKi6.js → outline-panel-VIqWcHj6.js} +1 -1
- package/dist/assets/{packages-panel-DxS7zji3.js → packages-panel-D_z4ylBE.js} +1 -1
- package/dist/assets/panels--5tTbFBo.js +1 -0
- package/dist/assets/{process-output-DqiZsqG9.js → process-output-Q6wVr7a-.js} +1 -1
- package/dist/assets/{readonly-python-code-D8ITm60r.js → readonly-python-code-CI_b818F.js} +1 -1
- package/dist/assets/{run-page-CI2eOA-G.js → run-page-DN26u83D.js} +1 -1
- package/dist/assets/{scratchpad-panel-Dwp8-2S1.js → scratchpad-panel-CnaiXtoJ.js} +1 -1
- package/dist/assets/{secrets-panel-C6X5jB8Q.js → secrets-panel-DWMqzwkS.js} +1 -1
- package/dist/assets/{select--zcABebs.js → select-BwwUWhww.js} +1 -1
- package/dist/assets/{session-panel-ryqVmqVd.js → session-panel-C68GBFwH.js} +1 -1
- package/dist/assets/{slides-component-DXMG6OXG.js → slides-component-ncUJNz7U.js} +1 -1
- package/dist/assets/{snippets-panel--mh2FUXA.js → snippets-panel-BmIdR0lc.js} +1 -1
- package/dist/assets/{state-CMxx6hcP.js → state-DAlJ-NbL.js} +1 -1
- package/dist/assets/{state-BDrig0S2.js → state-DPomuurt.js} +1 -1
- package/dist/assets/{switch-C6xjg01T.js → switch-YkPg_CVc.js} +1 -1
- package/dist/assets/{textarea-Cfp3upzK.js → textarea-CS2o3y4W.js} +1 -1
- package/dist/assets/{tracing-BExYhl1z.js → tracing-CPDDwzIA.js} +1 -1
- package/dist/assets/{tracing-panel-Co5DeX-F.js → tracing-panel-Ku1LapXJ.js} +2 -2
- package/dist/assets/{useAddCell-BaTlDxTu.js → useAddCell-B6yUY_RG.js} +1 -1
- package/dist/assets/{useBoolean-BvsK1Xcs.js → useBoolean-Dk1Mb_so.js} +1 -1
- package/dist/assets/{useCellActionButton-DftkIqUl.js → useCellActionButton-SxeK4dmW.js} +1 -1
- package/dist/assets/{useDeleteCell-d6yWnL3H.js → useDeleteCell-DHUjJQJx.js} +1 -1
- package/dist/assets/{useDependencyPanelTab-BaVcOBM4.js → useDependencyPanelTab-CflgayoH.js} +1 -1
- package/dist/assets/{useNotebookActions-D8Dm93y8.js → useNotebookActions-Ch1o32Jw.js} +1 -1
- package/dist/assets/{useRunCells-d2edY6Tu.js → useRunCells-DFYAOTWd.js} +1 -1
- package/dist/assets/{useSplitCell-DOiFyMgH.js → useSplitCell-Bh-NZsBl.js} +1 -1
- package/dist/assets/{vega-component-CiVPyAwP.js → vega-component-DtSTT5wO.js} +1 -1
- package/dist/assets/{write-secret-modal-CHfFN0H8.js → write-secret-modal-CInxHVWJ.js} +1 -1
- package/dist/index.html +39 -39
- package/package.json +1 -1
- package/src/components/editor/renderers/slides-layout/slides-layout.tsx +50 -44
- package/src/components/slides/__tests__/minimap.test.ts +402 -0
- package/src/components/slides/minimap.tsx +534 -0
- package/src/components/slides/slide.tsx +29 -0
- package/src/components/slides/slides-component.tsx +16 -1
- package/src/components/ui/button.tsx +1 -2
- package/src/core/cells/__tests__/cells.test.ts +105 -1
- package/src/core/cells/cells.ts +43 -0
- package/src/core/cells/document-changes.ts +2 -1
- package/src/plugins/core/RenderHTML.tsx +9 -0
- package/src/plugins/core/__test__/RenderHTML.test.ts +27 -0
- package/src/plugins/core/registerReactComponent.tsx +11 -8
- package/src/plugins/impl/ButtonPlugin.tsx +4 -6
- package/src/plugins/impl/CodeEditorPlugin.tsx +15 -18
- package/src/plugins/impl/DataEditorPlugin.tsx +8 -14
- package/src/plugins/impl/DataTablePlugin.tsx +1 -6
- package/src/plugins/impl/FileUploadPlugin.tsx +39 -43
- package/src/plugins/impl/FormPlugin.tsx +2 -6
- package/src/plugins/impl/chat/ChatPlugin.tsx +17 -20
- package/src/plugins/impl/data-explorer/DataExplorerPlugin.tsx +5 -8
- package/src/plugins/impl/matplotlib/matplotlib-renderer.ts +38 -14
- package/src/plugins/impl/vega/VegaPlugin.tsx +5 -8
- package/src/plugins/layout/NavigationMenuPlugin.tsx +2 -6
- package/src/utils/__tests__/events.test.ts +223 -0
- package/src/utils/events.ts +28 -14
- package/dist/assets/RenderHTML-0dk6-mYI.js +0 -1
- package/dist/assets/button-BKVLeSTX.js +0 -1
- package/dist/assets/edit-page-fl9KJOcI.js +0 -13
- package/dist/assets/index-DTBKKey_.js +0 -42
- package/dist/assets/index-qO0a4zuT.css +0 -2
- package/dist/assets/layout-cq-nxDfO.js +0 -5
- package/dist/assets/panels-B5BFPT3k.js +0 -1
|
@@ -22,7 +22,11 @@ import { foldAllBulk, unfoldAllBulk } from "@/core/codemirror/editing/commands";
|
|
|
22
22
|
import { adaptiveLanguageConfiguration } from "@/core/codemirror/language/extension";
|
|
23
23
|
import { OverridingHotkeyProvider } from "@/core/hotkeys/hotkeys";
|
|
24
24
|
import type { OutputMessage } from "@/core/kernel/messages";
|
|
25
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
type CollapsibleTree,
|
|
27
|
+
MultiColumn,
|
|
28
|
+
type CellColumnId,
|
|
29
|
+
} from "@/utils/id-tree";
|
|
26
30
|
import type { Seconds } from "@/utils/time";
|
|
27
31
|
import {
|
|
28
32
|
exportedForTesting,
|
|
@@ -495,6 +499,106 @@ describe("cell reducer", () => {
|
|
|
495
499
|
`);
|
|
496
500
|
});
|
|
497
501
|
|
|
502
|
+
it("can move a cell to an exact index within a column", () => {
|
|
503
|
+
actions.createNewCell({
|
|
504
|
+
cellId: firstCellId,
|
|
505
|
+
before: false,
|
|
506
|
+
});
|
|
507
|
+
actions.createNewCell({
|
|
508
|
+
cellId: cellId("1"),
|
|
509
|
+
before: false,
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
const columnId = state.cellIds.atOrThrow(0).id;
|
|
513
|
+
actions.moveCellToIndex({
|
|
514
|
+
cellId: firstCellId,
|
|
515
|
+
columnId,
|
|
516
|
+
index: 3,
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
520
|
+
"
|
|
521
|
+
[1] ''
|
|
522
|
+
|
|
523
|
+
[2] ''
|
|
524
|
+
|
|
525
|
+
[0] ''
|
|
526
|
+
"
|
|
527
|
+
`);
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
it("can move a cell to an exact index across columns", () => {
|
|
531
|
+
actions.createNewCell({
|
|
532
|
+
cellId: firstCellId,
|
|
533
|
+
before: false,
|
|
534
|
+
});
|
|
535
|
+
actions.createNewCell({
|
|
536
|
+
cellId: cellId("1"),
|
|
537
|
+
before: false,
|
|
538
|
+
});
|
|
539
|
+
actions.addColumnBreakpoint({ cellId: cellId("1") });
|
|
540
|
+
|
|
541
|
+
const secondColumnId = state.cellIds.atOrThrow(1).id;
|
|
542
|
+
actions.moveCellToIndex({
|
|
543
|
+
cellId: firstCellId,
|
|
544
|
+
columnId: secondColumnId,
|
|
545
|
+
index: 1,
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
expect(formatCells(state)).toMatchInlineSnapshot(`
|
|
549
|
+
"
|
|
550
|
+
> col 0
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
> col 1
|
|
554
|
+
[1] ''
|
|
555
|
+
|
|
556
|
+
[0] ''
|
|
557
|
+
|
|
558
|
+
[2] ''
|
|
559
|
+
"
|
|
560
|
+
`);
|
|
561
|
+
});
|
|
562
|
+
|
|
563
|
+
it("moveCellToIndex is a no-op when moving to the same position", () => {
|
|
564
|
+
actions.createNewCell({
|
|
565
|
+
cellId: firstCellId,
|
|
566
|
+
before: false,
|
|
567
|
+
});
|
|
568
|
+
actions.createNewCell({
|
|
569
|
+
cellId: cellId("1"),
|
|
570
|
+
before: false,
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
const columnId = state.cellIds.atOrThrow(0).id;
|
|
574
|
+
const before = formatCells(state);
|
|
575
|
+
|
|
576
|
+
actions.moveCellToIndex({
|
|
577
|
+
cellId: firstCellId,
|
|
578
|
+
columnId,
|
|
579
|
+
index: 0,
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
expect(formatCells(state)).toBe(before);
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
it("moveCellToIndex is a no-op for an invalid columnId", () => {
|
|
586
|
+
actions.createNewCell({
|
|
587
|
+
cellId: firstCellId,
|
|
588
|
+
before: false,
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
const before = formatCells(state);
|
|
592
|
+
|
|
593
|
+
actions.moveCellToIndex({
|
|
594
|
+
cellId: firstCellId,
|
|
595
|
+
columnId: "nonexistent-column" as CellColumnId,
|
|
596
|
+
index: 0,
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
expect(formatCells(state)).toBe(before);
|
|
600
|
+
});
|
|
601
|
+
|
|
498
602
|
it("can run cell and receive cell messages", () => {
|
|
499
603
|
// HAPPY PATH
|
|
500
604
|
/////////////////
|
package/src/core/cells/cells.ts
CHANGED
|
@@ -338,6 +338,49 @@ const {
|
|
|
338
338
|
scrollKey: cellId,
|
|
339
339
|
};
|
|
340
340
|
},
|
|
341
|
+
moveCellToIndex: (
|
|
342
|
+
state,
|
|
343
|
+
action: {
|
|
344
|
+
cellId: CellId;
|
|
345
|
+
columnId: CellColumnId;
|
|
346
|
+
index: number;
|
|
347
|
+
},
|
|
348
|
+
) => {
|
|
349
|
+
const { cellId, columnId, index } = action;
|
|
350
|
+
const fromColumn = state.cellIds.findWithId(cellId);
|
|
351
|
+
const fromIndex = fromColumn.indexOfOrThrow(cellId);
|
|
352
|
+
|
|
353
|
+
const destinationColumn = state.cellIds.get(columnId);
|
|
354
|
+
if (!destinationColumn) {
|
|
355
|
+
return state;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
const clampedIndex = Math.max(0, Math.min(index, destinationColumn.length));
|
|
359
|
+
const adjustedIndex =
|
|
360
|
+
fromColumn.id === columnId && fromIndex < clampedIndex
|
|
361
|
+
? clampedIndex - 1
|
|
362
|
+
: clampedIndex;
|
|
363
|
+
|
|
364
|
+
if (fromColumn.id === columnId && fromIndex === adjustedIndex) {
|
|
365
|
+
return state;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
const withoutCell = state.cellIds.deleteById(cellId);
|
|
369
|
+
const updatedColumn = withoutCell.get(columnId);
|
|
370
|
+
if (!updatedColumn) {
|
|
371
|
+
return state;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
return {
|
|
375
|
+
...state,
|
|
376
|
+
cellIds: withoutCell.insertId(
|
|
377
|
+
cellId,
|
|
378
|
+
columnId,
|
|
379
|
+
Math.max(0, Math.min(adjustedIndex, updatedColumn.length)),
|
|
380
|
+
),
|
|
381
|
+
scrollKey: null,
|
|
382
|
+
};
|
|
383
|
+
},
|
|
341
384
|
dropCellOverCell: (state, action: { cellId: CellId; overCellId: CellId }) => {
|
|
342
385
|
const { cellId, overCellId } = action;
|
|
343
386
|
|
|
@@ -215,12 +215,13 @@ export function toDocumentChanges(
|
|
|
215
215
|
];
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
// dropCellOverCell/dropCellOverColumn → set-config + reorder-cells
|
|
218
|
+
// dropCellOverCell/dropCellOverColumn/moveCellToIndex → set-config + reorder-cells
|
|
219
219
|
// Drag-and-drop reorders can move cells within or across columns.
|
|
220
220
|
// We emit config changes for cells whose column changed, then
|
|
221
221
|
// the full ordering.
|
|
222
222
|
case "dropCellOverCell":
|
|
223
223
|
case "dropCellOverColumn":
|
|
224
|
+
case "moveCellToIndex":
|
|
224
225
|
return columnChanges(prevState, newState);
|
|
225
226
|
|
|
226
227
|
// updateCellCode → set-code
|
|
@@ -164,11 +164,20 @@ const wrapDocHoverTargets: TransformFn = (
|
|
|
164
164
|
// Wrap elements with data-tooltip attribute in a Tooltip component.
|
|
165
165
|
// This renders the tooltip in a portal (top layer), fixing clipping inside
|
|
166
166
|
// containers with overflow:hidden (e.g. grid cells).
|
|
167
|
+
//
|
|
168
|
+
// Marimo custom elements (marimo-button, etc.) are skipped — they handle
|
|
169
|
+
// tooltips via the plugin system inside their Shadow DOM. Wrapping them here
|
|
170
|
+
// would create a duplicate tooltip with incorrect positioning and
|
|
171
|
+
// un-decoded JSON content (the data-* value is JSON-encoded by the backend).
|
|
167
172
|
const wrapTooltipTargets: TransformFn = (
|
|
168
173
|
reactNode: ReactNode,
|
|
169
174
|
domNode: DOMNode,
|
|
170
175
|
): JSX.Element | undefined => {
|
|
171
176
|
if (domNode instanceof Element && domNode.attribs?.["data-tooltip"]) {
|
|
177
|
+
const tagName = domNode.name?.toLowerCase() ?? "";
|
|
178
|
+
if (tagName.startsWith("marimo-")) {
|
|
179
|
+
return undefined;
|
|
180
|
+
}
|
|
172
181
|
const tooltipContent = domNode.attribs["data-tooltip"];
|
|
173
182
|
return (
|
|
174
183
|
<Tooltip content={tooltipContent}>{reactNode as JSX.Element}</Tooltip>
|
|
@@ -240,6 +240,33 @@ describe("wrapTooltipTargets", () => {
|
|
|
240
240
|
</p>
|
|
241
241
|
`);
|
|
242
242
|
});
|
|
243
|
+
|
|
244
|
+
test("data-tooltip on marimo custom elements is not wrapped", () => {
|
|
245
|
+
const html =
|
|
246
|
+
'<marimo-button data-tooltip=""Run clicky"">click</marimo-button>';
|
|
247
|
+
expect(parseHtml({ html })).toMatchInlineSnapshot(`
|
|
248
|
+
<marimo-button
|
|
249
|
+
data-tooltip=""Run clicky""
|
|
250
|
+
>
|
|
251
|
+
click
|
|
252
|
+
</marimo-button>
|
|
253
|
+
`);
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
test("data-tooltip on non-marimo custom elements is still wrapped", () => {
|
|
257
|
+
const html = '<my-widget data-tooltip="info">content</my-widget>';
|
|
258
|
+
expect(parseHtml({ html })).toMatchInlineSnapshot(`
|
|
259
|
+
<Tooltip
|
|
260
|
+
content="info"
|
|
261
|
+
>
|
|
262
|
+
<my-widget
|
|
263
|
+
data-tooltip="info"
|
|
264
|
+
>
|
|
265
|
+
content
|
|
266
|
+
</my-widget>
|
|
267
|
+
</Tooltip>
|
|
268
|
+
`);
|
|
269
|
+
});
|
|
243
270
|
});
|
|
244
271
|
|
|
245
272
|
describe("parseHtml with < nad >", () => {
|
|
@@ -23,6 +23,7 @@ import React, {
|
|
|
23
23
|
import ReactDOM, { type Root } from "react-dom/client";
|
|
24
24
|
import useEvent from "react-use-event-hook";
|
|
25
25
|
import { type ZodSchema, z } from "zod";
|
|
26
|
+
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
26
27
|
import { notebookAtom } from "@/core/cells/cells.ts";
|
|
27
28
|
import { HTMLCellId } from "@/core/cells/ids.ts";
|
|
28
29
|
import { isUninstantiated } from "@/core/cells/utils";
|
|
@@ -250,14 +251,16 @@ function PluginSlotInternal<T>(
|
|
|
250
251
|
<StyleNamespace>
|
|
251
252
|
<div className={`contents ${theme}`}>
|
|
252
253
|
<Suspense fallback={<div />}>
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
254
|
+
<TooltipProvider>
|
|
255
|
+
{plugin.render({
|
|
256
|
+
setValue: setValueAndSendInput,
|
|
257
|
+
value,
|
|
258
|
+
data: parsedResult.data,
|
|
259
|
+
children: childNodes,
|
|
260
|
+
host: hostElement,
|
|
261
|
+
functions: functionMethods,
|
|
262
|
+
})}
|
|
263
|
+
</TooltipProvider>
|
|
261
264
|
</Suspense>
|
|
262
265
|
</div>
|
|
263
266
|
</StyleNamespace>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import type { JSX } from "react";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import { KeyboardHotkeys } from "@/components/shortcuts/renderShortcut";
|
|
6
|
-
import { Tooltip
|
|
6
|
+
import { Tooltip } from "@/components/ui/tooltip";
|
|
7
7
|
import { cn } from "@/utils/cn";
|
|
8
8
|
import { Button } from "../../components/ui/button";
|
|
9
9
|
import { renderHTML } from "../core/RenderHTML";
|
|
@@ -69,11 +69,9 @@ export class ButtonPlugin implements IPlugin<number, Data> {
|
|
|
69
69
|
|
|
70
70
|
if (tooltipContent) {
|
|
71
71
|
return (
|
|
72
|
-
<
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
</Tooltip>
|
|
76
|
-
</TooltipProvider>
|
|
72
|
+
<Tooltip content={tooltipContent} delayDuration={200}>
|
|
73
|
+
{button}
|
|
74
|
+
</Tooltip>
|
|
77
75
|
);
|
|
78
76
|
}
|
|
79
77
|
|
|
@@ -4,7 +4,6 @@ import { EditorView } from "@codemirror/view";
|
|
|
4
4
|
import { type JSX, useEffect, useMemo, useState } from "react";
|
|
5
5
|
import useEvent from "react-use-event-hook";
|
|
6
6
|
import { z } from "zod";
|
|
7
|
-
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
8
7
|
import { useDebounceControlledState } from "@/hooks/useDebounce";
|
|
9
8
|
import { type Theme, useTheme } from "@/theme/useTheme";
|
|
10
9
|
import type { IPlugin, IPluginProps, Setter } from "../types";
|
|
@@ -98,22 +97,20 @@ const CodeEditorComponent = (props: CodeEditorComponentProps) => {
|
|
|
98
97
|
}, [props.debounce, onBlur]);
|
|
99
98
|
|
|
100
99
|
return (
|
|
101
|
-
<
|
|
102
|
-
<
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
</Labeled>
|
|
117
|
-
</TooltipProvider>
|
|
100
|
+
<Labeled label={props.label} align="top" fullWidth={true}>
|
|
101
|
+
<LazyAnyLanguageCodeMirror
|
|
102
|
+
className={`cm *:outline-hidden border rounded overflow-hidden ${finalTheme}`}
|
|
103
|
+
theme={finalTheme === "dark" ? "dark" : "light"}
|
|
104
|
+
minHeight={minHeight}
|
|
105
|
+
maxHeight={maxHeight}
|
|
106
|
+
placeholder={props.placeholder}
|
|
107
|
+
editable={!props.disabled}
|
|
108
|
+
value={localValue}
|
|
109
|
+
language={props.language}
|
|
110
|
+
onChange={handleChange}
|
|
111
|
+
showCopyButton={props.showCopyButton}
|
|
112
|
+
extensions={extensions}
|
|
113
|
+
/>
|
|
114
|
+
</Labeled>
|
|
118
115
|
);
|
|
119
116
|
};
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
3
|
import glideCss from "@glideapps/glide-data-grid/dist/index.css?inline";
|
|
4
|
-
import { Tooltip } from "radix-ui";
|
|
5
|
-
|
|
6
|
-
const TooltipProvider = Tooltip.Provider;
|
|
7
|
-
|
|
8
4
|
import React, { useState } from "react";
|
|
9
5
|
import { z } from "zod";
|
|
10
6
|
import { inferFieldTypes } from "@/components/data-table/columns";
|
|
@@ -63,16 +59,14 @@ export const DataEditorPlugin = createPlugin<Edits>("marimo-data-editor", {
|
|
|
63
59
|
.withFunctions({})
|
|
64
60
|
.renderer((props) => {
|
|
65
61
|
return (
|
|
66
|
-
<
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
/>
|
|
75
|
-
</TooltipProvider>
|
|
62
|
+
<LoadingDataEditor
|
|
63
|
+
data={props.data.data}
|
|
64
|
+
fieldTypes={props.data.fieldTypes}
|
|
65
|
+
edits={props.value}
|
|
66
|
+
onEdits={props.setValue}
|
|
67
|
+
host={props.host}
|
|
68
|
+
editableColumns={props.data.editableColumns}
|
|
69
|
+
/>
|
|
76
70
|
);
|
|
77
71
|
});
|
|
78
72
|
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
3
|
import { Provider as SlotzProvider } from "@marimo-team/react-slotz";
|
|
4
|
-
import { Tooltip } from "radix-ui";
|
|
5
|
-
|
|
6
|
-
const TooltipProvider = Tooltip.Provider;
|
|
7
4
|
|
|
8
5
|
import type {
|
|
9
6
|
ColumnFiltersState,
|
|
@@ -1123,9 +1120,7 @@ export const TableProviders: React.FC<{ children: React.ReactNode }> = ({
|
|
|
1123
1120
|
return (
|
|
1124
1121
|
<ErrorBoundary>
|
|
1125
1122
|
<Provider store={store}>
|
|
1126
|
-
<SlotzProvider controller={slotsController}>
|
|
1127
|
-
<TooltipProvider>{children}</TooltipProvider>
|
|
1128
|
-
</SlotzProvider>
|
|
1123
|
+
<SlotzProvider controller={slotsController}>{children}</SlotzProvider>
|
|
1129
1124
|
</Provider>
|
|
1130
1125
|
</ErrorBoundary>
|
|
1131
1126
|
);
|
|
@@ -4,7 +4,7 @@ import { MousePointerSquareDashedIcon, Upload } from "lucide-react";
|
|
|
4
4
|
import type { JSX } from "react";
|
|
5
5
|
import { useDropzone } from "react-dropzone";
|
|
6
6
|
import { z } from "zod";
|
|
7
|
-
import { Tooltip
|
|
7
|
+
import { Tooltip } from "@/components/ui/tooltip";
|
|
8
8
|
import { toast } from "@/components/ui/use-toast";
|
|
9
9
|
import { cn } from "@/utils/cn";
|
|
10
10
|
import { Logger } from "@/utils/Logger";
|
|
@@ -184,42 +184,40 @@ export const FileUpload = (props: FileUploadProps): JSX.Element => {
|
|
|
184
184
|
// link button to the hidden input element
|
|
185
185
|
const label = props.label ?? "Upload";
|
|
186
186
|
return (
|
|
187
|
-
<
|
|
188
|
-
<
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
<
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
{value.length} {value.length === 1 ? "file" : "files"}.
|
|
208
|
-
</span>
|
|
187
|
+
<div className="flex flex-row items-center justify-start gap-2">
|
|
188
|
+
<button
|
|
189
|
+
data-testid="marimo-plugin-file-upload-button"
|
|
190
|
+
{...getRootProps({})}
|
|
191
|
+
className={buttonVariants({
|
|
192
|
+
variant: "secondary",
|
|
193
|
+
size: "xs",
|
|
194
|
+
})}
|
|
195
|
+
>
|
|
196
|
+
{renderHTML({ html: label })}
|
|
197
|
+
<Upload size={14} className="ml-2" />
|
|
198
|
+
</button>
|
|
199
|
+
<input {...getInputProps({})} type="file" />
|
|
200
|
+
{uploaded ? (
|
|
201
|
+
<>
|
|
202
|
+
<Tooltip content={uploadedFiles}>
|
|
203
|
+
<span className="text-xs text-muted-foreground">
|
|
204
|
+
Uploaded{" "}
|
|
205
|
+
<span className="underline cursor-pointer">
|
|
206
|
+
{value.length} {value.length === 1 ? "file" : "files"}.
|
|
209
207
|
</span>
|
|
210
|
-
</
|
|
208
|
+
</span>
|
|
209
|
+
</Tooltip>
|
|
211
210
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
</TooltipProvider>
|
|
211
|
+
<button
|
|
212
|
+
className={cn("text-xs text-destructive hover:underline")}
|
|
213
|
+
onClick={() => setValue([])}
|
|
214
|
+
type="button"
|
|
215
|
+
>
|
|
216
|
+
Click to clear files.
|
|
217
|
+
</button>
|
|
218
|
+
</>
|
|
219
|
+
) : null}
|
|
220
|
+
</div>
|
|
223
221
|
);
|
|
224
222
|
}
|
|
225
223
|
|
|
@@ -274,14 +272,12 @@ export const FileUpload = (props: FileUploadProps): JSX.Element => {
|
|
|
274
272
|
{uploaded ? (
|
|
275
273
|
<div className="flex flex-row gap-1">
|
|
276
274
|
<div className="text-xs text-muted-foreground">
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
<
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
</Tooltip>
|
|
284
|
-
</TooltipProvider>
|
|
275
|
+
Uploaded{" "}
|
|
276
|
+
<Tooltip content={uploadedFiles}>
|
|
277
|
+
<span className="underline cursor-pointer">
|
|
278
|
+
{value.length} {value.length === 1 ? "file" : "files"}.
|
|
279
|
+
</span>
|
|
280
|
+
</Tooltip>
|
|
285
281
|
</div>
|
|
286
282
|
<span className="text-xs text-destructive hover:underline hover:cursor-pointer">
|
|
287
283
|
<button
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { Loader2Icon } from "lucide-react";
|
|
4
4
|
import { type JSX, useEffect, useRef, useState } from "react";
|
|
5
5
|
import { z } from "zod";
|
|
6
|
-
import { Tooltip
|
|
6
|
+
import { Tooltip } from "@/components/ui/tooltip";
|
|
7
7
|
import type { UIElementId } from "@/core/cells/ids";
|
|
8
8
|
import {
|
|
9
9
|
MarimoValueInputEvent,
|
|
@@ -72,11 +72,7 @@ export const FormPlugin = createPlugin("marimo-form")
|
|
|
72
72
|
.output(z.string().nullish()),
|
|
73
73
|
})
|
|
74
74
|
.renderer(({ data, functions, ...rest }) => {
|
|
75
|
-
return
|
|
76
|
-
<TooltipProvider>
|
|
77
|
-
<Form {...data} {...rest} {...functions} />
|
|
78
|
-
</TooltipProvider>
|
|
79
|
-
);
|
|
75
|
+
return <Form {...data} {...rest} {...functions} />;
|
|
80
76
|
});
|
|
81
77
|
|
|
82
78
|
export interface FormWrapperProps<T>
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
import type { UIMessage } from "ai";
|
|
4
4
|
import React, { Suspense } from "react";
|
|
5
5
|
import { z } from "zod";
|
|
6
|
-
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
7
6
|
import { createPlugin } from "@/plugins/core/builder";
|
|
8
7
|
import { rpc } from "@/plugins/core/rpc";
|
|
9
8
|
import { Arrays } from "@/utils/arrays";
|
|
@@ -73,23 +72,21 @@ export const ChatPlugin = createPlugin<{ messages: UIMessage[] }>(
|
|
|
73
72
|
.output(z.unknown()),
|
|
74
73
|
})
|
|
75
74
|
.renderer((props) => (
|
|
76
|
-
<
|
|
77
|
-
<
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
</Suspense>
|
|
94
|
-
</TooltipProvider>
|
|
75
|
+
<Suspense>
|
|
76
|
+
<LazyChatbot
|
|
77
|
+
prompts={props.data.prompts}
|
|
78
|
+
showConfigurationControls={props.data.showConfigurationControls}
|
|
79
|
+
maxHeight={props.data.maxHeight}
|
|
80
|
+
allowAttachments={props.data.allowAttachments}
|
|
81
|
+
disabled={props.data.disabled}
|
|
82
|
+
config={props.data.config}
|
|
83
|
+
get_chat_history={props.functions.get_chat_history}
|
|
84
|
+
delete_chat_history={props.functions.delete_chat_history}
|
|
85
|
+
delete_chat_message={props.functions.delete_chat_message}
|
|
86
|
+
send_prompt={props.functions.send_prompt}
|
|
87
|
+
value={props.value?.messages || Arrays.EMPTY}
|
|
88
|
+
setValue={(messages) => props.setValue({ messages })}
|
|
89
|
+
host={props.host}
|
|
90
|
+
/>
|
|
91
|
+
</Suspense>
|
|
95
92
|
));
|
|
@@ -3,7 +3,6 @@ import "../vega/vega.css";
|
|
|
3
3
|
|
|
4
4
|
import React from "react";
|
|
5
5
|
import { z } from "zod";
|
|
6
|
-
import { TooltipProvider } from "@/components/ui/tooltip";
|
|
7
6
|
import { createPlugin } from "@/plugins/core/builder";
|
|
8
7
|
import type { DataExplorerState } from "./ConnectedDataExplorerComponent";
|
|
9
8
|
|
|
@@ -21,11 +20,9 @@ export const DataExplorerPlugin = createPlugin<DataExplorerState>(
|
|
|
21
20
|
}),
|
|
22
21
|
)
|
|
23
22
|
.renderer((props) => (
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
/>
|
|
30
|
-
</TooltipProvider>
|
|
23
|
+
<LazyDataExplorerComponent
|
|
24
|
+
{...props.data}
|
|
25
|
+
value={props.value}
|
|
26
|
+
setValue={props.setValue}
|
|
27
|
+
/>
|
|
31
28
|
));
|