@marimo-team/islands 0.23.12-dev2 → 0.23.12-dev21
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/{ConnectedDataExplorerComponent-WqG-xX4l.js → ConnectedDataExplorerComponent-Du3_nUzI.js} +13 -13
- package/dist/{ErrorBoundary-BNx_OSVo.js → ErrorBoundary-DE6tzZf-.js} +2 -2
- package/dist/{any-language-editor-rPSlOll9.js → any-language-editor-DN1R-1KZ.js} +5 -5
- package/dist/{button-vQhauTmO.js → button-BacYv-bE.js} +7 -1
- package/dist/{capabilities-BEHzIS99.js → capabilities-D_4LYhSU.js} +1 -1
- package/dist/{chat-ui-k2kqhCv5.js → chat-ui-CsPewo4h.js} +16 -16
- package/dist/{check-nrzHDi45.js → check-C9OoNtR4.js} +1 -1
- package/dist/{code-visibility-DZ_6U5hT.js → code-visibility-DBnAQPtB.js} +664 -663
- package/dist/{copy-UhDed7D4.js → copy-COam1EG7.js} +2 -2
- package/dist/{dist-DYGLrbYQ.js → dist--2Bqjvs0.js} +2 -2
- package/dist/{error-banner-BHAkVFc2.js → error-banner-DFPfz_Qf.js} +2 -2
- package/dist/{esm-Bqu9AE2K.js → esm-M837UxV5.js} +1 -1
- package/dist/{extends-9Yl5BEcg.js → extends-9MVIxxRo.js} +4 -4
- package/dist/{formats-BV4bOfMI.js → formats-d6MhLuQ9.js} +4 -4
- package/dist/{glide-data-editor-BDTq6YUb.js → glide-data-editor-DkzAInWG.js} +9 -9
- package/dist/{html-to-image-C86pQALH.js → html-to-image-DXwLcQ6l.js} +95 -88
- package/dist/{input-AKkGXdyV.js → input-CbEz_aj_.js} +6 -6
- package/dist/{label-E3ZJXHu8.js → label-WfTSU8L4.js} +2 -2
- package/dist/{loader-YPuQvn1Y.js → loader-Boph2xIS.js} +1 -1
- package/dist/main.js +1753 -1626
- package/dist/{mermaid-QFAR9YgY.js → mermaid-CJW9vIyO.js} +5 -5
- package/dist/{process-output-nNw4OpSj.js → process-output-C6_e1pT_.js} +3 -3
- package/dist/{reveal-component-BxDb5eK0.js → reveal-component-DIzKQ1NS.js} +11 -11
- package/dist/{spec-B45_YCNI.js → spec-Bv-XlYiv.js} +4 -4
- package/dist/{strings-Cq2s9_EQ.js → strings-Dq_j3Rxw.js} +4 -4
- package/dist/style.css +2 -2
- package/dist/{swiper-component-BNa_4kh2.js → swiper-component-5HoSsPi1.js} +2 -2
- package/dist/{toDate-Do1xRzAo.js → toDate-D-l5s8nn.js} +3 -3
- package/dist/{tooltip-Bz3OAwrU.js → tooltip-Czds6Qr8.js} +3 -3
- package/dist/{types-D8gEGs4R.js → types-C2Ir191_.js} +1 -1
- package/dist/{useAsyncData-CL3o2p4i.js → useAsyncData-1Dhzjfwf.js} +1 -1
- package/dist/{useDateFormatter-BC6iSz9g.js → useDateFormatter-CMnRuVmN.js} +2 -2
- package/dist/{useDeepCompareMemoize-BPx2MuOK.js → useDeepCompareMemoize-CDWT3BDz.js} +1 -1
- package/dist/{useIframeCapabilities-C6Ta3EyP.js → useIframeCapabilities-DWIYvDh7.js} +1 -1
- package/dist/{useLifecycle-C3Ec71q0.js → useLifecycle-AHlswLw-.js} +3 -3
- package/dist/{useTheme-ZhT6uIu3.js → useTheme-BrYvK-_A.js} +2 -2
- package/dist/{vega-component-C3AWYGAL.js → vega-component-Pk6lyc_a.js} +10 -10
- package/dist/{zod-DXqkaI_w.js → zod-CijjQh4u.js} +1 -1
- package/package.json +3 -3
- package/src/components/ai/display-helpers.tsx +5 -5
- package/src/components/app-config/ai-config.tsx +5 -5
- package/src/components/app-config/mcp-config.tsx +3 -3
- package/src/components/chat/acp/agent-panel.tsx +3 -3
- package/src/components/chat/acp/blocks.tsx +36 -38
- package/src/components/chat/acp/common.tsx +12 -16
- package/src/components/chat/acp/scroll-to-bottom-button.tsx +1 -1
- package/src/components/chat/acp/session-tabs.tsx +2 -2
- package/src/components/chat/chat-history-popover.tsx +1 -1
- package/src/components/chat/chat-panel.tsx +47 -23
- package/src/components/data-table/TableBottomBar.tsx +4 -1
- package/src/components/data-table/columns.tsx +2 -2
- package/src/components/data-table/data-table.tsx +26 -17
- package/src/components/data-table/filter-pill-editor.tsx +1 -1
- package/src/components/dependency-graph/minimap-content.tsx +1 -1
- package/src/components/editor/RecoveryButton.tsx +1 -1
- package/src/components/editor/actions/pair-with-agent-modal.tsx +2 -2
- package/src/components/editor/actions/useNotebookActions.tsx +4 -4
- package/src/components/editor/ai/__tests__/completion-utils.test.ts +138 -2
- package/src/components/editor/ai/ai-completion-editor.tsx +1 -1
- package/src/components/editor/ai/completion-utils.ts +124 -21
- package/src/components/editor/cell/CreateCellButton.tsx +1 -1
- package/src/components/editor/chrome/panels/empty-state.tsx +1 -1
- package/src/components/editor/chrome/panels/outline/floating-outline.tsx +1 -1
- package/src/components/editor/chrome/wrapper/pending-ai-cells.tsx +1 -1
- package/src/components/editor/columns/cell-column.tsx +1 -1
- package/src/components/editor/columns/sortable-column.tsx +2 -2
- package/src/components/editor/output/MarimoErrorOutput.tsx +1 -1
- package/src/components/editor/output/TextOutput.tsx +2 -2
- package/src/components/home/components.tsx +4 -4
- package/src/components/icons/github.tsx +21 -0
- package/src/components/icons/youtube.tsx +21 -0
- package/src/components/slides/minimap.tsx +2 -2
- package/src/components/slides/reveal-component.tsx +1 -1
- package/src/components/storage/components.tsx +3 -7
- package/src/components/ui/alert.tsx +1 -1
- package/src/components/ui/command.tsx +2 -2
- package/src/components/ui/reorderable-list.tsx +1 -1
- package/src/components/ui/table.tsx +2 -5
- package/src/core/codemirror/go-to-definition/__tests__/commands.test.ts +67 -0
- package/src/core/codemirror/go-to-definition/__tests__/utils.test.ts +47 -0
- package/src/core/codemirror/go-to-definition/commands.ts +47 -30
- package/src/core/codemirror/go-to-definition/utils.ts +0 -1
- package/src/core/codemirror/language/languages/sql/renderers.tsx +60 -68
- package/src/core/codemirror/reactive-references/__tests__/analyzer.test.ts +54 -0
- package/src/core/codemirror/reactive-references/analyzer.ts +44 -35
- package/src/core/hotkeys/hotkeys.ts +1 -0
- package/src/core/islands/__tests__/bridge.test.ts +25 -0
- package/src/core/islands/__tests__/parse.test.ts +585 -1
- package/src/core/islands/__tests__/test-utils.tsx +10 -1
- package/src/core/islands/bridge.ts +6 -1
- package/src/core/islands/constants.ts +2 -0
- package/src/core/islands/parse.ts +293 -13
- package/src/plugins/impl/DataTablePlugin.tsx +20 -1
- package/src/plugins/impl/FileBrowserPlugin.tsx +165 -74
- package/src/plugins/impl/MatrixPlugin.tsx +2 -2
- package/src/plugins/impl/TabsPlugin.tsx +1 -1
- package/src/plugins/impl/__tests__/DataTablePlugin.test.tsx +141 -1
- package/src/plugins/impl/__tests__/FileBrowserPlugin.test.tsx +314 -0
- package/src/plugins/impl/anywidget/AnyWidgetPlugin.tsx +4 -1
- package/src/plugins/impl/anywidget/__tests__/AnyWidgetPlugin.test.tsx +34 -0
- package/src/plugins/impl/anywidget/__tests__/model.test.ts +19 -0
- package/src/plugins/impl/anywidget/model.ts +15 -0
- package/src/plugins/impl/matplotlib/matplotlib-renderer.ts +1 -1
- package/src/plugins/impl/mpl-interactive/MplInteractivePlugin.tsx +155 -98
- package/src/plugins/impl/mpl-interactive/__tests__/MplInteractivePlugin.test.tsx +154 -1
- package/src/plugins/impl/mpl-interactive/mpl-websocket-shim.ts +10 -0
|
@@ -307,33 +307,52 @@ function collectMatchingDeclarations(
|
|
|
307
307
|
break;
|
|
308
308
|
}
|
|
309
309
|
case "ImportStatement": {
|
|
310
|
+
// The grammar emits one ImportStatement for both `import x [as y]` and
|
|
311
|
+
// `from m import x [as y], ...`. Direct children include the keywords
|
|
312
|
+
// (`from`/`import`/`as`), commas, dots, and every VariableName from the
|
|
313
|
+
// module path AND the import list. We only want the names that actually
|
|
314
|
+
// bind in the current scope: the post-`as` alias if present, otherwise
|
|
315
|
+
// the imported name itself. Names before `import` (the from-path) and
|
|
316
|
+
// the original name when an alias follows it are NOT bindings.
|
|
310
317
|
const subCursor = node.cursor();
|
|
311
318
|
subCursor.firstChild();
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
319
|
+
let pastImport = false;
|
|
320
|
+
// Buffer the most recent post-`import` VariableName so we can defer
|
|
321
|
+
// committing it until we know whether `as` follows.
|
|
322
|
+
let pending: { from: number; matches: boolean } | null = null;
|
|
323
|
+
const commit = () => {
|
|
324
|
+
if (pending?.matches) {
|
|
325
|
+
addDeclaration(declarations, currentScope, pending.from);
|
|
318
326
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}
|
|
322
|
-
case "ImportFromStatement": {
|
|
323
|
-
const subCursor = node.cursor();
|
|
324
|
-
subCursor.firstChild();
|
|
325
|
-
let foundImport = false;
|
|
327
|
+
pending = null;
|
|
328
|
+
};
|
|
326
329
|
do {
|
|
327
330
|
if (subCursor.name === "import") {
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
331
|
+
pastImport = true;
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
if (!pastImport) {
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
if (subCursor.name === "as") {
|
|
338
|
+
// Next VariableName is the alias and replaces `pending`.
|
|
339
|
+
pending = null;
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
if (subCursor.name === "VariableName") {
|
|
343
|
+
// Flush any previous pending name (no `as` followed it).
|
|
344
|
+
commit();
|
|
345
|
+
pending = {
|
|
346
|
+
from: subCursor.from,
|
|
347
|
+
matches:
|
|
348
|
+
state.doc.sliceString(subCursor.from, subCursor.to) ===
|
|
349
|
+
variableName,
|
|
350
|
+
};
|
|
351
|
+
} else if (subCursor.name === ",") {
|
|
352
|
+
commit();
|
|
335
353
|
}
|
|
336
354
|
} while (subCursor.nextSibling());
|
|
355
|
+
commit();
|
|
337
356
|
break;
|
|
338
357
|
}
|
|
339
358
|
case "TryStatement":
|
|
@@ -410,23 +429,21 @@ function findScopedDefinitionPosition(
|
|
|
410
429
|
* @param view The editor view which contains the variable name.
|
|
411
430
|
* @param variableName The name of the variable to select, if found in the editor.
|
|
412
431
|
* @param usagePosition The position of the variable usage, if available.
|
|
413
|
-
* @param fallbackToFirstMatch Whether to fall back to the first matching
|
|
414
|
-
* variable name when no scoped definition is found. Defaults to true.
|
|
415
432
|
*/
|
|
416
433
|
export function goToVariableDefinition(
|
|
417
434
|
view: EditorView,
|
|
418
435
|
variableName: string,
|
|
419
436
|
usagePosition?: number,
|
|
420
|
-
fallbackToFirstMatch = true,
|
|
421
437
|
): boolean {
|
|
422
438
|
const { state } = view;
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
439
|
+
// When the caller knows the usage position, trust the scoped lookup. Falling
|
|
440
|
+
// back to first-match would defeat the local-vs-cross-cell decision in
|
|
441
|
+
// goToDefinition: if the symbol only appears as a module path in an import,
|
|
442
|
+
// scoped resolution returns null and we want the caller to try other cells.
|
|
443
|
+
const from =
|
|
444
|
+
usagePosition !== undefined
|
|
445
|
+
? findScopedDefinitionPosition(state, variableName, usagePosition)
|
|
446
|
+
: findFirstMatchingVariable(state, variableName);
|
|
430
447
|
|
|
431
448
|
if (from === null) {
|
|
432
449
|
return false;
|
|
@@ -34,22 +34,22 @@ const PREVIEW_ITEM_LIMIT = 5;
|
|
|
34
34
|
|
|
35
35
|
// Color mappings for data types (Tailwind-safe)
|
|
36
36
|
const DATA_TYPE_COLORS: Record<DataType, string> = {
|
|
37
|
-
boolean: "bg-
|
|
38
|
-
date: "bg-
|
|
39
|
-
time: "bg-
|
|
40
|
-
datetime: "bg-
|
|
41
|
-
number: "bg-
|
|
42
|
-
integer: "bg-
|
|
43
|
-
string: "bg-
|
|
44
|
-
unknown: "bg-
|
|
37
|
+
boolean: "bg-(--orange-4) text-(--orange-11)",
|
|
38
|
+
date: "bg-(--grass-4) text-(--grass-11)",
|
|
39
|
+
time: "bg-(--grass-4) text-(--grass-11)",
|
|
40
|
+
datetime: "bg-(--grass-4) text-(--grass-11)",
|
|
41
|
+
number: "bg-(--purple-4) text-(--purple-11)",
|
|
42
|
+
integer: "bg-(--purple-4) text-(--purple-11)",
|
|
43
|
+
string: "bg-(--blue-4) text-(--blue-11)",
|
|
44
|
+
unknown: "bg-(--slate-4) text-(--slate-11)",
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
// Source type colors
|
|
48
48
|
const SOURCE_TYPE_COLORS = {
|
|
49
|
-
local: "bg-
|
|
50
|
-
duckdb: "bg-
|
|
51
|
-
connection: "bg-
|
|
52
|
-
catalog: "bg-
|
|
49
|
+
local: "bg-(--blue-4) text-(--blue-11)",
|
|
50
|
+
duckdb: "bg-(--amber-4) text-(--amber-11)",
|
|
51
|
+
connection: "bg-(--green-4) text-(--green-11)",
|
|
52
|
+
catalog: "bg-(--purple-4) text-(--purple-11)",
|
|
53
53
|
} as const;
|
|
54
54
|
|
|
55
55
|
const CONTAINER_STYLES = "p-3 min-w-[250px] flex flex-col divide-y";
|
|
@@ -78,7 +78,7 @@ const MetadataRow: React.FC<{
|
|
|
78
78
|
value: React.ReactNode;
|
|
79
79
|
}> = ({ label, value }) => (
|
|
80
80
|
<div className="flex items-center justify-between text-xs">
|
|
81
|
-
<span className="text-
|
|
81
|
+
<span className="text-(--slate-11)">{label}:</span>
|
|
82
82
|
{value}
|
|
83
83
|
</div>
|
|
84
84
|
);
|
|
@@ -89,7 +89,7 @@ const StatisticItem: React.FC<{
|
|
|
89
89
|
}> = ({ icon, text }) => (
|
|
90
90
|
<div className="flex items-center gap-1">
|
|
91
91
|
{icon}
|
|
92
|
-
<span className="text-xs text-
|
|
92
|
+
<span className="text-xs text-(--slate-11)">{text}</span>
|
|
93
93
|
</div>
|
|
94
94
|
);
|
|
95
95
|
|
|
@@ -109,14 +109,12 @@ const PreviewList: React.FC<{
|
|
|
109
109
|
return (
|
|
110
110
|
<div className="py-2">
|
|
111
111
|
{title && (
|
|
112
|
-
<h4 className="text-xs font-medium text-
|
|
113
|
-
{title}:
|
|
114
|
-
</h4>
|
|
112
|
+
<h4 className="text-xs font-medium text-(--slate-11) mb-2">{title}:</h4>
|
|
115
113
|
)}
|
|
116
114
|
<div className="flex flex-col gap-1 overflow-y-auto">
|
|
117
115
|
{visibleItems}
|
|
118
116
|
{hasMore && (
|
|
119
|
-
<div className="text-xs text-
|
|
117
|
+
<div className="text-xs text-(--slate-10) text-center py-1">
|
|
120
118
|
... and {totalCount - limit} more
|
|
121
119
|
</div>
|
|
122
120
|
)}
|
|
@@ -132,9 +130,9 @@ const getDataTypeColorClass = (dataType: DataType): string => {
|
|
|
132
130
|
export const renderTableInfo = (table: DataTable): React.ReactNode => {
|
|
133
131
|
const tableIcon =
|
|
134
132
|
table.type === "view" ? (
|
|
135
|
-
<ViewIcon className="w-4 h-4 text-
|
|
133
|
+
<ViewIcon className="w-4 h-4 text-(--blue-9)" />
|
|
136
134
|
) : (
|
|
137
|
-
<TableIcon className="w-4 h-4 text-
|
|
135
|
+
<TableIcon className="w-4 h-4 text-(--green-9)" />
|
|
138
136
|
);
|
|
139
137
|
|
|
140
138
|
const typeBadge = (
|
|
@@ -142,8 +140,8 @@ export const renderTableInfo = (table: DataTable): React.ReactNode => {
|
|
|
142
140
|
variant="secondary"
|
|
143
141
|
className={`text-xs ${
|
|
144
142
|
table.type === "view"
|
|
145
|
-
? "bg-
|
|
146
|
-
: "bg-
|
|
143
|
+
? "bg-(--blue-4) text-(--blue-11)"
|
|
144
|
+
: "bg-(--green-4) text-(--green-11)"
|
|
147
145
|
}`}
|
|
148
146
|
>
|
|
149
147
|
{table.type}
|
|
@@ -158,7 +156,7 @@ export const renderTableInfo = (table: DataTable): React.ReactNode => {
|
|
|
158
156
|
className="flex items-center justify-between text-xs rounded"
|
|
159
157
|
>
|
|
160
158
|
<div className="flex items-center gap-2">
|
|
161
|
-
<TypeIcon className="w-3 h-3 text-
|
|
159
|
+
<TypeIcon className="w-3 h-3 text-(--slate-9)" />
|
|
162
160
|
<span className="font-mono">{column.name}</span>
|
|
163
161
|
</div>
|
|
164
162
|
<Badge
|
|
@@ -196,7 +194,7 @@ export const renderTableInfo = (table: DataTable): React.ReactNode => {
|
|
|
196
194
|
<MetadataRow
|
|
197
195
|
label="Variable"
|
|
198
196
|
value={
|
|
199
|
-
<code className="text-xs bg-
|
|
197
|
+
<code className="text-xs bg-(--slate-4) px-1 rounded">
|
|
200
198
|
{table.variable_name}
|
|
201
199
|
</code>
|
|
202
200
|
}
|
|
@@ -207,7 +205,7 @@ export const renderTableInfo = (table: DataTable): React.ReactNode => {
|
|
|
207
205
|
<MetadataRow
|
|
208
206
|
label="Engine"
|
|
209
207
|
value={
|
|
210
|
-
<code className="text-xs bg-
|
|
208
|
+
<code className="text-xs bg-(--slate-4) px-1 rounded">
|
|
211
209
|
{table.engine}
|
|
212
210
|
</code>
|
|
213
211
|
}
|
|
@@ -220,13 +218,13 @@ export const renderTableInfo = (table: DataTable): React.ReactNode => {
|
|
|
220
218
|
<div className="grid grid-cols-2 gap-2 py-2">
|
|
221
219
|
{table.num_columns != null && (
|
|
222
220
|
<StatisticItem
|
|
223
|
-
icon={<ColumnIcon className="w-3 h-3 text-
|
|
221
|
+
icon={<ColumnIcon className="w-3 h-3 text-(--slate-9)" />}
|
|
224
222
|
text={`${table.num_columns} ${columnsText.pluralize(table.num_columns)}`}
|
|
225
223
|
/>
|
|
226
224
|
)}
|
|
227
225
|
{table.num_rows != null && (
|
|
228
226
|
<StatisticItem
|
|
229
|
-
icon={<HashIcon className="w-3 h-3 text-
|
|
227
|
+
icon={<HashIcon className="w-3 h-3 text-(--slate-9)" />}
|
|
230
228
|
text={`${table.num_rows} ${rowsText.pluralize(table.num_rows)}`}
|
|
231
229
|
/>
|
|
232
230
|
)}
|
|
@@ -242,8 +240,8 @@ export const renderTableInfo = (table: DataTable): React.ReactNode => {
|
|
|
242
240
|
{hasPrimaryKeys && (
|
|
243
241
|
<div className="flex flex-row gap-1">
|
|
244
242
|
<div className="flex items-center gap-1">
|
|
245
|
-
<PrimaryKeyIcon className="w-3 h-3 text-
|
|
246
|
-
<span className="text-xs font-medium text-
|
|
243
|
+
<PrimaryKeyIcon className="w-3 h-3 text-(--amber-9)" />
|
|
244
|
+
<span className="text-xs font-medium text-(--slate-11)">
|
|
247
245
|
Primary Keys:
|
|
248
246
|
</span>
|
|
249
247
|
</div>
|
|
@@ -251,7 +249,7 @@ export const renderTableInfo = (table: DataTable): React.ReactNode => {
|
|
|
251
249
|
<Badge
|
|
252
250
|
key={key}
|
|
253
251
|
variant="outline"
|
|
254
|
-
className="text-xs text-
|
|
252
|
+
className="text-xs text-(--slate-11)"
|
|
255
253
|
>
|
|
256
254
|
{key}
|
|
257
255
|
</Badge>
|
|
@@ -262,8 +260,8 @@ export const renderTableInfo = (table: DataTable): React.ReactNode => {
|
|
|
262
260
|
{hasIndexes && (
|
|
263
261
|
<div className="flex flex-row gap-1">
|
|
264
262
|
<div className="flex items-center gap-1 mb-1">
|
|
265
|
-
<IndexIcon className="w-3 h-3 text-
|
|
266
|
-
<span className="text-xs font-medium text-
|
|
263
|
+
<IndexIcon className="w-3 h-3 text-(--purple-9)" />
|
|
264
|
+
<span className="text-xs font-medium text-(--slate-11)">
|
|
267
265
|
Indexes:
|
|
268
266
|
</span>
|
|
269
267
|
</div>
|
|
@@ -271,7 +269,7 @@ export const renderTableInfo = (table: DataTable): React.ReactNode => {
|
|
|
271
269
|
<Badge
|
|
272
270
|
key={index}
|
|
273
271
|
variant="outline"
|
|
274
|
-
className="text-xs text-
|
|
272
|
+
className="text-xs text-(--slate-11)"
|
|
275
273
|
>
|
|
276
274
|
{index}
|
|
277
275
|
</Badge>
|
|
@@ -303,10 +301,7 @@ export const renderColumnInfo = (column: DataTableColumn): React.ReactNode => {
|
|
|
303
301
|
|
|
304
302
|
const sampleItems =
|
|
305
303
|
column.sample_values?.map((value, index) => (
|
|
306
|
-
<div
|
|
307
|
-
key={index}
|
|
308
|
-
className="text-xs bg-[var(--slate-3)] rounded font-mono"
|
|
309
|
-
>
|
|
304
|
+
<div key={index} className="text-xs bg-(--slate-3) rounded font-mono">
|
|
310
305
|
{value === null || value === undefined ? "null" : String(value)}
|
|
311
306
|
</div>
|
|
312
307
|
)) || [];
|
|
@@ -314,7 +309,7 @@ export const renderColumnInfo = (column: DataTableColumn): React.ReactNode => {
|
|
|
314
309
|
return (
|
|
315
310
|
<div className={CONTAINER_STYLES}>
|
|
316
311
|
<SectionHeader
|
|
317
|
-
icon={<TypeIcon className="w-4 h-4 text-
|
|
312
|
+
icon={<TypeIcon className="w-4 h-4 text-(--slate-9)" />}
|
|
318
313
|
title={column.name}
|
|
319
314
|
badge={typeBadge}
|
|
320
315
|
/>
|
|
@@ -328,7 +323,7 @@ export const renderColumnInfo = (column: DataTableColumn): React.ReactNode => {
|
|
|
328
323
|
<MetadataRow
|
|
329
324
|
label="External Type"
|
|
330
325
|
value={
|
|
331
|
-
<code className="text-xs bg-
|
|
326
|
+
<code className="text-xs bg-(--slate-4) px-1 rounded">
|
|
332
327
|
{column.external_type}
|
|
333
328
|
</code>
|
|
334
329
|
}
|
|
@@ -349,10 +344,7 @@ export const renderColumnInfo = (column: DataTableColumn): React.ReactNode => {
|
|
|
349
344
|
|
|
350
345
|
export const renderDatabaseInfo = (database: Database): React.ReactNode => {
|
|
351
346
|
const dialectBadge = (
|
|
352
|
-
<Badge
|
|
353
|
-
variant="outline"
|
|
354
|
-
className="text-xs bg-[var(--blue-4)] text-[var(--blue-11)]"
|
|
355
|
-
>
|
|
347
|
+
<Badge variant="outline" className="text-xs bg-(--blue-4) text-(--blue-11)">
|
|
356
348
|
{database.dialect}
|
|
357
349
|
</Badge>
|
|
358
350
|
);
|
|
@@ -360,10 +352,10 @@ export const renderDatabaseInfo = (database: Database): React.ReactNode => {
|
|
|
360
352
|
const schemaItems = database.schemas.map((schema) => (
|
|
361
353
|
<div
|
|
362
354
|
key={schema.name}
|
|
363
|
-
className="flex items-center justify-between text-xs rounded hover:bg-
|
|
355
|
+
className="flex items-center justify-between text-xs rounded hover:bg-(--slate-3)"
|
|
364
356
|
>
|
|
365
357
|
<div className="flex items-center gap-2">
|
|
366
|
-
<SchemaIcon className="w-3 h-3 text-
|
|
358
|
+
<SchemaIcon className="w-3 h-3 text-(--slate-9)" />
|
|
367
359
|
<span>{schema.name}</span>
|
|
368
360
|
</div>
|
|
369
361
|
<Badge variant="outline" className="text-xs">
|
|
@@ -375,7 +367,7 @@ export const renderDatabaseInfo = (database: Database): React.ReactNode => {
|
|
|
375
367
|
return (
|
|
376
368
|
<div className={CONTAINER_STYLES}>
|
|
377
369
|
<SectionHeader
|
|
378
|
-
icon={<DatabaseIcon className="w-4 h-4 text-
|
|
370
|
+
icon={<DatabaseIcon className="w-4 h-4 text-(--blue-9)" />}
|
|
379
371
|
title={database.name}
|
|
380
372
|
badge={dialectBadge}
|
|
381
373
|
/>
|
|
@@ -390,7 +382,7 @@ export const renderDatabaseInfo = (database: Database): React.ReactNode => {
|
|
|
390
382
|
<MetadataRow
|
|
391
383
|
label="Engine"
|
|
392
384
|
value={
|
|
393
|
-
<code className="text-xs bg-
|
|
385
|
+
<code className="text-xs bg-(--slate-4) px-1 rounded">
|
|
394
386
|
{database.engine}
|
|
395
387
|
</code>
|
|
396
388
|
}
|
|
@@ -400,7 +392,7 @@ export const renderDatabaseInfo = (database: Database): React.ReactNode => {
|
|
|
400
392
|
{/* Schema Statistics */}
|
|
401
393
|
<div className="py-2">
|
|
402
394
|
<StatisticItem
|
|
403
|
-
icon={<SchemaIcon className="w-3 h-3 text-
|
|
395
|
+
icon={<SchemaIcon className="w-3 h-3 text-(--slate-9)" />}
|
|
404
396
|
text={`${database.schemas.length} schema${database.schemas.length === 1 ? "" : "s"}`}
|
|
405
397
|
/>
|
|
406
398
|
</div>
|
|
@@ -423,7 +415,7 @@ export const renderSchemaInfo = (schema: DatabaseSchema): React.ReactNode => {
|
|
|
423
415
|
const schemaBadge = (
|
|
424
416
|
<Badge
|
|
425
417
|
variant="outline"
|
|
426
|
-
className="text-xs bg-
|
|
418
|
+
className="text-xs bg-(--green-4) text-(--green-11)"
|
|
427
419
|
>
|
|
428
420
|
Schema
|
|
429
421
|
</Badge>
|
|
@@ -432,13 +424,13 @@ export const renderSchemaInfo = (schema: DatabaseSchema): React.ReactNode => {
|
|
|
432
424
|
const tableItems = schema.tables.map((table) => (
|
|
433
425
|
<div
|
|
434
426
|
key={table.name}
|
|
435
|
-
className="flex items-center justify-between text-xs rounded hover:bg-
|
|
427
|
+
className="flex items-center justify-between text-xs rounded hover:bg-(--slate-3)"
|
|
436
428
|
>
|
|
437
429
|
<div className="flex items-center gap-2">
|
|
438
430
|
{table.type === "view" ? (
|
|
439
|
-
<ViewIcon className="w-3 h-3 text-
|
|
431
|
+
<ViewIcon className="w-3 h-3 text-(--blue-9)" />
|
|
440
432
|
) : (
|
|
441
|
-
<TableIcon className="w-3 h-3 text-
|
|
433
|
+
<TableIcon className="w-3 h-3 text-(--green-9)" />
|
|
442
434
|
)}
|
|
443
435
|
<span>{table.name}</span>
|
|
444
436
|
</div>
|
|
@@ -446,8 +438,8 @@ export const renderSchemaInfo = (schema: DatabaseSchema): React.ReactNode => {
|
|
|
446
438
|
variant="outline"
|
|
447
439
|
className={`text-xs ${
|
|
448
440
|
table.type === "view"
|
|
449
|
-
? "bg-
|
|
450
|
-
: "bg-
|
|
441
|
+
? "bg-(--blue-4) text-(--blue-11)"
|
|
442
|
+
: "bg-(--green-4) text-(--green-11)"
|
|
451
443
|
}`}
|
|
452
444
|
>
|
|
453
445
|
{table.type}
|
|
@@ -458,7 +450,7 @@ export const renderSchemaInfo = (schema: DatabaseSchema): React.ReactNode => {
|
|
|
458
450
|
return (
|
|
459
451
|
<div className={CONTAINER_STYLES}>
|
|
460
452
|
<SectionHeader
|
|
461
|
-
icon={<SchemaIcon className="w-4 h-4 text-
|
|
453
|
+
icon={<SchemaIcon className="w-4 h-4 text-(--green-9)" />}
|
|
462
454
|
title={schema.name}
|
|
463
455
|
badge={schemaBadge}
|
|
464
456
|
/>
|
|
@@ -466,7 +458,7 @@ export const renderSchemaInfo = (schema: DatabaseSchema): React.ReactNode => {
|
|
|
466
458
|
{/* Table Statistics */}
|
|
467
459
|
<div className="py-2">
|
|
468
460
|
<StatisticItem
|
|
469
|
-
icon={<TableIcon className="w-3 h-3 text-
|
|
461
|
+
icon={<TableIcon className="w-3 h-3 text-(--slate-9)" />}
|
|
470
462
|
text={`${schema.tables.length} table${schema.tables.length === 1 ? "" : "s"}`}
|
|
471
463
|
/>
|
|
472
464
|
</div>
|
|
@@ -516,7 +508,7 @@ export const renderDatasourceInfo = (
|
|
|
516
508
|
.map((table) => {
|
|
517
509
|
return (
|
|
518
510
|
<div key={table.name} className="flex items-center gap-2 ml-4">
|
|
519
|
-
<TableIcon className="w-3 h-3 text-
|
|
511
|
+
<TableIcon className="w-3 h-3 text-(--green-9)" />
|
|
520
512
|
<span className="text-xs">{table.name}</span>
|
|
521
513
|
</div>
|
|
522
514
|
);
|
|
@@ -525,8 +517,8 @@ export const renderDatasourceInfo = (
|
|
|
525
517
|
|
|
526
518
|
return (
|
|
527
519
|
<div key={schema.name}>
|
|
528
|
-
<div className="flex items-center gap-2 text-xs rounded hover:bg-
|
|
529
|
-
<SchemaIcon className="w-3 h-3 text-
|
|
520
|
+
<div className="flex items-center gap-2 text-xs rounded hover:bg-(--slate-3) ml-2">
|
|
521
|
+
<SchemaIcon className="w-3 h-3 text-(--slate-9)" />
|
|
530
522
|
<span>{schema.name}</span>
|
|
531
523
|
{isDefaultSchema && DefaultBadge}
|
|
532
524
|
<Badge variant="outline" className="text-xs ml-auto">
|
|
@@ -554,7 +546,7 @@ export const renderDatasourceInfo = (
|
|
|
554
546
|
return (
|
|
555
547
|
<div key={db.name}>
|
|
556
548
|
<div className="flex items-center gap-2">
|
|
557
|
-
<DatabaseIcon className="w-3 h-3 text-
|
|
549
|
+
<DatabaseIcon className="w-3 h-3 text-(--blue-9)" />
|
|
558
550
|
<span className="text-xs">{db.name}</span>
|
|
559
551
|
{isDefaultDb && DefaultBadge}
|
|
560
552
|
</div>
|
|
@@ -572,7 +564,7 @@ export const renderDatasourceInfo = (
|
|
|
572
564
|
|
|
573
565
|
const dataframeItems = dataframes?.map((table) => (
|
|
574
566
|
<div key={table.name} className="flex items-center gap-2">
|
|
575
|
-
<TableIcon className="w-3 h-3 text-
|
|
567
|
+
<TableIcon className="w-3 h-3 text-(--blue-9)" />
|
|
576
568
|
<span className="text-xs">{table.name}</span>
|
|
577
569
|
</div>
|
|
578
570
|
));
|
|
@@ -580,7 +572,7 @@ export const renderDatasourceInfo = (
|
|
|
580
572
|
return (
|
|
581
573
|
<div className={`${CONTAINER_STYLES} px-1`}>
|
|
582
574
|
<SectionHeader
|
|
583
|
-
icon={<DatasourceIcon className="w-4 h-4 text-
|
|
575
|
+
icon={<DatasourceIcon className="w-4 h-4 text-(--purple-9)" />}
|
|
584
576
|
title={title}
|
|
585
577
|
/>
|
|
586
578
|
|
|
@@ -599,7 +591,7 @@ export const renderDatasourceInfo = (
|
|
|
599
591
|
value={
|
|
600
592
|
<Badge
|
|
601
593
|
variant="outline"
|
|
602
|
-
className="text-xs bg-
|
|
594
|
+
className="text-xs bg-(--green-4) text-(--green-11)"
|
|
603
595
|
>
|
|
604
596
|
{connection.source}
|
|
605
597
|
</Badge>
|
|
@@ -610,11 +602,11 @@ export const renderDatasourceInfo = (
|
|
|
610
602
|
{/* Statistics */}
|
|
611
603
|
<div className="flex flex-row justify-between py-2">
|
|
612
604
|
<StatisticItem
|
|
613
|
-
icon={<DatabaseIcon className="w-3 h-3 text-
|
|
605
|
+
icon={<DatabaseIcon className="w-3 h-3 text-(--slate-9)" />}
|
|
614
606
|
text={`${databaseCount} ${databasesText.pluralize(databaseCount)}`}
|
|
615
607
|
/>
|
|
616
608
|
<StatisticItem
|
|
617
|
-
icon={<SchemaIcon className="w-3 h-3 text-
|
|
609
|
+
icon={<SchemaIcon className="w-3 h-3 text-(--slate-9)" />}
|
|
618
610
|
text={`${schemasCount} ${schemasText.pluralize(schemasCount)}`}
|
|
619
611
|
/>
|
|
620
612
|
</div>
|
|
@@ -641,10 +633,10 @@ export const renderEmptyInfo = (
|
|
|
641
633
|
) => {
|
|
642
634
|
return (
|
|
643
635
|
<div className="flex items-start gap-2 mt-3">
|
|
644
|
-
<InfoIcon size={10} className="mt-1 text-
|
|
645
|
-
<span className="text-xs text-
|
|
636
|
+
<InfoIcon size={10} className="mt-1 text-(--slate-10) shrink-0" />
|
|
637
|
+
<span className="text-xs text-(--slate-11)">
|
|
646
638
|
No {type} information available.{" \n"}
|
|
647
|
-
<span className="text-
|
|
639
|
+
<span className="text-(--blue-10)">
|
|
648
640
|
Introspect to see more details.
|
|
649
641
|
</span>
|
|
650
642
|
</span>
|
|
@@ -640,6 +640,60 @@ def run(polars):
|
|
|
640
640
|
`);
|
|
641
641
|
});
|
|
642
642
|
|
|
643
|
+
test("set comprehension target shadows outer global", () => {
|
|
644
|
+
// Regression: SCOPE_CREATING_NODES used "SetComprehension" instead of the
|
|
645
|
+
// grammar's "SetComprehensionExpression", so set comprehensions never
|
|
646
|
+
// created a scope and their for-target was treated as reactive.
|
|
647
|
+
expect(runHighlight(["x"], "result = {x for x in range(5)}"))
|
|
648
|
+
.toMatchInlineSnapshot(`
|
|
649
|
+
"
|
|
650
|
+
result = {x for x in range(5)}
|
|
651
|
+
"
|
|
652
|
+
`);
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
test("from-import module path stays reactive", () => {
|
|
656
|
+
// Regression: ImportStatement collected every VariableName child, so the
|
|
657
|
+
// module name in `from m import y` was wrongly treated as a local binding.
|
|
658
|
+
expect(
|
|
659
|
+
runHighlight(
|
|
660
|
+
["math"],
|
|
661
|
+
`
|
|
662
|
+
def f():
|
|
663
|
+
from math import sin as my_sin
|
|
664
|
+
return math + my_sin(1)`,
|
|
665
|
+
),
|
|
666
|
+
).toMatchInlineSnapshot(`
|
|
667
|
+
"
|
|
668
|
+
def f():
|
|
669
|
+
from math import sin as my_sin
|
|
670
|
+
return math + my_sin(1)
|
|
671
|
+
^^^^
|
|
672
|
+
"
|
|
673
|
+
`);
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
test("from-import: aliased imported name is not a binding", () => {
|
|
677
|
+
// Regression: `sin` in `from math import sin as my_sin` was incorrectly
|
|
678
|
+
// registered as a local binding, hiding genuine reactive uses of `sin`.
|
|
679
|
+
expect(
|
|
680
|
+
runHighlight(
|
|
681
|
+
["sin"],
|
|
682
|
+
`
|
|
683
|
+
def f():
|
|
684
|
+
from math import sin as my_sin
|
|
685
|
+
return sin + my_sin(1)`,
|
|
686
|
+
),
|
|
687
|
+
).toMatchInlineSnapshot(`
|
|
688
|
+
"
|
|
689
|
+
def f():
|
|
690
|
+
from math import sin as my_sin
|
|
691
|
+
return sin + my_sin(1)
|
|
692
|
+
^^^
|
|
693
|
+
"
|
|
694
|
+
`);
|
|
695
|
+
});
|
|
696
|
+
|
|
643
697
|
test("lambda inside function with outer global", () => {
|
|
644
698
|
expect(
|
|
645
699
|
runHighlight(
|