@marimo-team/islands 0.25.3-dev222 → 0.25.3-dev223
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/{ErrorBoundary-Cg9q4kUW.js → ErrorBoundary-BToheQV2.js} +1 -1
- package/dist/{code-visibility-Dp-DkL1e.js → code-visibility-CO0hOr56.js} +1 -1
- package/dist/{common-DHr2MXY3.js → common-CV0669k1.js} +1 -1
- package/dist/{data-grid-overlay-editor-B-OJHxuO.js → data-grid-overlay-editor-CwDPMtXI.js} +1 -1
- package/dist/{feedback-button-DGAcA9xH.js → feedback-button-RB_OfVUt.js} +2 -2
- package/dist/{glide-data-editor-09FJOvJw.js → glide-data-editor-B2h5fYfH.js} +3 -3
- package/dist/{globals-2eTRp9qC.js → globals-YR9OeOwq.js} +1 -1
- package/dist/main.js +6 -6
- package/dist/{number-overlay-editor-XJ1jA8Jv.js → number-overlay-editor-BY4yYxfZ.js} +1 -1
- package/dist/{reveal-component-DxdLWQiq.js → reveal-component-GiGQpBMz.js} +2 -2
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/app-config/ai-config.tsx +148 -147
- package/src/components/app-config/app-config-button.tsx +6 -5
- package/src/components/app-config/common.tsx +7 -9
- package/src/components/app-config/data-form.tsx +112 -113
- package/src/components/app-config/mcp-config.tsx +30 -53
- package/src/components/app-config/user-config-form.css +91 -0
- package/src/components/app-config/user-config-form.tsx +236 -298
- package/src/components/editor/actions/__tests__/pair-with-agent-modal.test.tsx +9 -5
- package/src/components/editor/actions/__tests__/pair-with-agent.test.tsx +3 -3
- package/src/components/editor/actions/pair-with-agent-modal.tsx +5 -5
- package/src/components/editor/actions/pair-with-agent.tsx +10 -7
|
@@ -75,113 +75,113 @@ export const DataForm = ({
|
|
|
75
75
|
|
|
76
76
|
return (
|
|
77
77
|
<>
|
|
78
|
-
<
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
<
|
|
84
|
-
<
|
|
85
|
-
|
|
86
|
-
<
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
78
|
+
<SettingGroup title="Data">
|
|
79
|
+
<OverriddenFormField
|
|
80
|
+
control={form.control}
|
|
81
|
+
name="display.dataframes"
|
|
82
|
+
render={({ field, override }) => (
|
|
83
|
+
<div className="settings-field flex flex-col space-y-1">
|
|
84
|
+
<FormItem className={formItemClasses}>
|
|
85
|
+
<FormLabel>Dataframe viewer</FormLabel>
|
|
86
|
+
<FormDescription>
|
|
87
|
+
Whether to use marimo's rich dataframe viewer or a plain HTML
|
|
88
|
+
table. This requires restarting your notebook to take effect.
|
|
89
|
+
</FormDescription>
|
|
90
|
+
<FormControl>
|
|
91
|
+
<NativeSelect
|
|
92
|
+
data-testid="display-dataframes-select"
|
|
93
|
+
onChange={(e) => field.onChange(e.target.value)}
|
|
94
|
+
value={override.value}
|
|
95
|
+
disabled={field.disabled || override.isOverridden}
|
|
96
|
+
className="inline-flex mr-2"
|
|
97
|
+
>
|
|
98
|
+
{["rich", "plain"].map((option) => (
|
|
99
|
+
<option value={option} key={option}>
|
|
100
|
+
{option}
|
|
101
|
+
</option>
|
|
102
|
+
))}
|
|
103
|
+
</NativeSelect>
|
|
104
|
+
</FormControl>
|
|
105
|
+
<FormMessage />
|
|
106
|
+
<IsOverridden override={override} />
|
|
107
|
+
</FormItem>
|
|
108
|
+
</div>
|
|
109
|
+
)}
|
|
110
|
+
/>
|
|
111
|
+
<OverriddenFormField
|
|
112
|
+
control={form.control}
|
|
113
|
+
name="display.default_table_page_size"
|
|
114
|
+
render={({ field, override }) => (
|
|
115
|
+
<div className="settings-field flex flex-col space-y-1">
|
|
116
|
+
<FormItem className={formItemClasses}>
|
|
117
|
+
<FormLabel>Default table page size</FormLabel>
|
|
118
|
+
<FormDescription>
|
|
119
|
+
The default number of rows displayed in dataframes and SQL
|
|
120
|
+
results.
|
|
121
|
+
</FormDescription>
|
|
122
|
+
<FormControl>
|
|
123
|
+
<NumberField
|
|
124
|
+
aria-label="Default table page size"
|
|
125
|
+
data-testid="default-table-page-size-input"
|
|
126
|
+
className="m-0 w-24"
|
|
127
|
+
{...field}
|
|
128
|
+
value={override.value}
|
|
129
|
+
isDisabled={override.isOverridden}
|
|
130
|
+
minValue={1}
|
|
131
|
+
step={1}
|
|
132
|
+
onChange={(value) => {
|
|
133
|
+
field.onChange(value);
|
|
134
|
+
if (!Number.isNaN(value)) {
|
|
135
|
+
onSubmit(form.getValues());
|
|
136
|
+
}
|
|
137
|
+
}}
|
|
138
|
+
/>
|
|
139
|
+
</FormControl>
|
|
140
|
+
<FormMessage />
|
|
141
|
+
<IsOverridden override={override} />
|
|
142
|
+
</FormItem>
|
|
143
|
+
</div>
|
|
144
|
+
)}
|
|
145
|
+
/>
|
|
146
|
+
<OverriddenFormField
|
|
147
|
+
control={form.control}
|
|
148
|
+
name="display.default_table_max_columns"
|
|
149
|
+
render={({ field, override }) => (
|
|
150
|
+
<div className="settings-field flex flex-col space-y-1">
|
|
151
|
+
<FormItem className={formItemClasses}>
|
|
152
|
+
<FormLabel>Default table max columns</FormLabel>
|
|
153
|
+
<FormDescription>
|
|
154
|
+
The default maximum number of columns displayed in dataframes
|
|
155
|
+
and SQL results.
|
|
156
|
+
</FormDescription>
|
|
157
|
+
<FormControl>
|
|
158
|
+
<NumberField
|
|
159
|
+
aria-label="Default table max columns"
|
|
160
|
+
data-testid="default-table-max-columns-input"
|
|
161
|
+
className="m-0 w-24"
|
|
162
|
+
{...field}
|
|
163
|
+
value={override.value}
|
|
164
|
+
isDisabled={override.isOverridden}
|
|
165
|
+
minValue={1}
|
|
166
|
+
step={1}
|
|
167
|
+
onChange={(value) => {
|
|
168
|
+
field.onChange(value);
|
|
169
|
+
if (!Number.isNaN(value)) {
|
|
170
|
+
onSubmit(form.getValues());
|
|
171
|
+
}
|
|
172
|
+
}}
|
|
173
|
+
/>
|
|
174
|
+
</FormControl>
|
|
175
|
+
<FormMessage />
|
|
176
|
+
<IsOverridden override={override} />
|
|
177
|
+
</FormItem>
|
|
178
|
+
</div>
|
|
179
|
+
)}
|
|
180
|
+
/>
|
|
181
|
+
</SettingGroup>
|
|
182
182
|
<SettingGroup title="SQL">
|
|
183
|
-
<div className="flex flex-col gap-1">
|
|
184
|
-
<div className="text-sm text-foreground">
|
|
183
|
+
<div className="settings-field flex flex-col gap-1">
|
|
184
|
+
<div className="text-sm font-semibold text-muted-foreground">
|
|
185
185
|
Database Schema Discovery
|
|
186
186
|
</div>
|
|
187
187
|
<div className="text-sm text-muted-foreground mb-2">
|
|
@@ -212,7 +212,7 @@ export const DataForm = ({
|
|
|
212
212
|
control={form.control}
|
|
213
213
|
name="diagnostics.sql_linter"
|
|
214
214
|
render={({ field, override }) => (
|
|
215
|
-
<div className="flex flex-col space-y-1">
|
|
215
|
+
<div className="settings-field flex flex-col space-y-1">
|
|
216
216
|
<FormItem className={formItemClasses}>
|
|
217
217
|
<FormLabel>SQL Linter</FormLabel>
|
|
218
218
|
<FormControl>
|
|
@@ -237,9 +237,13 @@ export const DataForm = ({
|
|
|
237
237
|
control={form.control}
|
|
238
238
|
name="runtime.default_sql_output"
|
|
239
239
|
render={({ field, override }) => (
|
|
240
|
-
<div className="flex flex-col space-y-1">
|
|
240
|
+
<div className="settings-field flex flex-col space-y-1">
|
|
241
241
|
<FormItem className={formItemClasses}>
|
|
242
242
|
<FormLabel>Default SQL output</FormLabel>
|
|
243
|
+
<FormDescription>
|
|
244
|
+
The default SQL output type for new notebooks; overridden by
|
|
245
|
+
"sql_output" in the application config.
|
|
246
|
+
</FormDescription>
|
|
243
247
|
<FormControl>
|
|
244
248
|
<NativeSelect
|
|
245
249
|
data-testid="user-config-sql-output-select"
|
|
@@ -258,11 +262,6 @@ export const DataForm = ({
|
|
|
258
262
|
<FormMessage />
|
|
259
263
|
<IsOverridden override={override} />
|
|
260
264
|
</FormItem>
|
|
261
|
-
|
|
262
|
-
<FormDescription>
|
|
263
|
-
The default SQL output type for new notebooks; overridden by
|
|
264
|
-
"sql_output" in the application config.
|
|
265
|
-
</FormDescription>
|
|
266
265
|
</div>
|
|
267
266
|
)}
|
|
268
267
|
/>
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { Loader2, RefreshCwIcon } from "lucide-react";
|
|
4
4
|
import React from "react";
|
|
5
5
|
import type { UseFormReturn } from "react-hook-form";
|
|
6
|
+
import { Checkbox } from "@/components/ui/checkbox";
|
|
6
7
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} from "@/components/ui/
|
|
13
|
-
import { FormField, FormItem } from "@/components/ui/form";
|
|
8
|
+
FormControl,
|
|
9
|
+
FormDescription,
|
|
10
|
+
FormField,
|
|
11
|
+
FormItem,
|
|
12
|
+
FormLabel,
|
|
13
|
+
} from "@/components/ui/form";
|
|
14
14
|
import type { UserConfig } from "@/core/config/config-schema";
|
|
15
15
|
import { useMCPRefresh, useMCPStatus } from "../mcp/hooks";
|
|
16
16
|
import { McpStatusText } from "../mcp/mcp-status-indicator";
|
|
17
17
|
import { Button } from "../ui/button";
|
|
18
18
|
import { Kbd } from "../ui/kbd";
|
|
19
|
-
import { SettingSubtitle } from "./common";
|
|
19
|
+
import { formItemClasses, SettingSubtitle } from "./common";
|
|
20
20
|
import { useOpenSettingsToTab } from "./state";
|
|
21
21
|
|
|
22
22
|
interface MCPConfigProps {
|
|
@@ -35,13 +35,14 @@ interface PresetConfig {
|
|
|
35
35
|
const PRESET_CONFIGS: PresetConfig[] = [
|
|
36
36
|
{
|
|
37
37
|
id: "marimo",
|
|
38
|
-
title: "marimo
|
|
39
|
-
description: "
|
|
38
|
+
title: "marimo documentation",
|
|
39
|
+
description: "Let the AI assistant look up marimo documentation.",
|
|
40
40
|
},
|
|
41
41
|
{
|
|
42
42
|
id: "context7",
|
|
43
43
|
title: "Context7",
|
|
44
|
-
description:
|
|
44
|
+
description:
|
|
45
|
+
"Let the AI assistant look up current documentation and code examples for third-party libraries using Context7.",
|
|
45
46
|
},
|
|
46
47
|
];
|
|
47
48
|
|
|
@@ -58,12 +59,13 @@ export const MCPConfig: React.FC<MCPConfigProps> = ({ form, onSubmit }) => {
|
|
|
58
59
|
return (
|
|
59
60
|
<div className="flex flex-col gap-4">
|
|
60
61
|
<div className="flex items-center justify-between">
|
|
61
|
-
<SettingSubtitle>MCP
|
|
62
|
+
<SettingSubtitle>MCP servers</SettingSubtitle>
|
|
62
63
|
<div className="flex items-center gap-2">
|
|
63
64
|
{status && <McpStatusText status={status.status} />}
|
|
64
65
|
<Button
|
|
65
66
|
variant="outline"
|
|
66
67
|
size="xs"
|
|
68
|
+
aria-label="Refresh MCP servers"
|
|
67
69
|
onClick={handleRefresh}
|
|
68
70
|
disabled={isRefreshing || isFetching}
|
|
69
71
|
>
|
|
@@ -101,7 +103,7 @@ export const MCPConfig: React.FC<MCPConfigProps> = ({ form, onSubmit }) => {
|
|
|
101
103
|
onClick={() => handleClick("optionalDeps")}
|
|
102
104
|
size="xs"
|
|
103
105
|
>
|
|
104
|
-
Optional
|
|
106
|
+
Optional features
|
|
105
107
|
</Button>{" "}
|
|
106
108
|
for more details.
|
|
107
109
|
</p>
|
|
@@ -121,45 +123,20 @@ export const MCPConfig: React.FC<MCPConfigProps> = ({ form, onSubmit }) => {
|
|
|
121
123
|
};
|
|
122
124
|
|
|
123
125
|
return (
|
|
124
|
-
<
|
|
125
|
-
|
|
126
|
-
{
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
>
|
|
139
|
-
<CardHeader>
|
|
140
|
-
<div className="flex items-start justify-between">
|
|
141
|
-
<CardTitle className="text-base">
|
|
142
|
-
{config.title}
|
|
143
|
-
</CardTitle>
|
|
144
|
-
<span
|
|
145
|
-
className={`h-5 w-5 flex items-center justify-center rounded border ${
|
|
146
|
-
isChecked
|
|
147
|
-
? "border-(--blue-7) bg-(--blue-7) text-foreground"
|
|
148
|
-
: "border-muted bg-background text-muted-foreground"
|
|
149
|
-
}`}
|
|
150
|
-
>
|
|
151
|
-
{isChecked ? <CheckSquareIcon /> : null}
|
|
152
|
-
</span>
|
|
153
|
-
</div>
|
|
154
|
-
</CardHeader>
|
|
155
|
-
<CardContent>
|
|
156
|
-
<CardDescription>{config.description}</CardDescription>
|
|
157
|
-
</CardContent>
|
|
158
|
-
</Card>
|
|
159
|
-
);
|
|
160
|
-
})}
|
|
161
|
-
</div>
|
|
162
|
-
</FormItem>
|
|
126
|
+
<div className="flex flex-col gap-6">
|
|
127
|
+
{PRESET_CONFIGS.map((config) => (
|
|
128
|
+
<FormItem key={config.id} className={formItemClasses}>
|
|
129
|
+
<FormLabel>{config.title}</FormLabel>
|
|
130
|
+
<FormControl>
|
|
131
|
+
<Checkbox
|
|
132
|
+
checked={presets.includes(config.id)}
|
|
133
|
+
onCheckedChange={() => togglePreset(config.id)}
|
|
134
|
+
/>
|
|
135
|
+
</FormControl>
|
|
136
|
+
<FormDescription>{config.description}</FormDescription>
|
|
137
|
+
</FormItem>
|
|
138
|
+
))}
|
|
139
|
+
</div>
|
|
163
140
|
);
|
|
164
141
|
}}
|
|
165
142
|
/>
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
.user-config-form .settings-group {
|
|
4
|
+
gap: 1.5rem;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.user-config-form .settings-group > h3 {
|
|
8
|
+
margin-bottom: -0.75rem;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.user-config-form .settings-group + .settings-group {
|
|
12
|
+
border-top: 1px solid var(--border);
|
|
13
|
+
padding-top: 1.5rem;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.user-config-form .settings-row {
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
align-items: flex-start;
|
|
20
|
+
gap: 0.25rem;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.user-config-form .settings-row > * {
|
|
24
|
+
min-width: 0;
|
|
25
|
+
max-width: 100%;
|
|
26
|
+
margin: 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.user-config-form label {
|
|
30
|
+
font-weight: 600;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.user-config-form label:not(.text-destructive) {
|
|
34
|
+
color: var(--muted-foreground);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.user-config-form .settings-row > label {
|
|
38
|
+
width: auto;
|
|
39
|
+
line-height: 1.5;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.user-config-form .settings-row > label + p {
|
|
43
|
+
margin-bottom: 0.25rem;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.user-config-form .settings-row > select {
|
|
47
|
+
width: auto;
|
|
48
|
+
min-width: min(100%, 8rem);
|
|
49
|
+
height: 1.75rem;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.user-config-form .settings-row:has(> [role="checkbox"]) {
|
|
53
|
+
display: grid;
|
|
54
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
55
|
+
align-items: center;
|
|
56
|
+
column-gap: 0.5rem;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.user-config-form .settings-row > [role="checkbox"] {
|
|
60
|
+
grid-column: 1;
|
|
61
|
+
grid-row: 1;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.user-config-form .settings-row:has(> [role="checkbox"]) > label {
|
|
65
|
+
grid-column: 2;
|
|
66
|
+
grid-row: 1;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.user-config-form .settings-row:has(> [role="checkbox"]) > :nth-child(n + 3) {
|
|
70
|
+
grid-column: 1 / -1;
|
|
71
|
+
justify-self: start;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.user-config-form p {
|
|
75
|
+
line-height: 1.5;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.user-config-form :is(.settings-field, .settings-row) {
|
|
79
|
+
border-radius: 0.375rem;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.user-config-form
|
|
83
|
+
:is(.settings-field, .settings-row):is(:hover, :focus-within) {
|
|
84
|
+
background-color: color-mix(in srgb, var(--muted) 50%, transparent);
|
|
85
|
+
box-shadow: 0 0 0 0.5rem color-mix(in srgb, var(--muted) 50%, transparent);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.user-config-form .settings-field .settings-row:is(:hover, :focus-within) {
|
|
89
|
+
background-color: transparent;
|
|
90
|
+
box-shadow: none;
|
|
91
|
+
}
|