@marimo-team/islands 0.23.15-dev4 → 0.23.15-dev40

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 (92) hide show
  1. package/dist/{ConnectedDataExplorerComponent-CU4fZJzG.js → ConnectedDataExplorerComponent-7p7rt9iw.js} +4 -4
  2. package/dist/{ErrorBoundary-DE6tzZf-.js → ErrorBoundary-B_CAG7_e.js} +1 -1
  3. package/dist/{ImageComparisonComponent-CHrI72em.js → ImageComparisonComponent-1i5IBhon.js} +173 -129
  4. package/dist/assets/__vite-browser-external-CjNAy01L.js +1 -0
  5. package/dist/assets/worker-B3XPCb6y.js +98 -0
  6. package/dist/{chat-ui-DinOvbWu.js → chat-ui-C0z13gJB.js} +3111 -3111
  7. package/dist/{code-visibility-Dk8cVOny.js → code-visibility-CSsHnVZu.js} +946 -864
  8. package/dist/{constants-T20xxyNf.js → debounce-BOD3DbfP.js} +1 -24
  9. package/dist/{formats-Dzx4J_z1.js → formats-CitsMtUm.js} +1 -1
  10. package/dist/{glide-data-editor-CjTu7ukN.js → glide-data-editor-CwZz71BD.js} +3 -3
  11. package/dist/{html-to-image-_wGfk8V-.js → html-to-image-CEo5pRYw.js} +2291 -2250
  12. package/dist/{input-DtsN7xm-.js → input-BGPrFH3g.js} +2 -2
  13. package/dist/main.js +1297 -1201
  14. package/dist/{mermaid-BYqXy_NE.js → mermaid-UdmxG2PZ.js} +2 -2
  15. package/dist/{process-output-Mh4UrjwM.js → process-output-BOvvilRG.js} +1 -1
  16. package/dist/{reveal-component-B5DXLyO7.js → reveal-component-DGjJVNMQ.js} +618 -605
  17. package/dist/{spec-Cz-Bj1JI.js → spec-DSs9v0xx.js} +1 -1
  18. package/dist/style.css +1 -1
  19. package/dist/{toDate-CWNNlFEX.js → toDate-BRJgtOGm.js} +14 -5
  20. package/dist/{useAsyncData-KfHB8wQR.js → useAsyncData-BSOyAbac.js} +1 -1
  21. package/dist/{useDeepCompareMemoize-nJMtxhm4.js → useDeepCompareMemoize-BTLeWzuR.js} +1 -1
  22. package/dist/{useLifecycle-DegSo0lV.js → useLifecycle-C6wHjkhW.js} +1 -1
  23. package/dist/{useTheme-6eZ3GOTS.js → useTheme-Df_vGflw.js} +62 -27
  24. package/dist/{vega-component-DzyyM9fc.js → vega-component-BAvmvTjO.js} +6 -6
  25. package/package.json +1 -1
  26. package/src/components/chat/__tests__/chat-utils.test.ts +244 -1
  27. package/src/components/chat/__tests__/message-queue.test.tsx +121 -0
  28. package/src/components/chat/chat-panel.tsx +196 -67
  29. package/src/components/chat/chat-utils.ts +111 -2
  30. package/src/components/editor/SortableCell.tsx +6 -2
  31. package/src/components/editor/__tests__/output-persistence.test.tsx +241 -0
  32. package/src/components/editor/actions/__tests__/pair-with-agent-commands.test.ts +153 -0
  33. package/src/components/editor/actions/pair-with-agent-commands.ts +109 -0
  34. package/src/components/editor/actions/pair-with-agent-modal.tsx +20 -64
  35. package/src/components/editor/ai/add-cell-with-ai.tsx +14 -5
  36. package/src/components/editor/ai/ai-completion-editor.tsx +4 -1
  37. package/src/components/editor/cell/cell-context-menu.tsx +7 -0
  38. package/src/components/editor/chrome/panels/packages-panel.tsx +11 -1
  39. package/src/components/editor/columns/__tests__/cell-column.test.tsx +105 -0
  40. package/src/components/editor/columns/cell-column.tsx +34 -4
  41. package/src/components/editor/columns/sortable-column.tsx +24 -4
  42. package/src/components/editor/file-tree/download.ts +46 -0
  43. package/src/components/editor/file-tree/file-explorer.tsx +3 -21
  44. package/src/components/editor/file-tree/file-viewer.tsx +4 -27
  45. package/src/components/editor/navigation/__tests__/navigation.test.ts +33 -0
  46. package/src/components/editor/navigation/navigation.ts +8 -1
  47. package/src/components/editor/notebook-cell.tsx +203 -106
  48. package/src/components/editor/renderers/__tests__/cells-renderer.test.tsx +66 -0
  49. package/src/components/editor/renderers/cell-array.tsx +26 -13
  50. package/src/components/editor/renderers/cells-renderer.tsx +8 -2
  51. package/src/components/editor/renderers/slides-layout/__tests__/plugin.test.ts +29 -0
  52. package/src/components/editor/renderers/slides-layout/types.ts +4 -0
  53. package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +19 -19
  54. package/src/components/slides/reveal-component.tsx +37 -4
  55. package/src/components/slides/slide-form.tsx +72 -0
  56. package/src/components/ui/toast.tsx +11 -3
  57. package/src/components/ui/toaster.tsx +65 -9
  58. package/src/core/cells/__tests__/utils.test.ts +59 -0
  59. package/src/core/cells/utils.ts +51 -0
  60. package/src/core/codemirror/completion/__tests__/signature-hint.test.ts +97 -3
  61. package/src/core/codemirror/completion/signature-hint.ts +78 -11
  62. package/src/core/constants.ts +6 -0
  63. package/src/core/islands/__tests__/bridge.test.ts +341 -46
  64. package/src/core/islands/__tests__/main.test.ts +176 -0
  65. package/src/core/islands/__tests__/parse.test.ts +105 -0
  66. package/src/core/islands/bootstrap.ts +8 -3
  67. package/src/core/islands/bridge.ts +116 -23
  68. package/src/core/islands/components/__tests__/web-components.test.tsx +214 -0
  69. package/src/core/islands/components/web-components.tsx +76 -15
  70. package/src/core/islands/constants.ts +1 -0
  71. package/src/core/islands/main.ts +69 -3
  72. package/src/core/islands/parse.ts +70 -23
  73. package/src/core/islands/worker/__tests__/controller.test.ts +173 -0
  74. package/src/core/islands/worker/worker.tsx +145 -57
  75. package/src/core/runtime/__tests__/runtime.test.ts +64 -0
  76. package/src/core/runtime/runtime.ts +30 -10
  77. package/src/core/wasm/worker/bootstrap.ts +113 -20
  78. package/src/css/app/Cell.css +10 -0
  79. package/src/hooks/__tests__/useHotkey.test.tsx +88 -0
  80. package/src/hooks/useHotkey.ts +29 -4
  81. package/src/plugins/impl/anywidget/__tests__/host.test.ts +6 -9
  82. package/src/plugins/impl/anywidget/__tests__/widget-binding.test.ts +22 -61
  83. package/src/plugins/impl/anywidget/model-proxy.ts +0 -13
  84. package/src/plugins/impl/anywidget/widget-binding.ts +4 -34
  85. package/src/plugins/impl/image-comparison/ImageComparisonComponent.tsx +53 -2
  86. package/src/plugins/impl/image-comparison/__tests__/ImageComparisonComponent.test.tsx +71 -0
  87. package/src/plugins/impl/matplotlib/__tests__/matplotlib-renderer.test.ts +71 -3
  88. package/src/plugins/impl/matplotlib/matplotlib-renderer.ts +1 -0
  89. package/src/theme/__tests__/useTheme.test.ts +68 -0
  90. package/src/theme/useTheme.ts +16 -1
  91. package/dist/assets/__vite-browser-external-BQCLNwri.js +0 -1
  92. package/dist/assets/worker-DAWRHcPq.js +0 -73
@@ -1,12 +1,61 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
+ import type { EditorState } from "@codemirror/state";
2
3
  import { StateEffect, StateField } from "@codemirror/state";
3
- import { showTooltip, type Tooltip } from "@codemirror/view";
4
+ import { type EditorView, showTooltip, type Tooltip } from "@codemirror/view";
4
5
 
5
6
  /**
6
7
  * Effect to set (or clear, with `null`) the floating signature hint.
7
8
  */
8
9
  export const setSignatureHintEffect = StateEffect.define<Tooltip | null>();
9
10
 
11
+ // Bound the scan so large cells stay cheap on every keystroke.
12
+ const MAX_LINES_BACK = 20;
13
+
14
+ /**
15
+ * Whether the cursor is still inside the anchored call (just inside its `(`).
16
+ *
17
+ * Anchor-relative paren scan, bounded to {@link MAX_LINES_BACK} lines.
18
+ * Good enough for hint dismissal — not a full parse (ignores strings/comments).
19
+ */
20
+ function isCursorInsideAnchoredCall(options: {
21
+ state: EditorState;
22
+ anchor: number;
23
+ head: number;
24
+ }): boolean {
25
+ const { state, anchor, head } = options;
26
+ if (head < anchor) {
27
+ return false;
28
+ }
29
+
30
+ const headLine = state.doc.lineAt(head).number;
31
+ const anchorLine = state.doc.lineAt(anchor).number;
32
+ const startLine = Math.max(anchorLine, headLine - MAX_LINES_BACK + 1);
33
+ const from = Math.max(anchor, state.doc.line(startLine).from);
34
+
35
+ // If the anchor is outside the bounded window, assume its `(` is still open.
36
+ const assumedOpen = from > anchor;
37
+ let balance = assumedOpen ? 1 : 0;
38
+ const iter = state.doc.iterRange(from, head);
39
+ for (;;) {
40
+ const { value, done } = iter.next();
41
+ if (done) {
42
+ break;
43
+ }
44
+ for (const char of value) {
45
+ if (char === "(") {
46
+ balance++;
47
+ } else if (char === ")") {
48
+ balance--;
49
+ const closed = assumedOpen ? balance <= 0 : balance < 0;
50
+ if (closed) {
51
+ return false;
52
+ }
53
+ }
54
+ }
55
+ }
56
+ return true;
57
+ }
58
+
10
59
  /**
11
60
  * Wrap a tooltip so it renders like the completion popup's info box.
12
61
  *
@@ -34,13 +83,7 @@ export function asSignatureHint(tooltip: Tooltip): Tooltip {
34
83
  * Holds the floating "signature hint" shown after typing `(` or `,` inside a
35
84
  * call on the non-LSP (Jedi) completion path.
36
85
  *
37
- * The LSP path has its own signature help; this fills the gap for users
38
- * without a language server. The completion source (`pythonCompletionSource`)
39
- * drives it: it dispatches `setSignatureHintEffect` with the tooltip when the
40
- * backend returns a signature and with `null` otherwise. The hint is also
41
- * cleared when the cursor moves via a selection-only change (e.g. clicking
42
- * away or arrowing out of the call), and kept anchored across edits so it
43
- * doesn't flicker while a fresh result is in flight.
86
+ * The LSP path has its own signature help; this fills the gap for users without a language server.
44
87
  */
45
88
  export const signatureHintField = StateField.define<Tooltip | null>({
46
89
  create: () => null,
@@ -57,12 +100,36 @@ export const signatureHintField = StateField.define<Tooltip | null>({
57
100
  if (tr.selection && !tr.docChanged) {
58
101
  return null;
59
102
  }
60
- // Keep the hint anchored across edits; the completion source refreshes or
61
- // clears it as new results arrive.
103
+ // Dismiss once the cursor leaves the anchored call (e.g. the closing paren
104
+ // is typed). Otherwise keep the hint anchored across edits so it doesn't
105
+ // flicker while a fresh result is in flight; the completion source refreshes
106
+ // or clears it as results arrive.
62
107
  if (tr.docChanged) {
63
- return { ...tooltip, pos: tr.changes.mapPos(tooltip.pos) };
108
+ const anchor = tr.changes.mapPos(tooltip.pos);
109
+ if (
110
+ !isCursorInsideAnchoredCall({
111
+ state: tr.state,
112
+ anchor,
113
+ head: tr.state.selection.main.head,
114
+ })
115
+ ) {
116
+ return null;
117
+ }
118
+ return { ...tooltip, pos: anchor };
64
119
  }
65
120
  return tooltip;
66
121
  },
67
122
  provide: (field) => showTooltip.from(field),
68
123
  });
124
+
125
+ /**
126
+ * Dismiss the floating signature hint if one is showing.
127
+ * Returns `true` if a hint was dismissed.
128
+ */
129
+ export function closeSignatureHint(view: EditorView): boolean {
130
+ if (view.state.field(signatureHintField, false)) {
131
+ view.dispatch({ effects: setSignatureHintEffect.of(null) });
132
+ return true;
133
+ }
134
+ return false;
135
+ }
@@ -50,6 +50,12 @@ export const KnownQueryParams = {
50
50
  * If false, the chrome will be hidden.
51
51
  */
52
52
  showChrome: "show-chrome",
53
+ /**
54
+ * Override the display theme: `light`, `dark`, or `system`.
55
+ * Takes precedence over the notebook's saved `display.theme`.
56
+ * Ignored for embedded islands, which infer the theme from their host page.
57
+ */
58
+ theme: "theme",
53
59
  };
54
60
 
55
61
  /**