@marimo-team/islands 0.25.1-dev15 → 0.25.1-dev17

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 (30) hide show
  1. package/dist/{ErrorBoundary-rK4WeIKo.js → ErrorBoundary-B4i0ev18.js} +1 -1
  2. package/dist/{cells-B5-y5EY3.js → cells-Cksce8br.js} +2 -2
  3. package/dist/{chat-ui-HJZsTl7o.js → chat-ui-4lXygZ8L.js} +4 -4
  4. package/dist/{code-visibility-CP_C83cg.js → code-visibility-CRc1C5g4.js} +2 -2
  5. package/dist/{common-DG-DQIXA.js → common-DQS4JILK.js} +9 -9
  6. package/dist/{data-grid-overlay-editor-BkQlsfsY.js → data-grid-overlay-editor-D0-p5694.js} +1 -1
  7. package/dist/{error-entries-Bkbpx0T0.js → error-entries-CvCFdpY2.js} +1 -1
  8. package/dist/{feedback-button-Bq3Y9lLX.js → feedback-button-DD68Ij-B.js} +4 -4
  9. package/dist/{glide-data-editor-CqWK6dYe.js → glide-data-editor-DqTwUsOq.js} +3 -3
  10. package/dist/{globals-BgCP3PkW.js → globals-RG69U5-c.js} +1 -1
  11. package/dist/{html-to-image-BAgJOlSW.js → html-to-image-jTwYSWRc.js} +1 -1
  12. package/dist/main.js +13 -18
  13. package/dist/{number-overlay-editor-BkKIn1GU.js → number-overlay-editor-DB4g1nLo.js} +1 -1
  14. package/dist/{process-output-zDX4jbhd.js → process-output-DevJrL3v.js} +2 -2
  15. package/dist/{reveal-component-DJ1j8cCp.js → reveal-component-QBu-zZNO.js} +3 -3
  16. package/dist/style.css +1 -1
  17. package/package.json +1 -1
  18. package/src/components/editor/chrome/components/contribute-snippet-button.tsx +6 -1
  19. package/src/components/editor/notebook-cell.tsx +2 -2
  20. package/src/components/editor/output/MarimoTracebackOutput.tsx +1 -1
  21. package/src/components/editor/output/VideoOutput.tsx +1 -1
  22. package/src/components/editor/output/ansi-reduce.ts +8 -4
  23. package/src/components/editor/output/console/text-rendering.tsx +3 -1
  24. package/src/components/home/components.tsx +1 -0
  25. package/src/components/pages/run-page.tsx +1 -0
  26. package/src/components/static-html/share-modal.tsx +2 -1
  27. package/src/components/static-html/static-banner.tsx +2 -1
  28. package/src/components/ui/links.tsx +6 -1
  29. package/src/css/globals.css +18 -21
  30. package/src/plugins/layout/RoutesPlugin.tsx +4 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.25.1-dev15",
3
+ "version": "0.25.1-dev17",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -40,7 +40,12 @@ const ContributeSnippetModal: React.FC<{
40
40
  <DialogDescription>
41
41
  Have a useful snippet you want to share with the community? Make a
42
42
  pull request{" "}
43
- <a href={Constants.githubPage} target="_blank" className="underline">
43
+ <a
44
+ href={Constants.githubPage}
45
+ target="_blank"
46
+ rel="noreferrer"
47
+ className="underline"
48
+ >
44
49
  on GitHub
45
50
  </a>
46
51
  .
@@ -762,7 +762,7 @@ const EditableCellComponent = ({
762
762
  href="https://links.marimo.app/reusable-definitions"
763
763
  target="_blank"
764
764
  className="hover:underline text-muted-foreground text-xs font-bold"
765
- rel="noopener"
765
+ rel="noreferrer"
766
766
  >
767
767
  reusable
768
768
  </a>
@@ -801,7 +801,7 @@ const EditableCellComponent = ({
801
801
  <a
802
802
  href="https://links.marimo.app/reusable-definitions"
803
803
  target="_blank"
804
- rel="noopener"
804
+ rel="noreferrer"
805
805
  >
806
806
  <HelpCircleIcon
807
807
  size={16}
@@ -177,7 +177,7 @@ export const MarimoTracebackOutput = ({
177
177
  <a
178
178
  target="_blank"
179
179
  href="https://marimo.io/discord?ref=notebook"
180
- rel="noopener"
180
+ rel="noreferrer"
181
181
  >
182
182
  <MessageCircleIcon className="h-4 w-4 mr-2" />
183
183
  Ask in Discord
@@ -7,5 +7,5 @@ interface Props {
7
7
  }
8
8
 
9
9
  export const VideoOutput = ({ src, className }: Props): JSX.Element => {
10
- return <iframe className={className} src={src} />;
10
+ return <iframe className={className} src={src} title="Video output" />;
11
11
  };
@@ -13,8 +13,10 @@ export interface Cursor {
13
13
  export class TerminalBuffer {
14
14
  private lines: string[] = [""];
15
15
  private cursor: Cursor = { row: 0, col: 0 };
16
- // oxlint-ignore-next-line no-control-regex -- Needed for ANSI escape sequence parsing
17
- private static readonly ESCAPE_REGEX = /\u001B\[([0-9;]*)([A-DJKH])/u;
16
+ private static readonly ESCAPE_REGEX = new RegExp(
17
+ String.raw`\u001B\[([0-9;]*)([A-DJKH])`,
18
+ "u",
19
+ );
18
20
 
19
21
  /** Ensure the internal lines array is large enough. */
20
22
  private ensureLine(row: number) {
@@ -180,8 +182,10 @@ export class TerminalBuffer {
180
182
  */
181
183
  export class AnsiParser {
182
184
  // Matches both CSI sequences (ESC[...letter) and other escape sequences like character set selection (ESC(B)
183
- // oxlint-ignore-next-line no-control-regex -- Needed for ANSI parsing
184
- private ESC_REGEX = /\u001B(?:\[[0-9;]*[A-Za-z]|\([0-9A-Za-z])/gu;
185
+ private ESC_REGEX = new RegExp(
186
+ String.raw`\u001B(?:\[[0-9;]*[A-Za-z]|\([0-9A-Za-z])`,
187
+ "gu",
188
+ );
185
189
 
186
190
  parse(input: string): { type: "text" | "escape"; value: string }[] {
187
191
  const tokens: { type: "text" | "escape"; value: string }[] = [];
@@ -256,6 +256,7 @@ export const pipInstallReplacer: Replacer = (domNode: DOMNode) => {
256
256
  );
257
257
  }
258
258
 
259
+ // oxlint-disable-next-line react/jsx-no-useless-fragment -- html-react-parser replacers must return a React element.
259
260
  return <>{segments}</>;
260
261
  };
261
262
 
@@ -283,6 +284,7 @@ export const urlReplacer: Replacer = (domNode: DOMNode) => {
283
284
  return undefined;
284
285
  }
285
286
 
287
+ // oxlint-disable-next-line react/jsx-no-useless-fragment -- html-react-parser replacers must return a React element.
286
288
  return <>{result}</>;
287
289
  };
288
290
 
@@ -331,5 +333,5 @@ export const RenderTextWithLinks = ({ text }: { text: string }) => {
331
333
  );
332
334
  }, [text]);
333
335
 
334
- return <>{content}</>;
336
+ return content;
335
337
  };
@@ -170,6 +170,7 @@ export const ResourceLinks: React.FC = () => {
170
170
  key={resource.title}
171
171
  href={resource.url}
172
172
  target="_blank"
173
+ rel="noreferrer"
173
174
  aria-label={`${resource.title}: ${resource.description}`}
174
175
  className="flex items-start gap-3 py-3 px-3 rounded-lg border hover:bg-accent/20 transition-colors shadow-xs"
175
176
  >
@@ -50,6 +50,7 @@ const Watermark = () => {
50
50
  <a
51
51
  href={Constants.githubPage}
52
52
  target="_blank"
53
+ rel="noreferrer"
53
54
  className="text-sm text-(--grass-11) font-bold tracking-wide transition-colors bg-(--grass-4) hover:bg-(--grass-5) border-t border-l border-(--grass-8) px-3 py-1 rounded-tl-md flex items-center gap-2"
54
55
  >
55
56
  <span>made with marimo</span>
@@ -74,6 +74,7 @@ export const ShareStaticNotebookModal: React.FC<{
74
74
  <a
75
75
  href={Constants.issuesPage}
76
76
  target="_blank"
77
+ rel="noreferrer"
77
78
  className="underline"
78
79
  >
79
80
  GitHub
@@ -102,7 +103,7 @@ export const ShareStaticNotebookModal: React.FC<{
102
103
  <DialogDescription>
103
104
  You can publish a static, non-interactive version of this notebook
104
105
  to the public web. We will create a link for you that lives on{" "}
105
- <a href={BASE_URL} target="_blank">
106
+ <a href={BASE_URL} target="_blank" rel="noreferrer">
106
107
  {BASE_URL}
107
108
  </a>
108
109
  .
@@ -1,6 +1,5 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  /* oxlint-disable react/jsx-no-comment-textnodes */
3
- /* oxlint-disable react/jsx-no-target-blank */
4
3
 
5
4
  import { useAtomValue } from "jotai";
6
5
  import { CopyIcon, DownloadIcon } from "lucide-react";
@@ -49,6 +48,7 @@ export const StaticBanner: React.FC = () => {
49
48
  <a
50
49
  href={Constants.githubPage}
51
50
  target="_blank"
51
+ rel="noreferrer"
52
52
  className="text-(--sky-11) font-medium underline"
53
53
  >
54
54
  marimo
@@ -93,6 +93,7 @@ const StaticBannerDialog = ({ code }: { code: string }) => {
93
93
  <a
94
94
  href={Constants.githubPage}
95
95
  target="_blank"
96
+ rel="noreferrer"
96
97
  className="text-(--sky-11) hover:underline font-medium"
97
98
  >
98
99
  marimo
@@ -21,7 +21,12 @@ export const ExternalLink = ({
21
21
  children: React.ReactNode;
22
22
  }) => {
23
23
  return (
24
- <a href={href} target="_blank" className="text-link hover:underline">
24
+ <a
25
+ href={href}
26
+ target="_blank"
27
+ rel="noreferrer"
28
+ className="text-link hover:underline"
29
+ >
25
30
  {children}
26
31
  </a>
27
32
  );
@@ -55,29 +55,21 @@
55
55
  --background: light-dark(hsl(0deg 0% 100%), hsl(150deg 7.7% 10.2%));
56
56
  --foreground: light-dark(hsl(222.2deg 47.4% 11.2%), hsl(155deg 7% 93%));
57
57
  --muted: light-dark(hsl(210deg 40% 96.1%), hsl(180deg 14% 1%));
58
- --muted-foreground: light-dark(
59
- hsl(215.4deg 16.3% 46.9%),
60
- hsl(155deg 5% 68.3%)
61
- );
58
+ --muted-foreground: light-dark(hsl(215.4deg 16.3% 46.9%),
59
+ hsl(155deg 5% 68.3%));
62
60
  --popover: light-dark(hsl(0deg 0% 100%), hsl(151deg 5.5% 15.2%));
63
- --popover-foreground: light-dark(
64
- hsl(222.2deg 47.4% 11.2%),
65
- hsl(155deg 5% 68.3%)
66
- );
61
+ --popover-foreground: light-dark(hsl(222.2deg 47.4% 11.2%),
62
+ hsl(155deg 5% 68.3%));
67
63
  --card: light-dark(hsl(0deg 0% 100%), hsl(151deg 5.5% 15.2%));
68
- --card-foreground: light-dark(
69
- hsl(222.2deg 47.4% 11.2%),
70
- hsl(155deg 5% 76.3%)
71
- );
64
+ --card-foreground: light-dark(hsl(222.2deg 47.4% 11.2%),
65
+ hsl(155deg 5% 76.3%));
72
66
  --border: light-dark(hsl(214.3deg 31.8% 91.4%), hsl(153deg 3.7% 24.2%));
73
67
  --input: light-dark(hsl(0deg 0% 64%), hsl(154deg 3.3% 28.7%));
74
68
  --primary: light-dark(hsl(208deg 93.5% 47.4%), hsl(192deg 59.8% 39%));
75
69
  --primary-foreground: light-dark(hsl(210deg 40% 98%), hsl(190deg 80% 84%));
76
70
  --secondary: light-dark(hsl(210deg 40% 96.1%), hsl(155deg 7% 93%));
77
- --secondary-foreground: light-dark(
78
- hsl(222.2deg 47.4% 11.2%),
79
- hsl(151deg 5.5% 15.2%)
80
- );
71
+ --secondary-foreground: light-dark(hsl(222.2deg 47.4% 11.2%),
72
+ hsl(151deg 5.5% 15.2%));
81
73
  --accent: light-dark(hsl(209deg 100% 96.5%), hsl(192deg 56.6% 26.5%));
82
74
  --accent-foreground: light-dark(hsl(211deg 90% 42%), hsl(190deg 80% 84%));
83
75
  --ring: hsl(215deg 20.2% 65.1%);
@@ -105,10 +97,8 @@
105
97
 
106
98
  /* Base shadows. */
107
99
  --base-shadow: light-dark(hsl(0deg 0% 85% / 40%), hsla(0deg 0% 36% / 60%));
108
- --base-shadow-darker: light-dark(
109
- hsl(0deg 0% 50% / 40%),
110
- hsl(0deg 0% 50% / 60%)
111
- );
100
+ --base-shadow-darker: light-dark(hsl(0deg 0% 50% / 40%),
101
+ hsl(0deg 0% 50% / 60%));
112
102
  --base-shadow-opacity: 5%;
113
103
 
114
104
  /* Codemirror editor */
@@ -162,7 +152,14 @@
162
152
  animation-duration: 0.01ms !important;
163
153
  animation-delay: 0s !important;
164
154
  animation-iteration-count: 1 !important;
165
- transition-duration: 0.01ms !important;
155
+
156
+ /*
157
+ Set to 0s, because `transition-property` defaults to `all`, so any non-zero
158
+ duration gives every element a transition. Libraries that change an
159
+ attribute and measure synchronously (e.g. Plotly hover labels) would read
160
+ stale geometry.
161
+ */
162
+ transition-duration: 0s !important;
166
163
  transition-delay: 0s !important;
167
164
  }
168
165
 
@@ -1,6 +1,5 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  import React, {
3
- type JSX,
4
3
  type PropsWithChildren,
5
4
  useEffect,
6
5
  useMemo,
@@ -28,7 +27,7 @@ export class RoutesPlugin implements IStatelessPlugin<Data> {
28
27
  routes: z.array(z.string()),
29
28
  });
30
29
 
31
- render(props: IStatelessPluginProps<Data>): JSX.Element {
30
+ render(props: IStatelessPluginProps<Data>): React.ReactElement {
32
31
  return <RoutesComponent {...props.data}>{props.children}</RoutesComponent>;
33
32
  }
34
33
  }
@@ -36,7 +35,7 @@ export class RoutesPlugin implements IStatelessPlugin<Data> {
36
35
  const RoutesComponent = ({
37
36
  routes,
38
37
  children,
39
- }: PropsWithChildren<Data>): JSX.Element => {
38
+ }: PropsWithChildren<Data>): React.ReactNode => {
40
39
  const childCount = React.Children.count(children);
41
40
  if (childCount !== routes.length) {
42
41
  throw new Error(
@@ -69,12 +68,11 @@ const RoutesComponent = ({
69
68
  }, [handleFindMatch]);
70
69
 
71
70
  if (!matched) {
72
- // oxlint-disable-next-line react/jsx-no-useless-fragment
73
- return <></>;
71
+ return null;
74
72
  }
75
73
 
76
74
  const matchedIndex = routes.indexOf(matched);
77
75
  const child = React.Children.toArray(children)[matchedIndex];
78
76
 
79
- return <>{child}</>;
77
+ return child;
80
78
  };