@marimo-team/islands 0.23.15-dev33 → 0.23.15-dev5

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.
Files changed (85) hide show
  1. package/dist/{ConnectedDataExplorerComponent-7p7rt9iw.js → ConnectedDataExplorerComponent-CU4fZJzG.js} +4 -4
  2. package/dist/{ErrorBoundary-B_CAG7_e.js → ErrorBoundary-DE6tzZf-.js} +1 -1
  3. package/dist/{ImageComparisonComponent-1i5IBhon.js → ImageComparisonComponent-CHrI72em.js} +129 -173
  4. package/dist/assets/__vite-browser-external-BQCLNwri.js +1 -0
  5. package/dist/assets/worker-DAWRHcPq.js +73 -0
  6. package/dist/{chat-ui-C0wkSwxB.js → chat-ui-DinOvbWu.js} +3111 -3111
  7. package/dist/{code-visibility-BI94mK4u.js → code-visibility-DBuB5MVY.js} +864 -946
  8. package/dist/{debounce-BOD3DbfP.js → constants-T20xxyNf.js} +24 -1
  9. package/dist/{formats-BX3uDQbB.js → formats-Dzx4J_z1.js} +1 -1
  10. package/dist/{glide-data-editor-CwZz71BD.js → glide-data-editor-CjTu7ukN.js} +3 -3
  11. package/dist/{html-to-image-D8Q5SLSJ.js → html-to-image-_wGfk8V-.js} +2241 -2277
  12. package/dist/{input-BGPrFH3g.js → input-DtsN7xm-.js} +2 -2
  13. package/dist/main.js +1201 -1297
  14. package/dist/{mermaid-UdmxG2PZ.js → mermaid-BYqXy_NE.js} +2 -2
  15. package/dist/{process-output-C_A12w9J.js → process-output-Mh4UrjwM.js} +1 -1
  16. package/dist/{reveal-component-ELidGmPF.js → reveal-component-DfOZrkd6.js} +605 -618
  17. package/dist/{spec-DSs9v0xx.js → spec-Cz-Bj1JI.js} +1 -1
  18. package/dist/style.css +1 -1
  19. package/dist/{toDate-CKpRx4TS.js → toDate-CWNNlFEX.js} +4 -3
  20. package/dist/{useAsyncData-BSOyAbac.js → useAsyncData-KfHB8wQR.js} +1 -1
  21. package/dist/{useDeepCompareMemoize-BTLeWzuR.js → useDeepCompareMemoize-nJMtxhm4.js} +1 -1
  22. package/dist/{useLifecycle-C6wHjkhW.js → useLifecycle-DegSo0lV.js} +1 -1
  23. package/dist/{useTheme-Df_vGflw.js → useTheme-6eZ3GOTS.js} +27 -62
  24. package/dist/{vega-component-DNHEV0u0.js → vega-component-DzyyM9fc.js} +6 -6
  25. package/package.json +1 -1
  26. package/src/components/chat/__tests__/chat-utils.test.ts +1 -244
  27. package/src/components/chat/chat-panel.tsx +67 -196
  28. package/src/components/chat/chat-utils.ts +2 -111
  29. package/src/components/editor/SortableCell.tsx +2 -6
  30. package/src/components/editor/actions/pair-with-agent-modal.tsx +64 -20
  31. package/src/components/editor/ai/add-cell-with-ai.tsx +5 -14
  32. package/src/components/editor/ai/ai-completion-editor.tsx +1 -4
  33. package/src/components/editor/cell/cell-context-menu.tsx +0 -7
  34. package/src/components/editor/chrome/panels/packages-panel.tsx +1 -11
  35. package/src/components/editor/columns/cell-column.tsx +4 -34
  36. package/src/components/editor/columns/sortable-column.tsx +4 -24
  37. package/src/components/editor/navigation/__tests__/navigation.test.ts +0 -33
  38. package/src/components/editor/navigation/navigation.ts +1 -8
  39. package/src/components/editor/notebook-cell.tsx +106 -203
  40. package/src/components/editor/renderers/cell-array.tsx +13 -26
  41. package/src/components/editor/renderers/cells-renderer.tsx +2 -8
  42. package/src/components/editor/renderers/slides-layout/__tests__/plugin.test.ts +0 -29
  43. package/src/components/editor/renderers/slides-layout/types.ts +0 -4
  44. package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +19 -19
  45. package/src/components/slides/reveal-component.tsx +4 -37
  46. package/src/components/slides/slide-form.tsx +0 -72
  47. package/src/core/cells/__tests__/utils.test.ts +0 -59
  48. package/src/core/cells/utils.ts +0 -51
  49. package/src/core/codemirror/completion/__tests__/signature-hint.test.ts +3 -97
  50. package/src/core/codemirror/completion/signature-hint.ts +11 -78
  51. package/src/core/constants.ts +0 -6
  52. package/src/core/islands/__tests__/bridge.test.ts +46 -341
  53. package/src/core/islands/__tests__/parse.test.ts +0 -105
  54. package/src/core/islands/bootstrap.ts +3 -8
  55. package/src/core/islands/bridge.ts +23 -116
  56. package/src/core/islands/components/web-components.tsx +15 -76
  57. package/src/core/islands/constants.ts +0 -1
  58. package/src/core/islands/main.ts +3 -69
  59. package/src/core/islands/parse.ts +23 -70
  60. package/src/core/islands/worker/worker.tsx +57 -145
  61. package/src/core/wasm/worker/bootstrap.ts +20 -113
  62. package/src/css/app/Cell.css +0 -10
  63. package/src/hooks/useHotkey.ts +4 -29
  64. package/src/plugins/impl/anywidget/__tests__/host.test.ts +9 -6
  65. package/src/plugins/impl/anywidget/__tests__/widget-binding.test.ts +61 -22
  66. package/src/plugins/impl/anywidget/model-proxy.ts +13 -0
  67. package/src/plugins/impl/anywidget/widget-binding.ts +34 -4
  68. package/src/plugins/impl/image-comparison/ImageComparisonComponent.tsx +2 -53
  69. package/src/plugins/impl/matplotlib/__tests__/matplotlib-renderer.test.ts +3 -71
  70. package/src/plugins/impl/matplotlib/matplotlib-renderer.ts +0 -1
  71. package/src/theme/useTheme.ts +1 -16
  72. package/dist/assets/__vite-browser-external-CjNAy01L.js +0 -1
  73. package/dist/assets/worker-B3XPCb6y.js +0 -98
  74. package/src/components/chat/__tests__/message-queue.test.tsx +0 -121
  75. package/src/components/editor/__tests__/output-persistence.test.tsx +0 -241
  76. package/src/components/editor/actions/__tests__/pair-with-agent-commands.test.ts +0 -153
  77. package/src/components/editor/actions/pair-with-agent-commands.ts +0 -109
  78. package/src/components/editor/columns/__tests__/cell-column.test.tsx +0 -105
  79. package/src/components/editor/renderers/__tests__/cells-renderer.test.tsx +0 -66
  80. package/src/core/islands/__tests__/main.test.ts +0 -176
  81. package/src/core/islands/components/__tests__/web-components.test.tsx +0 -214
  82. package/src/core/islands/worker/__tests__/controller.test.ts +0 -173
  83. package/src/hooks/__tests__/useHotkey.test.tsx +0 -88
  84. package/src/plugins/impl/image-comparison/__tests__/ImageComparisonComponent.test.tsx +0 -71
  85. package/src/theme/__tests__/useTheme.test.ts +0 -68
@@ -14,7 +14,6 @@ import {
14
14
  type KeyboardEvent,
15
15
  memo,
16
16
  useCallback,
17
- useEffect,
18
17
  useImperativeHandle,
19
18
  useMemo,
20
19
  useRef,
@@ -55,8 +54,6 @@ import {
55
54
  cellNeedsRun,
56
55
  cellStatusClasses,
57
56
  isUninstantiated,
58
- publishedCellClasses,
59
- shouldHidePublishedCell,
60
57
  } from "../../core/cells/utils";
61
58
  import type { UserConfig } from "../../core/config/config-schema";
62
59
  import { isAppInteractionDisabled } from "../../core/websocket/connection-utils";
@@ -306,9 +303,7 @@ const CellComponent = (props: CellProps) => {
306
303
  );
307
304
  }
308
305
 
309
- // Present mode is handled by EditableCellComponent with the edit chrome
310
- // hidden, so that the output DOM is not remounted when toggling modes.
311
- if (mode === "edit" || mode === "present") {
306
+ if (mode === "edit") {
312
307
  return (
313
308
  <EditableCellComponent
314
309
  {...props}
@@ -334,14 +329,14 @@ const ReadonlyCellComponent = forwardRef(
334
329
  published: true,
335
330
  });
336
331
 
332
+ const outputIsError = isErrorMime(cellRuntime.output?.mimetype);
333
+
337
334
  // Hide the output if it's an error or stopped.
338
- const hidden = shouldHidePublishedCell({
339
- errored: cellRuntime.errored,
340
- interrupted: cellRuntime.interrupted,
341
- stopped: cellRuntime.stopped,
342
- output: cellRuntime.output,
343
- showErrorTracebacks: false,
344
- });
335
+ const hidden =
336
+ cellRuntime.errored ||
337
+ cellRuntime.interrupted ||
338
+ cellRuntime.stopped ||
339
+ outputIsError;
345
340
 
346
341
  if (hidden) {
347
342
  return null;
@@ -373,7 +368,6 @@ const EditableCellComponent = ({
373
368
  theme,
374
369
  showPlaceholder,
375
370
  cellId,
376
- mode,
377
371
  canDelete,
378
372
  userConfig,
379
373
  isCollapsed,
@@ -421,28 +415,6 @@ const EditableCellComponent = ({
421
415
 
422
416
  const loading = outputIsLoading(cellRuntime.status);
423
417
 
424
- const isPresenting = mode === "present";
425
-
426
- // While presenting, the cell may be hidden (matching the read view), but it
427
- // stays mounted (CSS-hidden) so its DOM survives mode toggles.
428
- const presentHidden =
429
- isPresenting &&
430
- shouldHidePublishedCell({
431
- errored: cellRuntime.errored,
432
- interrupted: cellRuntime.interrupted,
433
- stopped: cellRuntime.stopped,
434
- output: cellRuntime.output,
435
- showErrorTracebacks: userConfig.runtime.show_tracebacks ?? false,
436
- });
437
-
438
- // CodeMirror cannot measure itself while the tray is display:none, so
439
- // re-measure when returning to edit mode.
440
- useEffect(() => {
441
- if (!isPresenting) {
442
- editorView.current?.requestMeasure();
443
- }
444
- }, [isPresenting, editorView]);
445
-
446
418
  // console output is cleared immediately on run, so check for queued instead
447
419
  // of loading to determine staleness
448
420
  const consoleOutputStale =
@@ -482,12 +454,7 @@ const EditableCellComponent = ({
482
454
  });
483
455
  const canCollapse = canCollapseOutline(cellRuntime.outline);
484
456
  const hasOutput = !isOutputEmpty(cellRuntime.output);
485
- // While presenting, pending edits do not dim the output as stale,
486
- // matching the read view.
487
- const isStaleCell = outputIsStale(
488
- cellRuntime,
489
- cellData.edited && !isPresenting,
490
- );
457
+ const isStaleCell = outputIsStale(cellRuntime, cellData.edited);
491
458
  const hasConsoleOutput = cellRuntime.consoleOutputs.length > 0;
492
459
  const cellOutput = userConfig.display.cell_output;
493
460
 
@@ -520,8 +487,7 @@ const EditableCellComponent = ({
520
487
  },
521
488
  });
522
489
 
523
- const emptyMarkdownPlaceholder = !isPresenting &&
524
- isMarkdownCodeHidden &&
490
+ const emptyMarkdownPlaceholder = isMarkdownCodeHidden &&
525
491
  isEmptyMarkdownContent &&
526
492
  !needsRun && (
527
493
  <div
@@ -543,31 +509,25 @@ const EditableCellComponent = ({
543
509
  );
544
510
 
545
511
  const outputArea = hasOutput && !isEmptyMarkdownContent && (
546
- <div
547
- className="relative"
548
- onDoubleClick={isPresenting ? undefined : showHiddenCodeIfMarkdown}
549
- >
550
- {!isPresenting && (
551
- <div className="absolute top-5 -left-7 z-20 print:hidden">
552
- <CollapseToggle
553
- isCollapsed={isCollapsed}
554
- onClick={() => {
555
- if (isCollapsed) {
556
- actions.expandCell({ cellId });
557
- } else {
558
- actions.collapseCell({ cellId });
559
- }
560
- }}
561
- canCollapse={canCollapse}
562
- />
563
- </div>
564
- )}
512
+ <div className="relative" onDoubleClick={showHiddenCodeIfMarkdown}>
513
+ <div className="absolute top-5 -left-7 z-20 print:hidden">
514
+ <CollapseToggle
515
+ isCollapsed={isCollapsed}
516
+ onClick={() => {
517
+ if (isCollapsed) {
518
+ actions.expandCell({ cellId });
519
+ } else {
520
+ actions.collapseCell({ cellId });
521
+ }
522
+ }}
523
+ canCollapse={canCollapse}
524
+ />
525
+ </div>
565
526
  <OutputArea
566
- // `allowExpand` must stay constant across modes: flipping it swaps the
567
- // output's container component and would remount the output DOM.
527
+ // Only allow expanding in edit mode
568
528
  allowExpand={true}
569
- // Force expand when markdown is hidden or when presenting
570
- forceExpand={isMarkdownCodeHidden || isPresenting}
529
+ // Force expand when markdown is hidden
530
+ forceExpand={isMarkdownCodeHidden}
571
531
  className={CSSClasses.outputArea}
572
532
  cellId={cellId}
573
533
  output={cellRuntime.output}
@@ -577,32 +537,19 @@ const EditableCellComponent = ({
577
537
  </div>
578
538
  );
579
539
 
580
- const className = clsx(
581
- "marimo-cell",
582
- "hover-actions-parent",
583
- isPresenting
584
- ? // Match the published styling of the read view
585
- publishedCellClasses({
586
- errored: cellRuntime.errored,
587
- stopped: cellRuntime.stopped,
588
- })
589
- : {
590
- "z-10": true,
591
- interactive: true,
592
- ...cellStatusClasses({
593
- needsRun,
594
- errored: cellRuntime.errored,
595
- stopped: cellRuntime.stopped,
596
- disabled: cellData.config.disabled,
597
- status: cellRuntime.status,
598
- }),
599
- borderless:
600
- isMarkdownCodeHidden &&
601
- hasOutput &&
602
- !navigationProps["data-selected"],
603
- "pending-cut": isPendingCut,
604
- },
605
- );
540
+ const className = clsx("marimo-cell", "hover-actions-parent z-10", {
541
+ interactive: true,
542
+ ...cellStatusClasses({
543
+ needsRun,
544
+ errored: cellRuntime.errored,
545
+ stopped: cellRuntime.stopped,
546
+ disabled: cellData.config.disabled,
547
+ status: cellRuntime.status,
548
+ }),
549
+ borderless:
550
+ isMarkdownCodeHidden && hasOutput && !navigationProps["data-selected"],
551
+ "pending-cut": isPendingCut,
552
+ });
606
553
 
607
554
  const handleRefactorWithAI: OnRefactorWithAI = useEvent(
608
555
  (opts: { prompt: string; triggerImmediately: boolean }) => {
@@ -631,11 +578,7 @@ const EditableCellComponent = ({
631
578
 
632
579
  return (
633
580
  <TooltipProvider>
634
- <CellActionsContextMenu
635
- cellId={cellId}
636
- getEditorView={getEditorView}
637
- disabled={isPresenting}
638
- >
581
+ <CellActionsContextMenu cellId={cellId} getEditorView={getEditorView}>
639
582
  <SortableCell
640
583
  tabIndex={-1}
641
584
  ref={cellRef}
@@ -644,34 +587,23 @@ const EditableCellComponent = ({
644
587
  onKeyDown={resumeCompletionHandler}
645
588
  cellId={cellId}
646
589
  canMoveX={canMoveX}
647
- disabled={isPresenting}
648
- hidden={presentHidden}
649
590
  title={renderCellTitle()}
650
591
  >
651
592
  <div
652
593
  tabIndex={-1}
653
- {...(isPresenting ? undefined : navigationProps)}
594
+ {...navigationProps}
654
595
  className={cn(
655
596
  className,
656
- !isPresenting && navigationProps.className,
657
- !isPresenting &&
658
- "focus:ring-1 focus:ring-(--slate-8) focus:ring-offset-2",
597
+ navigationProps.className,
598
+ "focus:ring-1 focus:ring-(--slate-8) focus:ring-offset-2",
659
599
  )}
660
600
  ref={cellContainerRef}
661
601
  {...cellDomProps(cellId, cellData.name)}
662
602
  >
663
- {!isPresenting && (
664
- <CellLeftSideActions cellId={cellId} actions={actions} />
665
- )}
603
+ <CellLeftSideActions cellId={cellId} actions={actions} />
666
604
  {cellOutput === "above" && (outputArea || emptyMarkdownPlaceholder)}
667
- {/* The tray is hidden-but-mounted while presenting so CodeMirror
668
- state survives mode toggles. Hide via the `hidden` attribute:
669
- preflight's `[hidden] { display: none !important }` beats
670
- `.tray { display: flex }`, which a display class would not. */}
671
605
  <div
672
- data-testid="cell-tray"
673
- className="tray"
674
- hidden={isPresenting}
606
+ className={cn("tray")}
675
607
  data-has-output-above={hasOutputAbove}
676
608
  data-hidden={isMarkdownCodeHidden}
677
609
  >
@@ -711,25 +643,21 @@ const EditableCellComponent = ({
711
643
  setLanguageAdapter={setLanguageAdapter}
712
644
  outputArea={cellOutput}
713
645
  />
714
- {/* Unmounted while presenting: the status timer re-renders every
715
- frame for running cells. */}
716
- {!isPresenting && (
717
- <CellRightSideActions
718
- className={cn(
719
- isMarkdownCodeHidden && cellOutput === "below" && "top-14",
720
- )}
721
- edited={cellData.edited}
722
- status={cellRuntime.status}
723
- isCellStatusInline={isCellStatusInline}
724
- uninstantiated={uninstantiated}
725
- disabled={cellData.config.disabled}
726
- runElapsedTimeMs={cellRuntime.runElapsedTimeMs}
727
- runStartTimestamp={cellRuntime.runStartTimestamp}
728
- lastRunStartTimestamp={cellRuntime.lastRunStartTimestamp}
729
- staleInputs={cellRuntime.staleInputs}
730
- interrupted={cellRuntime.interrupted}
731
- />
732
- )}
646
+ <CellRightSideActions
647
+ className={cn(
648
+ isMarkdownCodeHidden && cellOutput === "below" && "top-14",
649
+ )}
650
+ edited={cellData.edited}
651
+ status={cellRuntime.status}
652
+ isCellStatusInline={isCellStatusInline}
653
+ uninstantiated={uninstantiated}
654
+ disabled={cellData.config.disabled}
655
+ runElapsedTimeMs={cellRuntime.runElapsedTimeMs}
656
+ runStartTimestamp={cellRuntime.runStartTimestamp}
657
+ lastRunStartTimestamp={cellRuntime.lastRunStartTimestamp}
658
+ staleInputs={cellRuntime.staleInputs}
659
+ interrupted={cellRuntime.interrupted}
660
+ />
733
661
  <div className="shoulder-bottom hover-action">
734
662
  {canDelete && isCellCodeShown && (
735
663
  <DeleteButton
@@ -747,14 +675,12 @@ const EditableCellComponent = ({
747
675
  )}
748
676
  </div>
749
677
  </div>
750
- {!isPresenting && (
751
- <SqlValidationErrorBanner
752
- cellId={cellId}
753
- hide={cellRuntime.errored && !isStaleCell}
754
- />
755
- )}
678
+ <SqlValidationErrorBanner
679
+ cellId={cellId}
680
+ hide={cellRuntime.errored && !isStaleCell}
681
+ />
756
682
  {cellOutput === "below" && (outputArea || emptyMarkdownPlaceholder)}
757
- {!isPresenting && cellRuntime.serialization && (
683
+ {cellRuntime.serialization && (
758
684
  <div className="py-1 px-2 flex items-center justify-end gap-2 last:rounded-b">
759
685
  {isToplevel && (
760
686
  <a
@@ -812,36 +738,34 @@ const EditableCellComponent = ({
812
738
  </Tooltip>
813
739
  </div>
814
740
  )}
815
- {!isPresenting && (
816
- <ConsoleOutput
817
- consoleOutputs={cellRuntime.consoleOutputs}
818
- stale={consoleOutputStale}
819
- interrupted={cellRuntime.interrupted}
820
- // Empty name if serialization triggered
821
- cellName={cellRuntime.serialization ? "_" : cellData.name}
822
- onRefactorWithAI={handleRefactorWithAI}
823
- onClear={() => {
824
- actions.clearCellConsoleOutput({ cellId });
825
- // The debugger "Clear" (trashcan) also drops this cell's
826
- // breakpoints; no-op when none are set.
827
- clearCellBreakpoints(cellId);
828
- }}
829
- onSubmitDebugger={(text, index) => {
830
- actions.setStdinResponse({
831
- cellId,
832
- response: text,
833
- outputIndex: index,
834
- });
835
- sendStdin({ text });
836
- }}
837
- cellId={cellId}
838
- debuggerActive={cellRuntime.debuggerActive}
839
- />
840
- )}
741
+ <ConsoleOutput
742
+ consoleOutputs={cellRuntime.consoleOutputs}
743
+ stale={consoleOutputStale}
744
+ interrupted={cellRuntime.interrupted}
745
+ // Empty name if serialization triggered
746
+ cellName={cellRuntime.serialization ? "_" : cellData.name}
747
+ onRefactorWithAI={handleRefactorWithAI}
748
+ onClear={() => {
749
+ actions.clearCellConsoleOutput({ cellId });
750
+ // The debugger "Clear" (trashcan) also drops this cell's
751
+ // breakpoints; no-op when none are set.
752
+ clearCellBreakpoints(cellId);
753
+ }}
754
+ onSubmitDebugger={(text, index) => {
755
+ actions.setStdinResponse({
756
+ cellId,
757
+ response: text,
758
+ outputIndex: index,
759
+ });
760
+ sendStdin({ text });
761
+ }}
762
+ cellId={cellId}
763
+ debuggerActive={cellRuntime.debuggerActive}
764
+ />
841
765
  <PendingDeleteConfirmation cellId={cellId} />
842
766
  </div>
843
- {!isPresenting && <StagedAICellFooter cellId={cellId} />}
844
- {isCollapsed && !isPresenting && (
767
+ <StagedAICellFooter cellId={cellId} />
768
+ {isCollapsed && (
845
769
  <CollapsedCellBanner
846
770
  onClick={() => actions.expandCell({ cellId })}
847
771
  count={collapseCount}
@@ -1046,7 +970,6 @@ const SetupCellComponent = ({
1046
970
  theme,
1047
971
  showPlaceholder,
1048
972
  cellId,
1049
- mode,
1050
973
  canDelete,
1051
974
  userConfig,
1052
975
  canMoveX,
@@ -1157,26 +1080,10 @@ const SetupCellComponent = ({
1157
1080
  return undefined;
1158
1081
  };
1159
1082
 
1160
- const isPresenting = mode === "present";
1161
-
1162
- // CodeMirror cannot measure itself while its hidden ancestor is display:none,
1163
- // so re-measure when returning to edit mode. (Mirrors EditableCellComponent.)
1164
- useEffect(() => {
1165
- if (!isPresenting) {
1166
- editorView.current?.requestMeasure();
1167
- }
1168
- }, [isPresenting, editorView]);
1169
-
1170
1083
  return (
1171
1084
  <TooltipProvider>
1172
- <CellActionsContextMenu
1173
- cellId={cellId}
1174
- getEditorView={getEditorView}
1175
- disabled={isPresenting}
1176
- >
1177
- {/* The setup cell has no visible output, so it is hidden (but stays
1178
- mounted) while presenting. */}
1179
- <div hidden={isPresenting}>
1085
+ <CellActionsContextMenu cellId={cellId} getEditorView={getEditorView}>
1086
+ <div>
1180
1087
  <div
1181
1088
  data-status={cellRuntime.status}
1182
1089
  ref={cellRef}
@@ -1238,22 +1145,18 @@ const SetupCellComponent = ({
1238
1145
  setLanguageAdapter={Functions.NOOP}
1239
1146
  showLanguageToggles={false}
1240
1147
  />
1241
- {/* Unmounted while presenting: the status timer re-renders every
1242
- frame for running cells. */}
1243
- {!isPresenting && (
1244
- <CellRightSideActions
1245
- edited={cellData.edited}
1246
- status={cellRuntime.status}
1247
- isCellStatusInline={false}
1248
- uninstantiated={uninstantiated}
1249
- disabled={cellData.config.disabled}
1250
- runElapsedTimeMs={cellRuntime.runElapsedTimeMs}
1251
- runStartTimestamp={cellRuntime.runStartTimestamp}
1252
- lastRunStartTimestamp={cellRuntime.lastRunStartTimestamp}
1253
- staleInputs={cellRuntime.staleInputs}
1254
- interrupted={cellRuntime.interrupted}
1255
- />
1256
- )}
1148
+ <CellRightSideActions
1149
+ edited={cellData.edited}
1150
+ status={cellRuntime.status}
1151
+ isCellStatusInline={false}
1152
+ uninstantiated={uninstantiated}
1153
+ disabled={cellData.config.disabled}
1154
+ runElapsedTimeMs={cellRuntime.runElapsedTimeMs}
1155
+ runStartTimestamp={cellRuntime.runStartTimestamp}
1156
+ lastRunStartTimestamp={cellRuntime.lastRunStartTimestamp}
1157
+ staleInputs={cellRuntime.staleInputs}
1158
+ interrupted={cellRuntime.interrupted}
1159
+ />
1257
1160
  <div className="shoulder-bottom hover-action">
1258
1161
  {canDelete && (
1259
1162
  <DeleteButton
@@ -89,32 +89,22 @@ const CellArrayInternal: React.FC<CellArrayProps> = ({
89
89
  const { theme } = useTheme();
90
90
  const { toggleSidebarPanel } = useChromeActions();
91
91
 
92
- const isPresenting = mode === "present";
93
-
94
92
  // Side-effects
95
93
  useFocusFirstEditor();
96
94
 
97
95
  // HOTKEYS
98
- // Cell-editing hotkeys are disabled while presenting
99
- const whilePresenting = { disabled: isPresenting };
100
- useHotkey("global.focusTop", actions.focusTopCell, whilePresenting);
101
- useHotkey("global.focusBottom", actions.focusBottomCell, whilePresenting);
96
+ useHotkey("global.focusTop", actions.focusTopCell);
97
+ useHotkey("global.focusBottom", actions.focusBottomCell);
102
98
  useHotkey("global.toggleSidebar", toggleSidebarPanel);
103
- useHotkey("global.foldCode", actions.foldAll, whilePresenting);
104
- useHotkey("global.unfoldCode", actions.unfoldAll, whilePresenting);
105
- useHotkey(
106
- "global.formatAll",
107
- () => {
108
- formatAll();
109
- },
110
- whilePresenting,
111
- );
99
+ useHotkey("global.foldCode", actions.foldAll);
100
+ useHotkey("global.unfoldCode", actions.unfoldAll);
101
+ useHotkey("global.formatAll", () => {
102
+ formatAll();
103
+ });
112
104
  // Catch all to avoid native OS behavior
113
- // Otherwise a user might try to hide a cell and accidentally hide the OS
114
- // window. While presenting, no cell editing is possible, so let the
115
- // keystrokes reach the browser/OS.
116
- useHotkey("cell.hideCode", Functions.NOOP, whilePresenting);
117
- useHotkey("cell.format", Functions.NOOP, whilePresenting);
105
+ // Otherwise a user might try to hide a cell and accidentally hide the OS window
106
+ useHotkey("cell.hideCode", Functions.NOOP);
107
+ useHotkey("cell.format", Functions.NOOP);
118
108
 
119
109
  const cellIds = useCellIds();
120
110
  const scrollKey = useScrollKey();
@@ -131,11 +121,10 @@ const CellArrayInternal: React.FC<CellArrayProps> = ({
131
121
  return (
132
122
  <VerticalLayoutWrapper
133
123
  // 'pb' allows the user to put the cell in the middle of the screen
134
- className={cn(!isPresenting && "pb-[40vh]")}
124
+ className="pb-[40vh]"
135
125
  invisible={false}
136
126
  appConfig={appConfig}
137
- // 'pr' makes room for the floating actions
138
- innerClassName={cn(!isPresenting && "pr-4")}
127
+ innerClassName="pr-4" // For the floating actions
139
128
  >
140
129
  <PackageAlert />
141
130
  <StartupLogsAlert />
@@ -197,7 +186,6 @@ const CellColumn: React.FC<{
197
186
 
198
187
  const hasOnlyOneCell = cellIds.hasOnlyOneId();
199
188
  const hasSetupCell = cellIds.inOrderIds.includes(SETUP_CELL_ID);
200
- const isPresenting = mode === "present";
201
189
 
202
190
  return (
203
191
  <Column
@@ -207,9 +195,8 @@ const CellColumn: React.FC<{
207
195
  canMoveRight={index < columnsLength - 1}
208
196
  width={appConfig.width}
209
197
  canDelete={columnsLength > 1}
210
- presenting={isPresenting}
211
198
  footer={
212
- hideControls || isPresenting ? null : (
199
+ hideControls ? null : (
213
200
  <AddCellButtons
214
201
  columnId={columnId}
215
202
  className={cn(
@@ -29,14 +29,8 @@ export const CellsRenderer: React.FC<PropsWithChildren<Props>> = memo(
29
29
  const { selectedLayout, layoutData } = useLayoutState();
30
30
  const kioskMode = useAtomValue(kioskModeAtom);
31
31
 
32
- // Render children (the editable notebook) in edit mode, and in present
33
- // mode with the vertical layout: keeping the same tree across the
34
- // edit<->present toggle preserves cell output DOM (iframes, widgets).
35
- // Grid/slides layouts and kiosk mode swap to their layout renderer.
36
- if (
37
- !kioskMode &&
38
- (mode === "edit" || (mode === "present" && selectedLayout === "vertical"))
39
- ) {
32
+ // Just render children if we are in edit mode
33
+ if (mode === "edit" && !kioskMode) {
40
34
  return children;
41
35
  }
42
36
 
@@ -42,23 +42,6 @@ describe("SlidesLayoutPlugin validator", () => {
42
42
  }).success,
43
43
  ).toBe(false);
44
44
  });
45
-
46
- it("accepts each valid deck vertical alignment", () => {
47
- for (const verticalAlign of ["top", "center", "bottom"]) {
48
- expect(
49
- SlidesLayoutPlugin.validator.safeParse({ deck: { verticalAlign } })
50
- .success,
51
- ).toBe(true);
52
- }
53
- });
54
-
55
- it("rejects an unknown deck vertical alignment", () => {
56
- expect(
57
- SlidesLayoutPlugin.validator.safeParse({
58
- deck: { verticalAlign: "middle" },
59
- }).success,
60
- ).toBe(false);
61
- });
62
45
  });
63
46
 
64
47
  describe("SlidesLayoutPlugin deserializeLayout", () => {
@@ -285,18 +268,6 @@ const BACKWARDS_COMPAT_SNAPSHOTS: BackwardsCompatCase[] = [
285
268
  ],
286
269
  },
287
270
  },
288
- {
289
- // `verticalAlign` was added to DeckConfig.
290
- label: "deck.verticalAlign round-trips through validate + (de)serialize",
291
- input: {
292
- cells: [{}],
293
- deck: { transition: "fade", verticalAlign: "top" },
294
- },
295
- expected: {
296
- deck: { transition: "fade", verticalAlign: "top" },
297
- cellIds: ["a"],
298
- },
299
- },
300
271
  ];
301
272
 
302
273
  describe("SlidesLayoutPlugin backwards compatibility", () => {
@@ -23,12 +23,8 @@ const DeckTransitionSchema = z.enum([
23
23
  ]);
24
24
  export type DeckTransition = z.infer<typeof DeckTransitionSchema>;
25
25
 
26
- const DeckVerticalAlignSchema = z.enum(["top", "center", "bottom"]);
27
- export type DeckVerticalAlign = z.infer<typeof DeckVerticalAlignSchema>;
28
-
29
26
  const DeckConfigSchema = z.looseObject({
30
27
  transition: DeckTransitionSchema.optional(),
31
- verticalAlign: DeckVerticalAlignSchema.optional(),
32
28
  });
33
29
  export type DeckConfig = z.infer<typeof DeckConfigSchema>;
34
30
 
@@ -33,14 +33,11 @@ import { getReadonlyCodeDisplay } from "@/core/cells/readonly-code-display";
33
33
  import { MarkdownLanguageAdapter } from "@/core/codemirror/language/languages/markdown";
34
34
  import { useResolvedMarimoConfig } from "@/core/config/config";
35
35
  import { CSSClasses, KnownQueryParams } from "@/core/constants";
36
- import type { OutputMessage } from "@/core/kernel/messages";
36
+ import type { MarimoError, OutputMessage } from "@/core/kernel/messages";
37
37
  import { kernelStateAtom } from "@/core/kernel/state";
38
38
  import { useNotebookCodeAvailable } from "@/core/meta/code-visibility";
39
39
  import { showCodeInRunModeAtom } from "@/core/meta/state";
40
- import {
41
- publishedCellClasses,
42
- shouldHidePublishedCell,
43
- } from "@/core/cells/utils";
40
+ import { isErrorMime } from "@/core/mime";
44
41
  import { type AppMode, kioskModeAtom } from "@/core/mode";
45
42
  import { useRequestClient } from "@/core/network/requests";
46
43
  import type { CellConfig } from "@/core/network/types";
@@ -365,13 +362,12 @@ const VerticalCell = memo(
365
362
  const className = cn(
366
363
  "marimo-cell",
367
364
  "hover-actions-parent empty:invisible",
368
- published
369
- ? publishedCellClasses({ errored, stopped })
370
- : {
371
- "has-error": errored,
372
- stopped: stopped,
373
- borderless: isPureMarkdown,
374
- },
365
+ {
366
+ published: published,
367
+ "has-error": errored,
368
+ stopped: stopped,
369
+ borderless: isPureMarkdown && !published,
370
+ },
375
371
  );
376
372
 
377
373
  // Read mode and show code
@@ -423,15 +419,19 @@ const VerticalCell = memo(
423
419
  );
424
420
  }
425
421
 
422
+ const outputIsError = isErrorMime(output?.mimetype);
426
423
  // When show_tracebacks is enabled, show error outputs inline
427
424
  // instead of hiding them
428
- const hidden = shouldHidePublishedCell({
429
- errored,
430
- interrupted,
431
- stopped,
432
- output,
433
- showErrorTracebacks,
434
- });
425
+ const hasTraceback =
426
+ showErrorTracebacks &&
427
+ outputIsError &&
428
+ Array.isArray(output?.data) &&
429
+ output.data.some(
430
+ (e: MarimoError) =>
431
+ e.type === "exception" && "traceback" in e && e.traceback,
432
+ );
433
+ const hidden =
434
+ (errored || interrupted || stopped || outputIsError) && !hasTraceback;
435
435
  if (hidden) {
436
436
  return null;
437
437
  }