@marimo-team/islands 0.23.7-dev75 → 0.23.7-dev78
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/{code-visibility-DJtWleQu.js → code-visibility-yHhPjulC.js} +2 -2
- package/dist/main.js +110 -95
- package/dist/{reveal-component-0rj8owbr.js → reveal-component-DixmqICj.js} +1 -1
- package/package.json +1 -1
- package/src/components/editor/notebook-cell.tsx +2 -0
- package/src/components/editor/output/console/ConsoleOutput.tsx +23 -5
- package/src/components/editor/output/console/__tests__/ConsoleOutput.test.tsx +114 -0
- package/src/components/editor/renderers/vertical-layout/vertical-layout.tsx +1 -0
- package/src/components/scratchpad/scratchpad.tsx +1 -0
- package/src/plugins/layout/DownloadPlugin.tsx +9 -7
- package/src/utils/download.ts +4 -2
|
@@ -32990,7 +32990,7 @@ Database schema: ${n}`), (_a3 = t2.aiFix) == null ? void 0 : _a3.setAiCompletion
|
|
|
32990
32990
|
};
|
|
32991
32991
|
downloadByURL = function(e, t) {
|
|
32992
32992
|
let n = document.createElement("a");
|
|
32993
|
-
n.href = e, n.download = t, n.click(), n.remove();
|
|
32993
|
+
n.href = e, t && (n.download = t), n.click(), n.remove();
|
|
32994
32994
|
};
|
|
32995
32995
|
downloadBlob = function(e, t) {
|
|
32996
32996
|
let n = URL.createObjectURL(e);
|
|
@@ -35172,7 +35172,7 @@ ${_}`,
|
|
|
35172
35172
|
return Logger.warn("Failed to get version from mount config"), null;
|
|
35173
35173
|
}
|
|
35174
35174
|
}
|
|
35175
|
-
marimoVersionAtom = atom(getVersionFromMountConfig() || "0.23.7-
|
|
35175
|
+
marimoVersionAtom = atom(getVersionFromMountConfig() || "0.23.7-dev78");
|
|
35176
35176
|
showCodeInRunModeAtom = atom(true);
|
|
35177
35177
|
atom(null);
|
|
35178
35178
|
var import_compiler_runtime = require_compiler_runtime();
|
package/dist/main.js
CHANGED
|
@@ -26,7 +26,7 @@ import { $ as useCellActions, At as DeferredRequestRegistry, B as safeExtractSet
|
|
|
26
26
|
import { __tla as __tla_1 } from "./chunk-5FQGJX7Z-BOg95xG5.js";
|
|
27
27
|
import { o as useSize, s as Root$2, u as createLucideIcon } from "./dist-D3ZI9nhS.js";
|
|
28
28
|
import { A as SquareFunction, C as DEFAULT_COLOR_SCHEME, D as SCALE_TYPE_DESCRIPTIONS, E as EMPTY_VALUE$1, O as TIME_UNIT_DESCRIPTIONS, S as DEFAULT_AGGREGATION, T as DEFAULT_TIME_UNIT, _ as AGGREGATION_TYPE_DESCRIPTIONS, a as AGGREGATION_FNS$1, b as COLOR_SCHEMES, c as COLOR_BY_FIELDS, d as NONE_VALUE, f as SELECTABLE_DATA_TYPES, g as TIME_UNITS, h as STRING_AGGREGATION_FNS, i as convertDataTypeToSelectable, j as ChartColumn, k as escapeFieldName, l as COMBINED_TIME_UNITS, m as SORT_TYPES, n as createSpecWithoutData, o as BIN_AGGREGATION, p as SINGLE_TIME_UNITS, r as isFieldSet, s as CHART_TYPES, t as augmentSpecWithData, u as ChartType, v as AGGREGATION_TYPE_ICON, w as DEFAULT_MAX_BINS_FACET, x as COUNT_FIELD, y as CHART_TYPE_ICON } from "./spec-hVaaZsY5.js";
|
|
29
|
-
import { $ as DelayMount, A as contextAwarePanelOwner, At as Kbd, B as Provider$1, Bt as Ellipsis, C as prettifyRowCount, Ct as TabsTrigger, D as ContextAwarePanelItem, Dt as LazyVegaEmbed, E as ComboboxItem, Et as ChartLoadingState, F as Toggle, Ft as TextWrap, G as TableHeader, Gt as ChevronsLeft, H as TableBody, Ht as Code, It as GripHorizontal, J as generateColumns, Jt as ArrowDownWideNarrow, K as TableRow, Kt as ChevronsDownUp, Lt as Funnel, M as isCellAwareAtom, Mt as EmotionCacheProvider, N as SlotNames, Nt as $fae977aafc393c5c$export$588937bcd60ade55, O as PANEL_TYPES, Ot as useOverflowDetection, P as slotsController, Pt as $fae977aafc393c5c$export$6b862160d295c8e, Q as ColumnChartSpecModel, Rt as EyeOff, S as prettifyRowColumnCount, St as TabsList, T as Combobox, Tt as ChartInfoState, U as TableCell, Ut as ChevronsUpDown, V as Table, Vt as Download, W as TableHead, Wt as ChevronsRight, X as renderCellValue, Y as inferFieldTypes, Z as ColumnChartContext, _ as downloadBlob, _t as CommandList, at as getPageIndexForRow, b as Progress, bt as Tabs, c as Slide, ct as INDEX_COLUMN_NAME, d as JsonOutput, dt as toFieldTypes, et as useIntersectionObserver, f as OutputArea, ft as getMimeValues, g as ADD_PRINTING_CLASS, gt as CommandItem, h as InstallPackageButton, ht as CommandInput, it as filtersToFilterGroup, j as contextAwarePanelType, jt as HtmlOutput, k as contextAwarePanelOpen, kt as RenderTextWithLinks, l as RadioGroup, lt as SELECT_COLUMN_ID, m as DataTable, mt as CommandEmpty, n as marimoVersionAtom, nt as DatePicker, o as SLIDE_TYPE_OPTIONS_BY_VALUE, ot as loadTableAndRawData, p as OutputRenderer, pt as Command, q as NAMELESS_COLUMN_PREFIX, qt as ChevronLeft, r as showCodeInRunModeAtom, rt as DateRangePicker, st as loadTableData, t as useNotebookCodeAvailable, tt as usePrevious$1, u as RadioGroupItem, ut as TOO_MANY_ROWS, v as downloadByURL, vt as CommandSeparator, w as useInternalStateWithSync, wt as ChartErrorState, x as Filenames, xt as TabsContent, y as downloadHTMLAsImage, yt as Maps, z as Fill, __tla as __tla_2 } from "./code-visibility-
|
|
29
|
+
import { $ as DelayMount, A as contextAwarePanelOwner, At as Kbd, B as Provider$1, Bt as Ellipsis, C as prettifyRowCount, Ct as TabsTrigger, D as ContextAwarePanelItem, Dt as LazyVegaEmbed, E as ComboboxItem, Et as ChartLoadingState, F as Toggle, Ft as TextWrap, G as TableHeader, Gt as ChevronsLeft, H as TableBody, Ht as Code, It as GripHorizontal, J as generateColumns, Jt as ArrowDownWideNarrow, K as TableRow, Kt as ChevronsDownUp, Lt as Funnel, M as isCellAwareAtom, Mt as EmotionCacheProvider, N as SlotNames, Nt as $fae977aafc393c5c$export$588937bcd60ade55, O as PANEL_TYPES, Ot as useOverflowDetection, P as slotsController, Pt as $fae977aafc393c5c$export$6b862160d295c8e, Q as ColumnChartSpecModel, Rt as EyeOff, S as prettifyRowColumnCount, St as TabsList, T as Combobox, Tt as ChartInfoState, U as TableCell, Ut as ChevronsUpDown, V as Table, Vt as Download, W as TableHead, Wt as ChevronsRight, X as renderCellValue, Y as inferFieldTypes, Z as ColumnChartContext, _ as downloadBlob, _t as CommandList, at as getPageIndexForRow, b as Progress, bt as Tabs, c as Slide, ct as INDEX_COLUMN_NAME, d as JsonOutput, dt as toFieldTypes, et as useIntersectionObserver, f as OutputArea, ft as getMimeValues, g as ADD_PRINTING_CLASS, gt as CommandItem, h as InstallPackageButton, ht as CommandInput, it as filtersToFilterGroup, j as contextAwarePanelType, jt as HtmlOutput, k as contextAwarePanelOpen, kt as RenderTextWithLinks, l as RadioGroup, lt as SELECT_COLUMN_ID, m as DataTable, mt as CommandEmpty, n as marimoVersionAtom, nt as DatePicker, o as SLIDE_TYPE_OPTIONS_BY_VALUE, ot as loadTableAndRawData, p as OutputRenderer, pt as Command, q as NAMELESS_COLUMN_PREFIX, qt as ChevronLeft, r as showCodeInRunModeAtom, rt as DateRangePicker, st as loadTableData, t as useNotebookCodeAvailable, tt as usePrevious$1, u as RadioGroupItem, ut as TOO_MANY_ROWS, v as downloadByURL, vt as CommandSeparator, w as useInternalStateWithSync, wt as ChartErrorState, x as Filenames, xt as TabsContent, y as downloadHTMLAsImage, yt as Maps, z as Fill, __tla as __tla_2 } from "./code-visibility-yHhPjulC.js";
|
|
30
30
|
import { c as Calendar, i as createReducerAndAtoms, n as useOnUnmount, o as ToggleLeft, t as useOnMount } from "./useLifecycle-BF6-z62y.js";
|
|
31
31
|
import { t as Check } from "./check-BcUIXnUT.js";
|
|
32
32
|
import { A as Trigger$1, C as $a916eb452884faea$export$b7a616150fdb9f44, E as $18f2051aff69b9bf$export$a54013f0d02a8f82, F as X, L as ChevronDown, M as usePrevious$2, N as useDirection, P as createCollection, S as logNever, T as $18f2051aff69b9bf$export$43bb16f9c6d9e3f7, a as SelectGroup, c as SelectSeparator, d as NativeSelect, i as SelectContent, j as clamp$2, k as Icon, l as SelectTrigger, n as capitalize, o as SelectItem, r as Select, s as SelectLabel, t as Strings, u as SelectValue, x as assertNever } from "./strings-BiIhGaI8.js";
|
|
@@ -26558,28 +26558,32 @@ ${c}
|
|
|
26558
26558
|
}));
|
|
26559
26559
|
var DownloadButton = ({ data: e, load: r }) => {
|
|
26560
26560
|
let [c, l] = (0, import_react.useState)(false), u = async (c2) => {
|
|
26561
|
-
if (e.
|
|
26562
|
-
c2.preventDefault(),
|
|
26563
|
-
|
|
26564
|
-
|
|
26565
|
-
|
|
26566
|
-
|
|
26567
|
-
|
|
26568
|
-
|
|
26569
|
-
|
|
26570
|
-
|
|
26571
|
-
|
|
26572
|
-
|
|
26573
|
-
|
|
26561
|
+
if (e.disabled) {
|
|
26562
|
+
c2.preventDefault(), c2.stopPropagation();
|
|
26563
|
+
return;
|
|
26564
|
+
}
|
|
26565
|
+
if (c2.preventDefault(), !e.lazy) {
|
|
26566
|
+
downloadByURL(e.data, e.filename ?? void 0);
|
|
26567
|
+
return;
|
|
26568
|
+
}
|
|
26569
|
+
l(true);
|
|
26570
|
+
try {
|
|
26571
|
+
let c3 = await r({});
|
|
26572
|
+
downloadByURL(c3.data, c3.filename ?? e.filename ?? void 0);
|
|
26573
|
+
} catch (e2) {
|
|
26574
|
+
toast({
|
|
26575
|
+
title: "Failed to download",
|
|
26576
|
+
description: "Please try again."
|
|
26577
|
+
}), Logger.error("Failed to download:", e2);
|
|
26578
|
+
} finally {
|
|
26579
|
+
l(false);
|
|
26574
26580
|
}
|
|
26575
26581
|
}, f = c ? LoaderCircle : Download, m = e.label ? renderHTML({
|
|
26576
26582
|
html: e.label
|
|
26577
26583
|
}) : "Download";
|
|
26578
26584
|
return (0, import_jsx_runtime.jsxs)("a", {
|
|
26579
26585
|
href: e.data,
|
|
26580
|
-
download: e.filename
|
|
26581
|
-
target: "_blank",
|
|
26582
|
-
rel: "noopener noreferrer",
|
|
26586
|
+
download: e.filename ?? "",
|
|
26583
26587
|
onClick: u,
|
|
26584
26588
|
className: buttonVariants({
|
|
26585
26589
|
variant: "secondary",
|
|
@@ -35970,7 +35974,7 @@ ${c}
|
|
|
35970
35974
|
if (l && l !== "slide") return l;
|
|
35971
35975
|
if (c == null ? void 0 : c.has(e)) return "skip";
|
|
35972
35976
|
}
|
|
35973
|
-
var LazySlidesComponent = import_react.lazy(() => import("./reveal-component-
|
|
35977
|
+
var LazySlidesComponent = import_react.lazy(() => import("./reveal-component-DixmqICj.js"));
|
|
35974
35978
|
const SlidesLayoutRenderer = ({ layout: e, setLayout: r, cells: c, mode: l }) => {
|
|
35975
35979
|
var _a3;
|
|
35976
35980
|
let u = useAtomValue(kioskModeAtom), d = l === "read" || u, f = useAtomValue(numColumnsAtom) > 1, [p, m] = (0, import_react.useState)(null), { cellsWithOutput: h, skippedIds: g, slideTypes: _, startCellIndex: v } = (0, import_react.useMemo)(() => computeSlideCellsInfo(c, e), [
|
|
@@ -36333,29 +36337,29 @@ ${c}
|
|
|
36333
36337
|
}), r[0] = e, r[1] = c), c;
|
|
36334
36338
|
};
|
|
36335
36339
|
var ConsoleOutputInternal = (e) => {
|
|
36336
|
-
let r = (0, import_compiler_runtime$6.c)(
|
|
36340
|
+
let r = (0, import_compiler_runtime$6.c)(63), c = import_react.useRef(null), { wrapText: l, setWrapText: u } = useWrapText(), [d, f] = useExpandedConsoleOutput(e.cellId), [m, h] = import_react.useState(""), g;
|
|
36337
36341
|
r[0] === m ? g = r[1] : (g = {
|
|
36338
36342
|
value: m,
|
|
36339
36343
|
setValue: h
|
|
36340
36344
|
}, r[0] = m, r[1] = g);
|
|
36341
|
-
let _ = useInputHistory(g), { consoleOutputs: v, stale: y,
|
|
36342
|
-
if (r[2] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (
|
|
36345
|
+
let _ = useInputHistory(g), { consoleOutputs: v, stale: y, interrupted: b, cellName: S, cellId: T, onSubmitDebugger: E, onClear: O, onRefactorWithAI: j, className: M } = e, I = useDebouncedConsoleOutputs(v), L = I.length > 0, R = useSelectAllContent(L), z = useOverflowDetection(c, L), B;
|
|
36346
|
+
if (r[2] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (B = () => {
|
|
36343
36347
|
let e2 = c.current;
|
|
36344
36348
|
if (!e2) return;
|
|
36345
36349
|
let r2 = e2.scrollHeight - e2.clientHeight;
|
|
36346
36350
|
r2 - e2.scrollTop < 120 && (e2.scrollTop = r2);
|
|
36347
|
-
}, r[2] =
|
|
36348
|
-
let
|
|
36349
|
-
if (r[3] !==
|
|
36350
|
-
let e2 =
|
|
36351
|
-
r[
|
|
36352
|
-
let
|
|
36353
|
-
|
|
36351
|
+
}, r[2] = B) : B = r[2], (0, import_react.useLayoutEffect)(B), !L && isInternalCellName(S)) return null;
|
|
36352
|
+
let H, W, G, q, zU, BU, Z, VU, HU, UU;
|
|
36353
|
+
if (r[3] !== T || r[4] !== M || r[5] !== I || r[6] !== L || r[7] !== _ || r[8] !== b || r[9] !== d || r[10] !== z || r[11] !== O || r[12] !== j || r[13] !== E || r[14] !== R || r[15] !== f || r[16] !== u || r[17] !== y || r[18] !== m || r[19] !== l) {
|
|
36354
|
+
let e2 = I.toReversed(), g2 = e2.some(_temp$2), v2 = e2.findIndex(_temp2$1), S2;
|
|
36355
|
+
r[30] === I ? S2 = r[31] : (S2 = () => I.filter(_temp3$1).map(_temp4$1).join("\n"), r[30] = I, r[31] = S2);
|
|
36356
|
+
let B2 = S2;
|
|
36357
|
+
H = "relative group", r[32] !== B2 || r[33] !== L || r[34] !== d || r[35] !== z || r[36] !== f || r[37] !== u || r[38] !== l ? (W = L && (0, import_jsx_runtime.jsxs)("div", {
|
|
36354
36358
|
className: "absolute top-1 right-4 z-10 opacity-0 group-hover:opacity-100 flex items-center gap-1 print:hidden",
|
|
36355
36359
|
children: [
|
|
36356
36360
|
(0, import_jsx_runtime.jsx)(CopyClipboardIcon, {
|
|
36357
36361
|
tooltip: "Copy console output",
|
|
36358
|
-
value:
|
|
36362
|
+
value: B2,
|
|
36359
36363
|
className: "h-4 w-4"
|
|
36360
36364
|
}),
|
|
36361
36365
|
(0, import_jsx_runtime.jsx)(Tooltip, {
|
|
@@ -36372,7 +36376,7 @@ ${c}
|
|
|
36372
36376
|
})
|
|
36373
36377
|
})
|
|
36374
36378
|
}),
|
|
36375
|
-
(
|
|
36379
|
+
(z || d) && (0, import_jsx_runtime.jsx)(Button, {
|
|
36376
36380
|
"aria-label": d ? "Collapse output" : "Expand output",
|
|
36377
36381
|
className: "p-0 mb-px",
|
|
36378
36382
|
onClick: () => f(!d),
|
|
@@ -36391,68 +36395,69 @@ ${c}
|
|
|
36391
36395
|
})
|
|
36392
36396
|
})
|
|
36393
36397
|
]
|
|
36394
|
-
}), r[
|
|
36395
|
-
let
|
|
36396
|
-
r[
|
|
36398
|
+
}), r[32] = B2, r[33] = L, r[34] = d, r[35] = z, r[36] = f, r[37] = u, r[38] = l, r[39] = W) : W = r[39], G = y ? "This console output is stale" : void 0, q = "console-output-area", zU = c, BU = R, Z = 0;
|
|
36399
|
+
let WU2 = y && "marimo-output-stale", GU2 = L ? "p-5" : "p-3";
|
|
36400
|
+
r[40] !== M || r[41] !== WU2 || r[42] !== GU2 ? (VU = cn("console-output-area overflow-hidden rounded-b-lg flex flex-col-reverse w-full gap-1 focus:outline-hidden", WU2, GU2, M), r[40] = M, r[41] = WU2, r[42] = GU2, r[43] = VU) : VU = r[43], r[44] === d ? HU = r[45] : (HU = d ? {
|
|
36397
36401
|
maxHeight: "none"
|
|
36398
|
-
} : void 0, r[
|
|
36402
|
+
} : void 0, r[44] = d, r[45] = HU), UU = e2.map((e3, r2) => {
|
|
36399
36403
|
if (e3.channel === "pdb") return null;
|
|
36400
36404
|
if (e3.channel === "stdin") {
|
|
36401
36405
|
invariant(typeof e3.data == "string", "Expected data to be a string");
|
|
36402
|
-
let c2 =
|
|
36406
|
+
let c2 = I.length - r2 - 1, l2 = e3.mimetype === "text/password";
|
|
36403
36407
|
return e3.response == null && v2 === r2 ? (0, import_jsx_runtime.jsx)(StdInput, {
|
|
36404
36408
|
output: e3.data,
|
|
36405
36409
|
isPdb: g2,
|
|
36406
36410
|
isPassword: l2,
|
|
36407
|
-
onSubmit: (e4) =>
|
|
36408
|
-
onClear:
|
|
36411
|
+
onSubmit: (e4) => E(e4, c2),
|
|
36412
|
+
onClear: O,
|
|
36409
36413
|
value: m,
|
|
36410
36414
|
setValue: h,
|
|
36411
36415
|
inputHistory: _
|
|
36412
36416
|
}, r2) : (0, import_jsx_runtime.jsx)(StdInputWithResponse, {
|
|
36413
36417
|
output: e3.data,
|
|
36414
36418
|
response: e3.response,
|
|
36415
|
-
isPassword: l2
|
|
36419
|
+
isPassword: l2,
|
|
36420
|
+
interrupted: b
|
|
36416
36421
|
}, r2);
|
|
36417
36422
|
}
|
|
36418
36423
|
return (0, import_jsx_runtime.jsx)(import_react.Fragment, {
|
|
36419
36424
|
children: (0, import_jsx_runtime.jsx)(OutputRenderer, {
|
|
36420
|
-
cellId:
|
|
36421
|
-
onRefactorWithAI:
|
|
36425
|
+
cellId: T,
|
|
36426
|
+
onRefactorWithAI: j,
|
|
36422
36427
|
message: e3,
|
|
36423
36428
|
wrapText: l
|
|
36424
36429
|
})
|
|
36425
36430
|
}, r2);
|
|
36426
|
-
}), r[3] =
|
|
36427
|
-
} else
|
|
36428
|
-
let UU;
|
|
36429
|
-
r[45] !== S || r[46] !== b ? (UU = (0, import_jsx_runtime.jsx)(NameCellContentEditable, {
|
|
36430
|
-
value: b,
|
|
36431
|
-
cellId: S,
|
|
36432
|
-
className: "bg-(--slate-4) border-(--slate-4) hover:bg-(--slate-5) dark:border-(--sky-5) dark:bg-(--sky-6) dark:text-(--sky-12) text-(--slate-12) rounded-l rounded-br-lg absolute right-0 bottom-0 text-xs px-1.5 py-0.5 font-mono max-w-[75%] whitespace-nowrap overflow-hidden"
|
|
36433
|
-
}), r[45] = S, r[46] = b, r[47] = UU) : UU = r[47];
|
|
36431
|
+
}), r[3] = T, r[4] = M, r[5] = I, r[6] = L, r[7] = _, r[8] = b, r[9] = d, r[10] = z, r[11] = O, r[12] = j, r[13] = E, r[14] = R, r[15] = f, r[16] = u, r[17] = y, r[18] = m, r[19] = l, r[20] = H, r[21] = W, r[22] = G, r[23] = q, r[24] = zU, r[25] = BU, r[26] = Z, r[27] = VU, r[28] = HU, r[29] = UU;
|
|
36432
|
+
} else H = r[20], W = r[21], G = r[22], q = r[23], zU = r[24], BU = r[25], Z = r[26], VU = r[27], HU = r[28], UU = r[29];
|
|
36434
36433
|
let WU;
|
|
36435
|
-
r[
|
|
36436
|
-
|
|
36437
|
-
|
|
36438
|
-
|
|
36439
|
-
|
|
36440
|
-
tabIndex: BU,
|
|
36441
|
-
className: Z,
|
|
36442
|
-
style: VU,
|
|
36443
|
-
children: [
|
|
36444
|
-
HU,
|
|
36445
|
-
UU
|
|
36446
|
-
]
|
|
36447
|
-
}), r[48] = UU, r[49] = W, r[50] = G, r[51] = q, r[52] = zU, r[53] = BU, r[54] = Z, r[55] = VU, r[56] = HU, r[57] = WU) : WU = r[57];
|
|
36434
|
+
r[46] !== T || r[47] !== S ? (WU = (0, import_jsx_runtime.jsx)(NameCellContentEditable, {
|
|
36435
|
+
value: S,
|
|
36436
|
+
cellId: T,
|
|
36437
|
+
className: "bg-(--slate-4) border-(--slate-4) hover:bg-(--slate-5) dark:border-(--sky-5) dark:bg-(--sky-6) dark:text-(--sky-12) text-(--slate-12) rounded-l rounded-br-lg absolute right-0 bottom-0 text-xs px-1.5 py-0.5 font-mono max-w-[75%] whitespace-nowrap overflow-hidden"
|
|
36438
|
+
}), r[46] = T, r[47] = S, r[48] = WU) : WU = r[48];
|
|
36448
36439
|
let GU;
|
|
36449
|
-
|
|
36450
|
-
|
|
36440
|
+
r[49] !== WU || r[50] !== G || r[51] !== q || r[52] !== zU || r[53] !== BU || r[54] !== Z || r[55] !== VU || r[56] !== HU || r[57] !== UU ? (GU = (0, import_jsx_runtime.jsxs)("div", {
|
|
36441
|
+
title: G,
|
|
36442
|
+
"data-testid": q,
|
|
36443
|
+
ref: zU,
|
|
36444
|
+
...BU,
|
|
36445
|
+
tabIndex: Z,
|
|
36446
|
+
className: VU,
|
|
36447
|
+
style: HU,
|
|
36451
36448
|
children: [
|
|
36452
|
-
|
|
36449
|
+
UU,
|
|
36453
36450
|
WU
|
|
36454
36451
|
]
|
|
36455
|
-
}), r[
|
|
36452
|
+
}), r[49] = WU, r[50] = G, r[51] = q, r[52] = zU, r[53] = BU, r[54] = Z, r[55] = VU, r[56] = HU, r[57] = UU, r[58] = GU) : GU = r[58];
|
|
36453
|
+
let KU;
|
|
36454
|
+
return r[59] !== H || r[60] !== W || r[61] !== GU ? (KU = (0, import_jsx_runtime.jsxs)("div", {
|
|
36455
|
+
className: H,
|
|
36456
|
+
children: [
|
|
36457
|
+
W,
|
|
36458
|
+
GU
|
|
36459
|
+
]
|
|
36460
|
+
}), r[59] = H, r[60] = W, r[61] = GU, r[62] = KU) : KU = r[62], KU;
|
|
36456
36461
|
}, StdInput = (e) => {
|
|
36457
36462
|
let r = (0, import_compiler_runtime$6.c)(25), { value: c, setValue: l, inputHistory: u, output: d, isPassword: f, isPdb: p, onSubmit: m, onClear: h } = e, { navigateUp: g, navigateDown: _, addToHistory: v } = u, y;
|
|
36458
36463
|
r[0] === d ? y = r[1] : (y = renderText(d), r[0] = d, r[1] = y);
|
|
@@ -36472,7 +36477,7 @@ ${c}
|
|
|
36472
36477
|
_(), e2.preventDefault();
|
|
36473
36478
|
return;
|
|
36474
36479
|
}
|
|
36475
|
-
e2.key === "Enter" && !e2.shiftKey && (c &&
|
|
36480
|
+
e2.key === "Enter" && !e2.shiftKey && (c && v(c), m(c), l(""), e2.preventDefault(), e2.stopPropagation()), e2.key === "Enter" && e2.metaKey && (e2.preventDefault(), e2.stopPropagation());
|
|
36476
36481
|
}, r[5] = v, r[6] = _, r[7] = g, r[8] = m, r[9] = l, r[10] = c, r[11] = T) : T = r[11];
|
|
36477
36482
|
let E;
|
|
36478
36483
|
r[12] !== b || r[13] !== S || r[14] !== T || r[15] !== c ? (E = (0, import_jsx_runtime.jsx)(Input, {
|
|
@@ -36503,21 +36508,30 @@ ${c}
|
|
|
36503
36508
|
]
|
|
36504
36509
|
}), r[21] = y, r[22] = E, r[23] = O, r[24] = j) : j = r[24], j;
|
|
36505
36510
|
}, StdInputWithResponse = (e) => {
|
|
36506
|
-
let r = (0, import_compiler_runtime$6.c)(
|
|
36507
|
-
r[0] ===
|
|
36508
|
-
let
|
|
36509
|
-
r[2] !==
|
|
36510
|
-
className: "text-(--sky-11)",
|
|
36511
|
-
|
|
36512
|
-
|
|
36513
|
-
|
|
36514
|
-
|
|
36511
|
+
let r = (0, import_compiler_runtime$6.c)(10), { output: c, response: l, isPassword: u, interrupted: d } = e, f = l != null && l !== "", p = d && !f, m;
|
|
36512
|
+
r[0] === c ? m = r[1] : (m = renderText(c), r[0] = c, r[1] = m);
|
|
36513
|
+
let h;
|
|
36514
|
+
r[2] !== f || r[3] !== u || r[4] !== l || r[5] !== p ? (h = !u && !p && (0, import_jsx_runtime.jsxs)("span", {
|
|
36515
|
+
className: "inline-flex items-center gap-1 text-(--sky-11)",
|
|
36516
|
+
"aria-label": "stdin response",
|
|
36517
|
+
children: [
|
|
36518
|
+
(0, import_jsx_runtime.jsx)(ChevronRight, {
|
|
36519
|
+
className: "w-4 h-4 shrink-0 opacity-70"
|
|
36520
|
+
}),
|
|
36521
|
+
f ? l : (0, import_jsx_runtime.jsx)("span", {
|
|
36522
|
+
className: "italic opacity-70",
|
|
36523
|
+
children: "(empty)"
|
|
36524
|
+
})
|
|
36525
|
+
]
|
|
36526
|
+
}), r[2] = f, r[3] = u, r[4] = l, r[5] = p, r[6] = h) : h = r[6];
|
|
36527
|
+
let g;
|
|
36528
|
+
return r[7] !== m || r[8] !== h ? (g = (0, import_jsx_runtime.jsxs)("div", {
|
|
36515
36529
|
className: "flex gap-2 items-center",
|
|
36516
36530
|
children: [
|
|
36517
|
-
|
|
36518
|
-
|
|
36531
|
+
m,
|
|
36532
|
+
h
|
|
36519
36533
|
]
|
|
36520
|
-
}), r[
|
|
36534
|
+
}), r[7] = m, r[8] = h, r[9] = g) : g = r[9], g;
|
|
36521
36535
|
}, renderText = (e) => e ? (0, import_jsx_runtime.jsx)(RenderTextWithLinks, {
|
|
36522
36536
|
text: e
|
|
36523
36537
|
}) : null;
|
|
@@ -36836,7 +36850,7 @@ ${c}
|
|
|
36836
36850
|
})
|
|
36837
36851
|
}), r[24] = y, r[25] = T), T;
|
|
36838
36852
|
}, VerticalCell = (0, import_react.memo)((e) => {
|
|
36839
|
-
let r = (0, import_compiler_runtime$3.c)(
|
|
36853
|
+
let r = (0, import_compiler_runtime$3.c)(56), { output: c, consoleOutputs: l, cellOutputArea: u, cellId: d, status: f, stopped: m, errored: h, config: g, interrupted: _, staleInputs: v, runStartTimestamp: y, code: b, showCode: S, mode: w, name: T, kiosk: E, showErrorTracebacks: O } = e, j = (0, import_react.useRef)(null), M;
|
|
36840
36854
|
r[0] !== _ || r[1] !== c || r[2] !== y || r[3] !== v || r[4] !== f ? (M = outputIsStale({
|
|
36841
36855
|
status: f,
|
|
36842
36856
|
output: c,
|
|
@@ -36871,58 +36885,59 @@ ${c}
|
|
|
36871
36885
|
r[19] !== b || r[20] !== c ? (p = shouldHideCode(b, c), r[19] = b, r[20] = c, r[21] = p) : p = r[21];
|
|
36872
36886
|
let m2 = p, h2;
|
|
36873
36887
|
r[22] !== d || r[23] !== T ? (h2 = cellDomProps(d, T), r[22] = d, r[23] = T, r[24] = h2) : h2 = r[24];
|
|
36874
|
-
let
|
|
36875
|
-
r[25] !== b || r[26] !== g || r[27] !== m2 || r[28] !== E ? (
|
|
36888
|
+
let v2 = u === "above" && f2, y2;
|
|
36889
|
+
r[25] !== b || r[26] !== g || r[27] !== m2 || r[28] !== E ? (y2 = !m2 && (0, import_jsx_runtime.jsx)("div", {
|
|
36876
36890
|
className: "tray",
|
|
36877
36891
|
children: (0, import_jsx_runtime.jsx)(ReadonlyCode, {
|
|
36878
36892
|
initiallyHideCode: g.hide_code || E,
|
|
36879
36893
|
code: b
|
|
36880
36894
|
})
|
|
36881
|
-
}), r[25] = b, r[26] = g, r[27] = m2, r[28] = E, r[29] =
|
|
36882
|
-
let
|
|
36883
|
-
r[30] !== d || r[31] !== l || r[32] !==
|
|
36895
|
+
}), r[25] = b, r[26] = g, r[27] = m2, r[28] = E, r[29] = y2) : y2 = r[29];
|
|
36896
|
+
let S2 = u === "below" && f2, w2;
|
|
36897
|
+
r[30] !== d || r[31] !== l || r[32] !== _ || r[33] !== T || r[34] !== I ? (w2 = (0, import_jsx_runtime.jsx)(ConsoleOutput, {
|
|
36884
36898
|
consoleOutputs: l,
|
|
36885
36899
|
stale: I,
|
|
36900
|
+
interrupted: _,
|
|
36886
36901
|
cellName: T,
|
|
36887
36902
|
onSubmitDebugger: _temp4,
|
|
36888
36903
|
cellId: d,
|
|
36889
36904
|
debuggerActive: false
|
|
36890
|
-
}), r[30] = d, r[31] = l, r[32] =
|
|
36891
|
-
let
|
|
36892
|
-
return r[
|
|
36905
|
+
}), r[30] = d, r[31] = l, r[32] = _, r[33] = T, r[34] = I, r[35] = w2) : w2 = r[35];
|
|
36906
|
+
let O2;
|
|
36907
|
+
return r[36] !== H || r[37] !== w2 || r[38] !== h2 || r[39] !== v2 || r[40] !== y2 || r[41] !== S2 ? (O2 = (0, import_jsx_runtime.jsxs)("div", {
|
|
36893
36908
|
tabIndex: -1,
|
|
36894
36909
|
ref: j,
|
|
36895
36910
|
className: H,
|
|
36896
36911
|
...h2,
|
|
36897
36912
|
children: [
|
|
36898
|
-
_2,
|
|
36899
36913
|
v2,
|
|
36900
36914
|
y2,
|
|
36901
|
-
S2
|
|
36915
|
+
S2,
|
|
36916
|
+
w2
|
|
36902
36917
|
]
|
|
36903
|
-
}), r[
|
|
36918
|
+
}), r[36] = H, r[37] = w2, r[38] = h2, r[39] = v2, r[40] = y2, r[41] = S2, r[42] = O2) : O2 = r[42], O2;
|
|
36904
36919
|
}
|
|
36905
36920
|
let W = isErrorMime(c == null ? void 0 : c.mimetype), G = O && W && Array.isArray(c == null ? void 0 : c.data) && c.data.some(_temp5);
|
|
36906
36921
|
if ((h || _ || m || W) && !G) return null;
|
|
36907
36922
|
let q;
|
|
36908
|
-
r[
|
|
36923
|
+
r[43] !== d || r[44] !== T ? (q = cellDomProps(d, T), r[43] = d, r[44] = T, r[45] = q) : q = r[45];
|
|
36909
36924
|
let zU = w === "edit", BU;
|
|
36910
|
-
r[
|
|
36925
|
+
r[46] !== d || r[47] !== R || r[48] !== c || r[49] !== I || r[50] !== zU ? (BU = (0, import_jsx_runtime.jsx)(OutputArea, {
|
|
36911
36926
|
allowExpand: zU,
|
|
36912
36927
|
output: c,
|
|
36913
36928
|
className: CSSClasses.outputArea,
|
|
36914
36929
|
cellId: d,
|
|
36915
36930
|
stale: I,
|
|
36916
36931
|
loading: R
|
|
36917
|
-
}), r[
|
|
36932
|
+
}), r[46] = d, r[47] = R, r[48] = c, r[49] = I, r[50] = zU, r[51] = BU) : BU = r[51];
|
|
36918
36933
|
let Z;
|
|
36919
|
-
return r[
|
|
36934
|
+
return r[52] !== H || r[53] !== q || r[54] !== BU ? (Z = (0, import_jsx_runtime.jsx)("div", {
|
|
36920
36935
|
tabIndex: -1,
|
|
36921
36936
|
ref: j,
|
|
36922
36937
|
className: H,
|
|
36923
36938
|
...q,
|
|
36924
36939
|
children: BU
|
|
36925
|
-
}), r[
|
|
36940
|
+
}), r[52] = H, r[53] = q, r[54] = BU, r[55] = Z) : Z = r[55], Z;
|
|
36926
36941
|
});
|
|
36927
36942
|
VerticalCell.displayName = "VerticalCell";
|
|
36928
36943
|
const VerticalLayoutPlugin = {
|
|
@@ -9,7 +9,7 @@ import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
|
9
9
|
import { ct as kioskModeAtom } from "./html-to-image-CpggM7u1.js";
|
|
10
10
|
import "./chunk-5FQGJX7Z-BOg95xG5.js";
|
|
11
11
|
import { u as createLucideIcon } from "./dist-D3ZI9nhS.js";
|
|
12
|
-
import { Ht as Code, I as Panel, L as PanelGroup, R as PanelResizeHandle, Rt as EyeOff, a as DEFAULT_SLIDE_TYPE, c as Slide, i as DEFAULT_DECK_TRANSITION, s as SlideSidebar, t as useNotebookCodeAvailable, zt as Expand } from "./code-visibility-
|
|
12
|
+
import { Ht as Code, I as Panel, L as PanelGroup, R as PanelResizeHandle, Rt as EyeOff, a as DEFAULT_SLIDE_TYPE, c as Slide, i as DEFAULT_DECK_TRANSITION, s as SlideSidebar, t as useNotebookCodeAvailable, zt as Expand } from "./code-visibility-yHhPjulC.js";
|
|
13
13
|
import { q as useDebouncedCallback } from "./input-D4kjoQUB.js";
|
|
14
14
|
import "./toDate-CIpC_34u.js";
|
|
15
15
|
import "./react-dom-BWRJ_g_k.js";
|
package/package.json
CHANGED
|
@@ -740,6 +740,7 @@ const EditableCellComponent = ({
|
|
|
740
740
|
<ConsoleOutput
|
|
741
741
|
consoleOutputs={cellRuntime.consoleOutputs}
|
|
742
742
|
stale={consoleOutputStale}
|
|
743
|
+
interrupted={cellRuntime.interrupted}
|
|
743
744
|
// Empty name if serialization triggered
|
|
744
745
|
cellName={cellRuntime.serialization ? "_" : cellData.name}
|
|
745
746
|
onRefactorWithAI={handleRefactorWithAI}
|
|
@@ -1204,6 +1205,7 @@ const SetupCellComponent = ({
|
|
|
1204
1205
|
<ConsoleOutput
|
|
1205
1206
|
consoleOutputs={cellRuntime.consoleOutputs}
|
|
1206
1207
|
stale={consoleOutputStale}
|
|
1208
|
+
interrupted={cellRuntime.interrupted}
|
|
1207
1209
|
// Don't show name
|
|
1208
1210
|
cellName={"_"}
|
|
1209
1211
|
onRefactorWithAI={handleRefactorWithAI}
|
|
@@ -85,6 +85,7 @@ interface Props {
|
|
|
85
85
|
className?: string;
|
|
86
86
|
consoleOutputs: WithResponse<OutputMessage>[];
|
|
87
87
|
stale: boolean;
|
|
88
|
+
interrupted: boolean;
|
|
88
89
|
debuggerActive: boolean;
|
|
89
90
|
onRefactorWithAI?: OnRefactorWithAI;
|
|
90
91
|
onClear?: () => void;
|
|
@@ -111,6 +112,7 @@ const ConsoleOutputInternal = (props: Props): React.ReactNode => {
|
|
|
111
112
|
const {
|
|
112
113
|
consoleOutputs: rawConsoleOutputs,
|
|
113
114
|
stale,
|
|
115
|
+
interrupted,
|
|
114
116
|
cellName,
|
|
115
117
|
cellId,
|
|
116
118
|
onSubmitDebugger,
|
|
@@ -280,6 +282,7 @@ const ConsoleOutputInternal = (props: Props): React.ReactNode => {
|
|
|
280
282
|
output={output.data}
|
|
281
283
|
response={output.response}
|
|
282
284
|
isPassword={isPassword}
|
|
285
|
+
interrupted={interrupted}
|
|
283
286
|
/>
|
|
284
287
|
);
|
|
285
288
|
}
|
|
@@ -359,9 +362,9 @@ const StdInput = (props: {
|
|
|
359
362
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
360
363
|
if (value) {
|
|
361
364
|
addToHistory(value);
|
|
362
|
-
onSubmit(value);
|
|
363
|
-
setValue("");
|
|
364
365
|
}
|
|
366
|
+
onSubmit(value);
|
|
367
|
+
setValue("");
|
|
365
368
|
e.preventDefault();
|
|
366
369
|
e.stopPropagation();
|
|
367
370
|
}
|
|
@@ -382,12 +385,27 @@ const StdInputWithResponse = (props: {
|
|
|
382
385
|
output: string;
|
|
383
386
|
response?: string;
|
|
384
387
|
isPassword?: boolean;
|
|
388
|
+
interrupted?: boolean;
|
|
385
389
|
}) => {
|
|
390
|
+
const { output, response, isPassword, interrupted } = props;
|
|
391
|
+
const hasResponse = response != null && response !== "";
|
|
392
|
+
const wasInterruptedWithoutResponse = interrupted && !hasResponse;
|
|
393
|
+
|
|
386
394
|
return (
|
|
387
395
|
<div className="flex gap-2 items-center">
|
|
388
|
-
{renderText(
|
|
389
|
-
{!
|
|
390
|
-
<span
|
|
396
|
+
{renderText(output)}
|
|
397
|
+
{!isPassword && !wasInterruptedWithoutResponse && (
|
|
398
|
+
<span
|
|
399
|
+
className="inline-flex items-center gap-1 text-(--sky-11)"
|
|
400
|
+
aria-label="stdin response"
|
|
401
|
+
>
|
|
402
|
+
<ChevronRightIcon className="w-4 h-4 shrink-0 opacity-70" />
|
|
403
|
+
{hasResponse ? (
|
|
404
|
+
response
|
|
405
|
+
) : (
|
|
406
|
+
<span className="italic opacity-70">(empty)</span>
|
|
407
|
+
)}
|
|
408
|
+
</span>
|
|
391
409
|
)}
|
|
392
410
|
</div>
|
|
393
411
|
);
|
|
@@ -28,6 +28,7 @@ describe("ConsoleOutput integration", () => {
|
|
|
28
28
|
cellName: "test_cell",
|
|
29
29
|
consoleOutputs: [] as WithResponse<OutputMessage>[],
|
|
30
30
|
stale: false,
|
|
31
|
+
interrupted: false,
|
|
31
32
|
debuggerActive: false,
|
|
32
33
|
onSubmitDebugger: () => {
|
|
33
34
|
// noop
|
|
@@ -59,6 +60,7 @@ describe("ConsoleOutput pdb history", () => {
|
|
|
59
60
|
cellName: "test_cell",
|
|
60
61
|
consoleOutputs: [] as WithResponse<OutputMessage>[],
|
|
61
62
|
stale: false,
|
|
63
|
+
interrupted: false,
|
|
62
64
|
debuggerActive: false,
|
|
63
65
|
onSubmitDebugger: vi.fn(),
|
|
64
66
|
};
|
|
@@ -118,6 +120,82 @@ describe("ConsoleOutput pdb history", () => {
|
|
|
118
120
|
expect(newInput).toHaveValue("next");
|
|
119
121
|
});
|
|
120
122
|
|
|
123
|
+
it("should submit an empty string when Enter is pressed with no input", () => {
|
|
124
|
+
// Many CLIs prompt "Press Enter to continue" and expect "" back.
|
|
125
|
+
const onSubmitDebugger = vi.fn();
|
|
126
|
+
const outputs: WithResponse<OutputMessage>[] = [
|
|
127
|
+
stdinPrompt("Press Enter to continue: "),
|
|
128
|
+
];
|
|
129
|
+
|
|
130
|
+
renderWithProvider(
|
|
131
|
+
<ConsoleOutput
|
|
132
|
+
{...defaultProps}
|
|
133
|
+
consoleOutputs={outputs}
|
|
134
|
+
onSubmitDebugger={onSubmitDebugger}
|
|
135
|
+
/>,
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
const input = screen.getByTestId("console-input");
|
|
139
|
+
fireEvent.keyDown(input, { key: "Enter" });
|
|
140
|
+
|
|
141
|
+
expect(onSubmitDebugger).toHaveBeenCalledWith("", 0);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it("should not record empty submissions in input history", () => {
|
|
145
|
+
const onSubmitDebugger = vi.fn();
|
|
146
|
+
const outputs1: WithResponse<OutputMessage>[] = [stdinPrompt("(Pdb) ")];
|
|
147
|
+
|
|
148
|
+
const { rerender } = renderWithProvider(
|
|
149
|
+
<ConsoleOutput
|
|
150
|
+
{...defaultProps}
|
|
151
|
+
consoleOutputs={outputs1}
|
|
152
|
+
onSubmitDebugger={onSubmitDebugger}
|
|
153
|
+
/>,
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
let input = screen.getByTestId("console-input");
|
|
157
|
+
fireEvent.change(input, { target: { value: "step" } });
|
|
158
|
+
fireEvent.keyDown(input, { key: "Enter" });
|
|
159
|
+
|
|
160
|
+
const outputs2: WithResponse<OutputMessage>[] = [
|
|
161
|
+
stdinPrompt("(Pdb) ", "step"),
|
|
162
|
+
stdinPrompt("(Pdb) "),
|
|
163
|
+
];
|
|
164
|
+
rerender(
|
|
165
|
+
<TooltipProvider>
|
|
166
|
+
<ConsoleOutput
|
|
167
|
+
{...defaultProps}
|
|
168
|
+
consoleOutputs={outputs2}
|
|
169
|
+
onSubmitDebugger={onSubmitDebugger}
|
|
170
|
+
/>
|
|
171
|
+
</TooltipProvider>,
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
// Submit an empty value; this should NOT enter the history stack.
|
|
175
|
+
input = screen.getByTestId("console-input");
|
|
176
|
+
fireEvent.keyDown(input, { key: "Enter" });
|
|
177
|
+
|
|
178
|
+
const outputs3: WithResponse<OutputMessage>[] = [
|
|
179
|
+
stdinPrompt("(Pdb) ", "step"),
|
|
180
|
+
stdinPrompt("(Pdb) ", ""),
|
|
181
|
+
stdinPrompt("(Pdb) "),
|
|
182
|
+
];
|
|
183
|
+
rerender(
|
|
184
|
+
<TooltipProvider>
|
|
185
|
+
<ConsoleOutput
|
|
186
|
+
{...defaultProps}
|
|
187
|
+
consoleOutputs={outputs3}
|
|
188
|
+
onSubmitDebugger={onSubmitDebugger}
|
|
189
|
+
/>
|
|
190
|
+
</TooltipProvider>,
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
// ArrowUp should jump back to "step", skipping the empty submission.
|
|
194
|
+
input = screen.getByTestId("console-input");
|
|
195
|
+
fireEvent.keyDown(input, { key: "ArrowUp" });
|
|
196
|
+
expect(input).toHaveValue("step");
|
|
197
|
+
});
|
|
198
|
+
|
|
121
199
|
it("should navigate through multiple history entries across remounts", () => {
|
|
122
200
|
const onSubmitDebugger = vi.fn();
|
|
123
201
|
|
|
@@ -192,6 +270,41 @@ describe("ConsoleOutput pdb history", () => {
|
|
|
192
270
|
fireEvent.keyDown(input, { key: "ArrowDown" });
|
|
193
271
|
expect(input).toHaveValue("");
|
|
194
272
|
});
|
|
273
|
+
|
|
274
|
+
it("should distinguish an interrupted prompt from a bare-Enter submission", () => {
|
|
275
|
+
// After interrupt, cell.ts coerces pending stdin prompts to response: "".
|
|
276
|
+
// We must render that case differently from a real bare-Enter response,
|
|
277
|
+
// so the user isn't told they "submitted" a blank value.
|
|
278
|
+
const interruptedOutputs: WithResponse<OutputMessage>[] = [
|
|
279
|
+
stdinPrompt("Press Enter to continue: ", ""),
|
|
280
|
+
];
|
|
281
|
+
|
|
282
|
+
const { rerender } = renderWithProvider(
|
|
283
|
+
<ConsoleOutput
|
|
284
|
+
{...defaultProps}
|
|
285
|
+
consoleOutputs={interruptedOutputs}
|
|
286
|
+
interrupted={true}
|
|
287
|
+
/>,
|
|
288
|
+
);
|
|
289
|
+
|
|
290
|
+
// No response chunk should be rendered for an interrupted pending prompt.
|
|
291
|
+
expect(screen.queryByLabelText("stdin response")).not.toBeInTheDocument();
|
|
292
|
+
|
|
293
|
+
// Same outputs, but the cell isn't interrupted -- this is a real
|
|
294
|
+
// bare-Enter submission, so we should render the (empty) placeholder.
|
|
295
|
+
rerender(
|
|
296
|
+
<TooltipProvider>
|
|
297
|
+
<ConsoleOutput
|
|
298
|
+
{...defaultProps}
|
|
299
|
+
consoleOutputs={interruptedOutputs}
|
|
300
|
+
interrupted={false}
|
|
301
|
+
/>
|
|
302
|
+
</TooltipProvider>,
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
expect(screen.getByLabelText("stdin response")).toBeInTheDocument();
|
|
306
|
+
expect(screen.getByText("(empty)")).toBeInTheDocument();
|
|
307
|
+
});
|
|
195
308
|
});
|
|
196
309
|
|
|
197
310
|
describe("ConsoleOutput debounced clearing", () => {
|
|
@@ -219,6 +332,7 @@ describe("ConsoleOutput debounced clearing", () => {
|
|
|
219
332
|
cellName: "test_cell",
|
|
220
333
|
consoleOutputs: [] as WithResponse<OutputMessage>[],
|
|
221
334
|
stale: false,
|
|
335
|
+
interrupted: false,
|
|
222
336
|
debuggerActive: false,
|
|
223
337
|
onSubmitDebugger: vi.fn(),
|
|
224
338
|
};
|
|
@@ -80,22 +80,26 @@ const DownloadButton = ({
|
|
|
80
80
|
const [isLoading, setIsLoading] = useState(false);
|
|
81
81
|
|
|
82
82
|
const handleClick = async (e: React.MouseEvent) => {
|
|
83
|
-
if (
|
|
83
|
+
if (data.disabled) {
|
|
84
|
+
e.preventDefault();
|
|
85
|
+
e.stopPropagation();
|
|
84
86
|
return;
|
|
85
87
|
}
|
|
86
88
|
|
|
87
|
-
|
|
89
|
+
e.preventDefault();
|
|
90
|
+
|
|
91
|
+
if (!data.lazy) {
|
|
92
|
+
downloadByURL(data.data, data.filename ?? undefined);
|
|
88
93
|
return;
|
|
89
94
|
}
|
|
90
95
|
|
|
91
|
-
e.preventDefault();
|
|
92
96
|
setIsLoading(true);
|
|
93
97
|
|
|
94
98
|
try {
|
|
95
99
|
const loadedData = await load({});
|
|
96
100
|
downloadByURL(
|
|
97
101
|
loadedData.data,
|
|
98
|
-
loadedData.filename
|
|
102
|
+
loadedData.filename ?? data.filename ?? undefined,
|
|
99
103
|
);
|
|
100
104
|
} catch (error) {
|
|
101
105
|
toast({
|
|
@@ -114,9 +118,7 @@ const DownloadButton = ({
|
|
|
114
118
|
return (
|
|
115
119
|
<a
|
|
116
120
|
href={data.data}
|
|
117
|
-
download={data.filename
|
|
118
|
-
target="_blank"
|
|
119
|
-
rel="noopener noreferrer"
|
|
121
|
+
download={data.filename ?? ""}
|
|
120
122
|
onClick={handleClick}
|
|
121
123
|
className={buttonVariants({
|
|
122
124
|
variant: "secondary",
|
package/src/utils/download.ts
CHANGED
|
@@ -175,10 +175,12 @@ export async function downloadHTMLAsImage(opts: {
|
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
export function downloadByURL(url: string, filename
|
|
178
|
+
export function downloadByURL(url: string, filename?: string) {
|
|
179
179
|
const a = document.createElement("a");
|
|
180
180
|
a.href = url;
|
|
181
|
-
|
|
181
|
+
if (filename) {
|
|
182
|
+
a.download = filename;
|
|
183
|
+
}
|
|
182
184
|
a.click();
|
|
183
185
|
a.remove();
|
|
184
186
|
}
|