@marimo-team/islands 0.23.15 → 0.23.16-dev2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marimo-team/islands",
3
- "version": "0.23.15",
3
+ "version": "0.23.16-dev2",
4
4
  "main": "dist/main.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -1,17 +1,31 @@
1
1
  /* Copyright 2026 Marimo. All rights reserved. */
2
2
  import { memo } from "react";
3
3
  import type { Intent } from "@/plugins/impl/common/intent";
4
- import { calloutStyles } from "./CalloutOutput.styles";
4
+ import { cn } from "@/utils/cn";
5
5
  import { HtmlOutput } from "./HtmlOutput";
6
6
 
7
7
  interface Props {
8
8
  html: string;
9
9
  kind: Intent;
10
+ title?: string;
10
11
  }
11
12
 
12
- export const CalloutOutput: React.FC<Props> = memo(({ html, kind }) => {
13
+ // Callouts share the flat admonition style of markdown admonitions
14
+ // (css/admonition.css); each intent maps onto an admonition kind.
15
+ const KIND_CLASS: Record<Intent, string> = {
16
+ neutral: "neutral",
17
+ info: "info",
18
+ warn: "warning",
19
+ success: "success",
20
+ danger: "danger",
21
+ // 'alert' is deprecated; render as danger
22
+ alert: "danger",
23
+ };
24
+
25
+ export const CalloutOutput: React.FC<Props> = memo(({ html, kind, title }) => {
13
26
  return (
14
- <div className={calloutStyles({ kind })}>
27
+ <div className={cn("admonition", KIND_CLASS[kind])}>
28
+ {title && <span className="admonition-title">{title}</span>}
15
29
  <HtmlOutput html={html} alwaysSanitizeHtml={true} />
16
30
  </div>
17
31
  );
@@ -1,32 +1,53 @@
1
1
  @reference "../css/globals.css";
2
2
 
3
+ /*
4
+ * Flat, GitHub-style admonitions.
5
+ *
6
+ * Icons are lucide (https://lucide.dev/icons/) data URIs applied as masks so
7
+ * they render in currentColor.
8
+ */
9
+
3
10
  .admonition {
4
- --admonition-bg: var(--blue-2);
5
- --admonition-border: var(--blue-8);
6
11
  --admonition-heading-color: var(--blue-11);
12
+ --admonition-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-info"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>');
7
13
 
8
14
  display: flex;
9
- position: relative;
10
15
  flex-direction: column;
11
- padding: 1rem;
12
- padding-left: 3rem;
13
- border-left: 4px solid;
16
+ padding: 0.5rem 1rem;
17
+ border-left: 0.25rem solid var(--admonition-heading-color);
14
18
  margin-bottom: 1rem;
15
- background-color: var(--admonition-bg);
16
- border-color: var(--admonition-border);
17
19
 
18
- &::before {
19
- position: absolute;
20
- margin-top: 0.35rem;
21
- margin-left: -2rem;
20
+ /* Tighten the gap between the title and body (md.css gives paragraphs a
21
+ 1rem block margin; flex children don't collapse margins). */
22
+ & > .paragraph,
23
+ & > p {
24
+ margin-block: 0.375rem;
25
+ }
26
+
27
+ /* The paragraph right after the title hugs it, matching callouts, whose
28
+ body is nested in a wrapper and gets the md.css :first-child treatment. */
29
+ & > .admonition-title + .paragraph,
30
+ & > .admonition-title + p {
31
+ margin-block-start: 0;
22
32
  }
23
33
  }
24
34
 
25
35
  .admonition-title {
26
- font-weight: bold;
36
+ display: block;
37
+ margin-bottom: 0.25rem;
38
+ font-weight: 600;
27
39
  color: var(--admonition-heading-color);
28
40
 
29
- @apply tracking-wide;
41
+ &::before {
42
+ content: "";
43
+ display: inline-block;
44
+ width: 1rem;
45
+ height: 1rem;
46
+ margin-right: 0.5rem;
47
+ vertical-align: -0.125rem;
48
+ background-color: currentcolor;
49
+ mask: var(--admonition-icon) no-repeat center / contain;
50
+ }
30
51
 
31
52
  > .paragraph {
32
53
  margin: 0;
@@ -38,90 +59,50 @@
38
59
  }
39
60
  }
40
61
 
41
- /* Icons from https://lucide.dev/icons/ */
42
-
43
62
  .admonition.info,
44
63
  .admonition.note {
45
- --admonition-bg: var(--blue-2);
46
- --admonition-border: var(--blue-8);
47
64
  --admonition-heading-color: var(--blue-11);
48
-
49
- &::before {
50
- content: light-dark(
51
- url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" opacity="60%" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="admonition-icon lucide lucide-info"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>'),
52
- url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" opacity="60%" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="admonition-icon lucide lucide-info"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>')
53
- );
54
- }
65
+ --admonition-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-info"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>');
55
66
  }
56
67
 
57
68
  .admonition.danger,
58
69
  .admonition.caution,
59
70
  .admonition.error {
60
- --admonition-bg: var(--red-2);
61
- --admonition-border: var(--red-8);
62
71
  --admonition-heading-color: var(--red-11);
63
-
64
- &::before {
65
- content: light-dark(
66
- url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" opacity="60%" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-octagon-alert"><polygon points="7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2"/><line x1="12" x2="12" y1="8" y2="12"/><line x1="12" x2="12.01" y1="16" y2="16"/></svg>'),
67
- url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" opacity="60%" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-octagon-alert"><polygon points="7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2"/><line x1="12" x2="12" y1="8" y2="12"/><line x1="12" x2="12.01" y1="16" y2="16"/></svg>')
68
- );
69
- }
72
+ --admonition-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-octagon-alert"><polygon points="7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2"/><line x1="12" x2="12" y1="8" y2="12"/><line x1="12" x2="12.01" y1="16" y2="16"/></svg>');
70
73
  }
71
74
 
72
75
  .admonition.attention,
73
76
  .admonition.warning {
74
- --admonition-bg: var(--yellow-2);
75
- --admonition-border: var(--yellow-8);
76
77
  --admonition-heading-color: var(--yellow-11);
77
-
78
- &::before {
79
- content: light-dark(
80
- url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" opacity="60%" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-triangle-alert"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>'),
81
- url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" opacity="60%" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-triangle-alert"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>')
82
- );
83
- }
78
+ --admonition-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-triangle-alert"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>');
84
79
  }
85
80
 
86
81
  .admonition.hint {
87
- --admonition-bg: var(--gray-2);
88
- --admonition-border: var(--gray-8);
89
82
  --admonition-heading-color: var(--gray-11);
90
-
91
- .dark & {
92
- --admonition-bg: var(--gray-3);
93
- }
94
-
95
- &::before {
96
- content: light-dark(
97
- url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" opacity="60%" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-info"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>'),
98
- url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" opacity="60%" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-info"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>')
99
- );
100
- }
83
+ --admonition-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-info"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>');
101
84
  }
102
85
 
103
86
  .admonition.important {
104
- --admonition-bg: var(--cyan-2);
105
- --admonition-border: var(--cyan-8);
106
87
  --admonition-heading-color: var(--cyan-11);
88
+ --admonition-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-message-square-warning"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/><path d="M12 7v2"/><path d="M12 13h.01"/></svg>');
89
+ }
107
90
 
108
- &::before {
109
- content: light-dark(
110
- url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" opacity="60%" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-message-square-warning"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/><path d="M12 7v2"/><path d="M12 13h.01"/></svg>'),
111
- url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" opacity="60%" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-message-square-warning"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/><path d="M12 7v2"/><path d="M12 13h.01"/></svg>')
112
- );
113
- }
91
+ .admonition.success {
92
+ --admonition-heading-color: var(--grass-11);
93
+ --admonition-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-circle-check"><circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/></svg>');
114
94
  }
115
95
 
116
96
  .admonition.tip {
117
- --admonition-bg: var(--grass-2);
118
- --admonition-border: var(--grass-8);
119
97
  --admonition-heading-color: var(--grass-11);
98
+ --admonition-icon: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-lightbulb"><path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/></svg>');
99
+ }
120
100
 
121
- &::before {
122
- content: light-dark(
123
- url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" opacity="60%" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-lightbulb"><path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/></svg>'),
124
- url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" opacity="60%" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-lightbulb"><path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/></svg>')
125
- );
101
+ /* Quiet, icon-less variant used by neutral callouts. */
102
+ .admonition.neutral {
103
+ --admonition-heading-color: var(--gray-11);
104
+
105
+ .admonition-title::before {
106
+ content: none;
126
107
  }
127
108
  }
@@ -18,6 +18,10 @@ interface Data {
18
18
  * The kind of callout
19
19
  */
20
20
  kind: Intent;
21
+ /**
22
+ * An optional bold title line
23
+ */
24
+ title?: string;
21
25
  }
22
26
 
23
27
  export class CalloutPlugin implements IStatelessPlugin<Data> {
@@ -26,9 +30,12 @@ export class CalloutPlugin implements IStatelessPlugin<Data> {
26
30
  validator = z.object({
27
31
  html: z.string(),
28
32
  kind: zodIntent,
33
+ title: z.string().optional(),
29
34
  });
30
35
 
31
36
  render({ data }: IStatelessPluginProps<Data>): JSX.Element {
32
- return <CalloutOutput html={data.html} kind={data.kind} />;
37
+ return (
38
+ <CalloutOutput html={data.html} kind={data.kind} title={data.title} />
39
+ );
33
40
  }
34
41
  }
@@ -71,3 +71,15 @@ export const Success = {
71
71
 
72
72
  name: "success",
73
73
  };
74
+
75
+ export const WithTitle = {
76
+ render: () => (
77
+ <CalloutOutput
78
+ html="<p>CalloutOutput with a title and <strong>HTML</strong></p>"
79
+ kind="warn"
80
+ title="Watch out"
81
+ />
82
+ ),
83
+
84
+ name: "with title",
85
+ };
@@ -1,22 +0,0 @@
1
- /* Copyright 2026 Marimo. All rights reserved. */
2
- import { cva } from "class-variance-authority";
3
-
4
- export const calloutStyles = cva(
5
- "border rounded-lg p-12 mt-12 mb-12 text-foreground shadow-[4px_4px_0px_0px]",
6
- {
7
- variants: {
8
- kind: {
9
- neutral: "border-(--slate-9) shadow-(color:--slate-8)",
10
- // @deprecated, use danger instead
11
- alert: "bg-(--red-2) border-(--red-9) shadow-(color:--red-8)",
12
- info: "bg-(--sky-1) border-(--sky-8) shadow-(color:--sky-7)",
13
- danger: "bg-(--red-2) border-(--red-9) shadow-(color:--red-8)",
14
- warn: "bg-(--amber-2) border-(--amber-9) shadow-(color:--amber-8)",
15
- success: "bg-(--grass-2) border-(--grass-9) shadow-(color:--grass-8)",
16
- },
17
- },
18
- defaultVariants: {
19
- kind: "neutral",
20
- },
21
- },
22
- );