@marimo-team/islands 0.23.10-dev22 → 0.23.10-dev24
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-DdeG-Hi-.js → ConnectedDataExplorerComponent-DmBropAy.js} +11 -11
- package/dist/{ErrorBoundary-rULOrC_p.js → ErrorBoundary-DpbaKVv7.js} +1 -1
- package/dist/{any-language-editor-CiES2a2h.js → any-language-editor-QDDrgvfh.js} +4 -4
- package/dist/{chat-ui-BTobdMRF.js → chat-ui-BrKSZ7Yu.js} +15 -15
- package/dist/{check-DTbrK0zt.js → check-BCaJeT-J.js} +1 -1
- package/dist/{code-visibility-PzFbkUPt.js → code-visibility-CVmFerQM.js} +18 -18
- package/dist/{copy-5jQ_kGE1.js → copy-UqRYxiOg.js} +1 -1
- package/dist/{dist-C1BYNeCR.js → dist-Dk6PV_d3.js} +10 -10
- package/dist/{error-banner-5bz0L9hS.js → error-banner-Cc0I3C9e.js} +1 -1
- package/dist/{esm-CCuYCd3R.js → esm-DzhtSSSq.js} +1 -1
- package/dist/{extends-CkydH1Q5.js → extends-C3j0Pbh9.js} +3 -3
- package/dist/{formats-DHxc-FdY.js → formats-C4wO47tk.js} +1 -1
- package/dist/{glide-data-editor-CRvL2R9l.js → glide-data-editor-Qhu8oCX-.js} +8 -8
- package/dist/{html-to-image-CjsdUYrb.js → html-to-image-D5fIgQg_.js} +13 -13
- package/dist/{input-DVkbXbIX.js → input-CMYy4hzj.js} +5 -5
- package/dist/{label-LWtdw5i8.js → label-CC4ytI1X.js} +1 -1
- package/dist/main.js +29 -29
- package/dist/{mermaid-lXOw5Py9.js → mermaid-zuLgJ8J8.js} +4 -4
- package/dist/{process-output-CI8a-CUx.js → process-output-B59yoBQx.js} +3 -3
- package/dist/{reveal-component-DEUT00rM.js → reveal-component-bghJ00sb.js} +561 -560
- package/dist/{spec-DMRQmLOc.js → spec-X7FwLJni.js} +4 -4
- package/dist/{strings-GCJA9n6d.js → strings-J57tzLr3.js} +22 -22
- package/dist/style.css +1 -1
- package/dist/{toDate-x-WRDCH7.js → toDate-d8RCRrRd.js} +2 -2
- package/dist/{tooltip-C5FYOpQc.js → tooltip-DpcyNkQ2.js} +2 -2
- package/dist/{types-CVvp1fKr.js → types-ChtMFmZ2.js} +1 -1
- package/dist/{useAsyncData-iRgKDT5s.js → useAsyncData-PonK__yh.js} +1 -1
- package/dist/{useDateFormatter-BRcO_TGJ.js → useDateFormatter-QB-3MpYr.js} +2 -2
- package/dist/{useDeepCompareMemoize-CkQ57VS2.js → useDeepCompareMemoize-D3NGWke6.js} +1 -1
- package/dist/{useLifecycle-BBO9PIph.js → useLifecycle-00mO3OSS.js} +2 -2
- package/dist/{useTheme-DHIrRQOe.js → useTheme-DEhDzATN.js} +1 -1
- package/dist/{vega-component-Dq-SH463.js → vega-component-9h1ACS78.js} +8 -8
- package/dist/{zod-CoBiJ5v4.js → zod-aLSua2NL.js} +24 -23
- package/package.json +1 -1
- package/src/components/editor/chrome/wrapper/app-chrome.tsx +97 -52
- package/src/components/editor/chrome/wrapper/lazy-panels.ts +91 -0
- package/src/components/editor/chrome/wrapper/sidebar.tsx +2 -0
- package/src/components/slides/reveal-component.tsx +4 -0
- package/src/components/ui/reorderable-list.tsx +13 -0
- package/src/utils/lazy.ts +6 -1
|
@@ -4,9 +4,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4
4
|
import { t as __commonJSMin } from "./chunk-BNovOVIE.js";
|
|
5
5
|
import { _ as Logger } from "./button-C5K9fIPF.js";
|
|
6
6
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
7
|
-
import { u as createLucideIcon } from "./dist-
|
|
7
|
+
import { u as createLucideIcon } from "./dist-Dk6PV_d3.js";
|
|
8
8
|
import { r as KnownQueryParams } from "./constants-T20xxyNf.js";
|
|
9
|
-
import { b as atom, d as store, m as isIslands, p as waitFor } from "./useTheme-
|
|
9
|
+
import { b as atom, d as store, m as isIslands, p as waitFor } from "./useTheme-DEhDzATN.js";
|
|
10
10
|
import { t as invariant } from "./invariant-wRzNXIsJ.js";
|
|
11
11
|
var CircleQuestionMark = createLucideIcon("circle-question-mark", [
|
|
12
12
|
["circle", {
|
|
@@ -2,9 +2,9 @@ import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
|
2
2
|
import { f as createSlottable, g as cn, m as useComposedRefs } from "./button-C5K9fIPF.js";
|
|
3
3
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
4
4
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
5
|
-
import { a as createPopperScope, i as Root2, n as Arrow, r as Content, s as Root, t as Anchor } from "./dist-
|
|
5
|
+
import { a as createPopperScope, i as Root2, n as Arrow, r as Content, s as Root, t as Anchor } from "./dist-Dk6PV_d3.js";
|
|
6
6
|
import { t as require_jsx_runtime } from "./jsx-runtime-DebpN0FN.js";
|
|
7
|
-
import {
|
|
7
|
+
import { Q as withSmartCollisionBoundary, Z as withFullScreenAsRoot, _t as createContextScope, at as Portal, ct as DismissableLayer, dt as useId, et as StyleNamespace, ft as Presence, ht as composeEventHandlers, pt as useControllableState, vt as Primitive } from "./zod-aLSua2NL.js";
|
|
8
8
|
var import_react = /* @__PURE__ */ __toESM(require_react(), 1), import_jsx_runtime = /* @__PURE__ */ __toESM(require_jsx_runtime(), 1), [createTooltipContext, createTooltipScope] = createContextScope("Tooltip", [createPopperScope]), usePopperScope = createPopperScope(), PROVIDER_NAME = "TooltipProvider", DEFAULT_DELAY_DURATION = 700, TOOLTIP_OPEN = "tooltip.open", [TooltipProviderContextProvider, useTooltipProviderContext] = createTooltipContext(PROVIDER_NAME), TooltipProvider$1 = (n) => {
|
|
9
9
|
let { __scopeTooltip: j, delayDuration: M = DEFAULT_DELAY_DURATION, skipDelayDuration: N = 300, disableHoverableContent: P = false, children: F } = n, I = import_react.useRef(true), L = import_react.useRef(false), R = import_react.useRef(0);
|
|
10
10
|
return import_react.useEffect(() => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { u as createLucideIcon } from "./dist-
|
|
1
|
+
import { u as createLucideIcon } from "./dist-Dk6PV_d3.js";
|
|
2
2
|
var Pencil = createLucideIcon("pencil", [["path", {
|
|
3
3
|
d: "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",
|
|
4
4
|
key: "1a8usu"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
2
2
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
3
3
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
4
|
-
import { T as useEvent_default } from "./useTheme-
|
|
4
|
+
import { T as useEvent_default } from "./useTheme-DEhDzATN.js";
|
|
5
5
|
import { t as invariant } from "./invariant-wRzNXIsJ.js";
|
|
6
6
|
var import_compiler_runtime = require_compiler_runtime(), import_react = /* @__PURE__ */ __toESM(require_react(), 1), Result = {
|
|
7
7
|
error(e, s) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
2
2
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
3
|
-
import { u as createLucideIcon } from "./dist-
|
|
4
|
-
import { E as $18f2051aff69b9bf$export$43bb16f9c6d9e3f7 } from "./strings-
|
|
3
|
+
import { u as createLucideIcon } from "./dist-Dk6PV_d3.js";
|
|
4
|
+
import { E as $18f2051aff69b9bf$export$43bb16f9c6d9e3f7 } from "./strings-J57tzLr3.js";
|
|
5
5
|
var ChartPie = createLucideIcon("chart-pie", [["path", {
|
|
6
6
|
d: "M21 12c.552 0 1.005-.449.95-.998a10 10 0 0 0-8.953-8.951c-.55-.055-.998.398-.998.95v8a1 1 0 0 0 1 1z",
|
|
7
7
|
key: "pzmjnu"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
2
2
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
3
|
-
import { w as dequal } from "./useTheme-
|
|
3
|
+
import { w as dequal } from "./useTheme-DEhDzATN.js";
|
|
4
4
|
var import_react = /* @__PURE__ */ __toESM(require_react(), 1);
|
|
5
5
|
function useDeepCompareMemoize(e) {
|
|
6
6
|
let i = import_react.useRef(e);
|
|
@@ -2,9 +2,9 @@ import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
|
2
2
|
import { _ as Logger, g as cn, r as cva } from "./button-C5K9fIPF.js";
|
|
3
3
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
4
4
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
5
|
-
import { u as createLucideIcon } from "./dist-
|
|
5
|
+
import { u as createLucideIcon } from "./dist-Dk6PV_d3.js";
|
|
6
6
|
import { t as require_jsx_runtime } from "./jsx-runtime-DebpN0FN.js";
|
|
7
|
-
import { b as atom, v as useSetAtom } from "./useTheme-
|
|
7
|
+
import { b as atom, v as useSetAtom } from "./useTheme-DEhDzATN.js";
|
|
8
8
|
var Calendar = createLucideIcon("calendar", [
|
|
9
9
|
["path", {
|
|
10
10
|
d: "M8 2v4",
|
|
@@ -2,7 +2,7 @@ import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
|
2
2
|
import { _ as Logger, a as OverridingHotkeyProvider, s as resolvePlatform } from "./button-C5K9fIPF.js";
|
|
3
3
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
4
4
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
5
|
-
import { A as looseObject, B as union, I as record, N as number, P as object, R as string, T as boolean, b as _enum, w as array } from "./zod-
|
|
5
|
+
import { A as looseObject, B as union, I as record, N as number, P as object, R as string, T as boolean, b as _enum, w as array } from "./zod-aLSua2NL.js";
|
|
6
6
|
import { t as merge_default } from "./merge-Be1CqGnU.js";
|
|
7
7
|
var import_react = /* @__PURE__ */ __toESM(require_react()), useInsertionEffect = typeof window < "u" ? import_react.useInsertionEffect || import_react.useLayoutEffect : () => {
|
|
8
8
|
};
|
|
@@ -2,23 +2,23 @@ import { s as __toESM } from "./chunk-BNovOVIE.js";
|
|
|
2
2
|
import { _ as Logger, c as Objects, g as cn, h as Events } from "./button-C5K9fIPF.js";
|
|
3
3
|
import { t as require_react } from "./react-DA-nE2FX.js";
|
|
4
4
|
import { t as require_compiler_runtime } from "./compiler-runtime-CEbnTgxf.js";
|
|
5
|
-
import { c as asRemoteURL, v as CircleQuestionMark } from "./toDate-
|
|
5
|
+
import { c as asRemoteURL, v as CircleQuestionMark } from "./toDate-d8RCRrRd.js";
|
|
6
6
|
import "./react-dom-BTJzcVJ9.js";
|
|
7
7
|
import { t as require_jsx_runtime } from "./jsx-runtime-DebpN0FN.js";
|
|
8
|
-
import "./zod-
|
|
9
|
-
import { n as ErrorBanner } from "./error-banner-
|
|
10
|
-
import { t as Tooltip } from "./tooltip-
|
|
8
|
+
import "./zod-aLSua2NL.js";
|
|
9
|
+
import { n as ErrorBanner } from "./error-banner-Cc0I3C9e.js";
|
|
10
|
+
import { t as Tooltip } from "./tooltip-DpcyNkQ2.js";
|
|
11
11
|
import { i as debounce_default } from "./constants-T20xxyNf.js";
|
|
12
|
-
import { T as useEvent_default, n as useTheme } from "./useTheme-
|
|
12
|
+
import { T as useEvent_default, n as useTheme } from "./useTheme-DEhDzATN.js";
|
|
13
13
|
import { s as uniq } from "./arrays-sEtDRoG4.js";
|
|
14
|
-
import { a as isValid, i as AlertTitle, n as Alert, t as arrow } from "./formats-
|
|
14
|
+
import { a as isValid, i as AlertTitle, n as Alert, t as arrow } from "./formats-C4wO47tk.js";
|
|
15
15
|
import { n as formats } from "./vega-loader.browser-CZ-J8Py3.js";
|
|
16
16
|
import { a as getContainerWidth, n as vegaLoadData, s as tooltipHandler } from "./loader-BWLPpjKK.js";
|
|
17
17
|
import { t as j } from "./react-vega-B0sAlDTL.js";
|
|
18
18
|
import "./defaultLocale-u-3osm0P.js";
|
|
19
19
|
import "./defaultLocale-BoHTsDG6.js";
|
|
20
|
-
import { t as useAsyncData } from "./useAsyncData-
|
|
21
|
-
import { t as useDeepCompareMemoize } from "./useDeepCompareMemoize-
|
|
20
|
+
import { t as useAsyncData } from "./useAsyncData-PonK__yh.js";
|
|
21
|
+
import { t as useDeepCompareMemoize } from "./useDeepCompareMemoize-D3NGWke6.js";
|
|
22
22
|
import { t as Semaphore } from "./semaphore-CNDGTzkX.js";
|
|
23
23
|
var import_compiler_runtime = require_compiler_runtime(), import_react = /* @__PURE__ */ __toESM(require_react(), 1);
|
|
24
24
|
function fixRelativeUrl(e) {
|
|
@@ -11758,7 +11758,7 @@ var external_exports = /* @__PURE__ */ __export({
|
|
|
11758
11758
|
config(en_default());
|
|
11759
11759
|
var zod_default = external_exports;
|
|
11760
11760
|
export {
|
|
11761
|
-
|
|
11761
|
+
isInVscodeExtension as $,
|
|
11762
11762
|
looseObject as A,
|
|
11763
11763
|
union as B,
|
|
11764
11764
|
any as C,
|
|
@@ -11775,59 +11775,60 @@ export {
|
|
|
11775
11775
|
number$1 as N,
|
|
11776
11776
|
lazy as O,
|
|
11777
11777
|
object as P,
|
|
11778
|
-
|
|
11778
|
+
withSmartCollisionBoundary as Q,
|
|
11779
11779
|
string$1 as R,
|
|
11780
11780
|
_null as S,
|
|
11781
11781
|
boolean$1 as T,
|
|
11782
11782
|
ZodError as U,
|
|
11783
11783
|
unknown as V,
|
|
11784
11784
|
toJSONSchema as W,
|
|
11785
|
-
|
|
11785
|
+
useFullScreenElement as X,
|
|
11786
11786
|
MAX_HEIGHT_OFFSET as Y,
|
|
11787
|
-
|
|
11787
|
+
withFullScreenAsRoot as Z,
|
|
11788
11788
|
ZodString as _,
|
|
11789
|
-
|
|
11789
|
+
createContextScope as _t,
|
|
11790
11790
|
ZodIssueCode as a,
|
|
11791
|
-
|
|
11791
|
+
Portal as at,
|
|
11792
11792
|
_enum as b,
|
|
11793
11793
|
ZodBoolean as c,
|
|
11794
|
-
|
|
11794
|
+
DismissableLayer as ct,
|
|
11795
11795
|
ZodDiscriminatedUnion as d,
|
|
11796
|
-
|
|
11797
|
-
|
|
11796
|
+
useId as dt,
|
|
11797
|
+
StyleNamespace as et,
|
|
11798
11798
|
ZodEnum as f,
|
|
11799
|
-
|
|
11799
|
+
Presence as ft,
|
|
11800
11800
|
ZodOptional as g,
|
|
11801
|
-
|
|
11801
|
+
createContext2 as gt,
|
|
11802
11802
|
ZodObject as h,
|
|
11803
|
-
|
|
11803
|
+
composeEventHandlers as ht,
|
|
11804
11804
|
string as i,
|
|
11805
|
-
|
|
11805
|
+
useFocusGuards as it,
|
|
11806
11806
|
nan as j,
|
|
11807
11807
|
literal as k,
|
|
11808
11808
|
ZodDate as l,
|
|
11809
|
-
|
|
11809
|
+
Root as lt,
|
|
11810
11810
|
ZodNumber as m,
|
|
11811
|
-
|
|
11811
|
+
useLayoutEffect2 as mt,
|
|
11812
11812
|
date as n,
|
|
11813
|
-
|
|
11813
|
+
Combination_default as nt,
|
|
11814
11814
|
ZodAny as o,
|
|
11815
|
-
|
|
11815
|
+
FocusScope as ot,
|
|
11816
11816
|
ZodLiteral as p,
|
|
11817
|
-
|
|
11817
|
+
useControllableState as pt,
|
|
11818
11818
|
$ZodError as q,
|
|
11819
11819
|
number as r,
|
|
11820
|
-
|
|
11820
|
+
__awaiter as rt,
|
|
11821
11821
|
ZodArray as s,
|
|
11822
|
-
|
|
11822
|
+
Branch as st,
|
|
11823
11823
|
zod_default as t,
|
|
11824
|
-
|
|
11824
|
+
hideOthers as tt,
|
|
11825
11825
|
ZodDefault as u,
|
|
11826
|
-
|
|
11826
|
+
useCallbackRef$1 as ut,
|
|
11827
11827
|
ZodType as v,
|
|
11828
|
-
|
|
11828
|
+
Primitive as vt,
|
|
11829
11829
|
array as w,
|
|
11830
11830
|
_instanceof as x,
|
|
11831
11831
|
ZodUnion as y,
|
|
11832
|
+
dispatchDiscreteCustomEvent as yt,
|
|
11832
11833
|
tuple as z
|
|
11833
11834
|
};
|
package/package.json
CHANGED
|
@@ -34,6 +34,26 @@ import { ErrorBoundary } from "../../boundary/ErrorBoundary";
|
|
|
34
34
|
import { raf2 } from "../../navigation/focus-utils";
|
|
35
35
|
import { ContextAwarePanel } from "../panels/context-aware-panel/context-aware-panel";
|
|
36
36
|
import { PanelSectionProvider } from "../panels/panel-context";
|
|
37
|
+
import { useTheme } from "@/theme/useTheme";
|
|
38
|
+
import {
|
|
39
|
+
LazyAgentPanel,
|
|
40
|
+
LazyCachePanel,
|
|
41
|
+
LazyChatPanel,
|
|
42
|
+
LazyDependencyGraphPanel,
|
|
43
|
+
LazyDocumentationPanel,
|
|
44
|
+
LazyErrorsPanel,
|
|
45
|
+
LazyFileExplorerPanel,
|
|
46
|
+
LazyLogsPanel,
|
|
47
|
+
LazyOutlinePanel,
|
|
48
|
+
LazyPackagesPanel,
|
|
49
|
+
LazyScratchpadPanel,
|
|
50
|
+
LazySecretsPanel,
|
|
51
|
+
LazySessionPanel,
|
|
52
|
+
LazySnippetsPanel,
|
|
53
|
+
LazyTerminal,
|
|
54
|
+
LazyTracingPanel,
|
|
55
|
+
PANEL_PRELOADERS,
|
|
56
|
+
} from "./lazy-panels";
|
|
37
57
|
import { panelLayoutAtom, useChromeActions, useChromeState } from "../state";
|
|
38
58
|
import {
|
|
39
59
|
isPanelHidden,
|
|
@@ -50,33 +70,26 @@ import { useAiPanelTab } from "./useAiPanel";
|
|
|
50
70
|
import { useDependencyPanelTab } from "./useDependencyPanelTab";
|
|
51
71
|
import { handleDragging } from "./utils";
|
|
52
72
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
() => import("../panels/scratchpad-panel"),
|
|
74
|
-
);
|
|
75
|
-
const LazySecretsPanel = React.lazy(() => import("../panels/secrets-panel"));
|
|
76
|
-
const LazySnippetsPanel = React.lazy(() => import("../panels/snippets-panel"));
|
|
77
|
-
const LazyTracingPanel = React.lazy(() => import("../panels/tracing-panel"));
|
|
78
|
-
const LazyCachePanel = React.lazy(() => import("../panels/cache-panel"));
|
|
79
|
-
|
|
73
|
+
// Placeholder that matches the eventual xterm theme background so the
|
|
74
|
+
// transition into the loaded terminal is seamless rather than a blank flash.
|
|
75
|
+
const TerminalSkeleton: React.FC = () => {
|
|
76
|
+
const { theme } = useTheme();
|
|
77
|
+
const isDark = theme === "dark";
|
|
78
|
+
return (
|
|
79
|
+
<div
|
|
80
|
+
aria-label="Loading terminal"
|
|
81
|
+
role="status"
|
|
82
|
+
className="w-full h-full flex items-start p-3 font-mono text-xs select-none"
|
|
83
|
+
style={{
|
|
84
|
+
background: isDark ? "#0f172a" : "#ffffff",
|
|
85
|
+
color: isDark ? "#94a3b8" : "#64748b",
|
|
86
|
+
}}
|
|
87
|
+
>
|
|
88
|
+
<span className="opacity-70">Starting terminal</span>
|
|
89
|
+
<span className="ml-1 inline-block w-2 h-3.5 align-middle bg-current animate-pulse" />
|
|
90
|
+
</div>
|
|
91
|
+
);
|
|
92
|
+
};
|
|
80
93
|
export const AppChrome: React.FC<PropsWithChildren> = ({ children }) => {
|
|
81
94
|
const {
|
|
82
95
|
isSidebarOpen,
|
|
@@ -96,6 +109,33 @@ export const AppChrome: React.FC<PropsWithChildren> = ({ children }) => {
|
|
|
96
109
|
const capabilities = useAtomValue(capabilitiesAtom);
|
|
97
110
|
const aiEnabled = useAtomValue(aiEnabledAtom);
|
|
98
111
|
|
|
112
|
+
// On mount, idle-preload whichever panels the user had open at last unload,
|
|
113
|
+
// so the first interaction with the sidebar/dev panel doesn't hit a cold
|
|
114
|
+
// chunk fetch. Runs once.
|
|
115
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
const preloadOpenPanels = () => {
|
|
118
|
+
if (isSidebarOpen && selectedPanel) {
|
|
119
|
+
PANEL_PRELOADERS[selectedPanel]?.();
|
|
120
|
+
}
|
|
121
|
+
if (isDeveloperPanelOpen && selectedDeveloperPanelTab) {
|
|
122
|
+
PANEL_PRELOADERS[selectedDeveloperPanelTab]?.();
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const canIdle =
|
|
127
|
+
typeof window !== "undefined" &&
|
|
128
|
+
typeof window.requestIdleCallback === "function";
|
|
129
|
+
if (canIdle) {
|
|
130
|
+
const handle = window.requestIdleCallback(preloadOpenPanels, {
|
|
131
|
+
timeout: 2000,
|
|
132
|
+
});
|
|
133
|
+
return () => window.cancelIdleCallback(handle);
|
|
134
|
+
}
|
|
135
|
+
const handle = setTimeout(preloadOpenPanels, 300);
|
|
136
|
+
return () => clearTimeout(handle);
|
|
137
|
+
}, []);
|
|
138
|
+
|
|
99
139
|
// Convert current developer panel items to PanelDescriptors
|
|
100
140
|
// Filter out hidden panels (e.g., terminal when capability is not available)
|
|
101
141
|
const devPanelItems = useMemo(() => {
|
|
@@ -256,32 +296,34 @@ export const AppChrome: React.FC<PropsWithChildren> = ({ children }) => {
|
|
|
256
296
|
|
|
257
297
|
const renderAiPanel = () => {
|
|
258
298
|
if (agentsEnabled && aiPanelTab === "agents") {
|
|
259
|
-
return <LazyAgentPanel />;
|
|
299
|
+
return <LazyAgentPanel.Component />;
|
|
260
300
|
}
|
|
261
|
-
return <LazyChatPanel />;
|
|
301
|
+
return <LazyChatPanel.Component />;
|
|
262
302
|
};
|
|
263
303
|
|
|
264
304
|
const SIDEBAR_PANELS: Record<PanelType, React.ReactNode> = {
|
|
265
|
-
files: <LazyFileExplorerPanel />,
|
|
266
|
-
variables: <LazySessionPanel />,
|
|
267
|
-
dependencies: <LazyDependencyGraphPanel />,
|
|
268
|
-
packages: <LazyPackagesPanel />,
|
|
269
|
-
outline: <LazyOutlinePanel />,
|
|
270
|
-
documentation: <LazyDocumentationPanel />,
|
|
271
|
-
snippets: <LazySnippetsPanel />,
|
|
305
|
+
files: <LazyFileExplorerPanel.Component />,
|
|
306
|
+
variables: <LazySessionPanel.Component />,
|
|
307
|
+
dependencies: <LazyDependencyGraphPanel.Component />,
|
|
308
|
+
packages: <LazyPackagesPanel.Component />,
|
|
309
|
+
outline: <LazyOutlinePanel.Component />,
|
|
310
|
+
documentation: <LazyDocumentationPanel.Component />,
|
|
311
|
+
snippets: <LazySnippetsPanel.Component />,
|
|
272
312
|
ai: renderAiPanel(),
|
|
273
|
-
errors: <LazyErrorsPanel />,
|
|
274
|
-
scratchpad: <LazyScratchpadPanel />,
|
|
275
|
-
tracing: <LazyTracingPanel />,
|
|
276
|
-
secrets: <LazySecretsPanel />,
|
|
277
|
-
logs: <LazyLogsPanel />,
|
|
313
|
+
errors: <LazyErrorsPanel.Component />,
|
|
314
|
+
scratchpad: <LazyScratchpadPanel.Component />,
|
|
315
|
+
tracing: <LazyTracingPanel.Component />,
|
|
316
|
+
secrets: <LazySecretsPanel.Component />,
|
|
317
|
+
logs: <LazyLogsPanel.Component />,
|
|
278
318
|
terminal: (
|
|
279
|
-
<
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
319
|
+
<Suspense fallback={<TerminalSkeleton />}>
|
|
320
|
+
<LazyTerminal.Component
|
|
321
|
+
visible={isSidebarOpen && selectedPanel === "terminal"}
|
|
322
|
+
onClose={() => setIsSidebarOpen(false)}
|
|
323
|
+
/>
|
|
324
|
+
</Suspense>
|
|
283
325
|
),
|
|
284
|
-
cache: <LazyCachePanel />,
|
|
326
|
+
cache: <LazyCachePanel.Component />,
|
|
285
327
|
};
|
|
286
328
|
|
|
287
329
|
const helpPaneBody = (
|
|
@@ -414,12 +456,14 @@ export const AppChrome: React.FC<PropsWithChildren> = ({ children }) => {
|
|
|
414
456
|
const DEVELOPER_PANELS: Record<PanelType, React.ReactNode> = {
|
|
415
457
|
...SIDEBAR_PANELS,
|
|
416
458
|
terminal: (
|
|
417
|
-
<
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
459
|
+
<Suspense fallback={<TerminalSkeleton />}>
|
|
460
|
+
<LazyTerminal.Component
|
|
461
|
+
visible={
|
|
462
|
+
isDeveloperPanelOpen && selectedDeveloperPanelTab === "terminal"
|
|
463
|
+
}
|
|
464
|
+
onClose={() => setIsDeveloperPanelOpen(false)}
|
|
465
|
+
/>
|
|
466
|
+
</Suspense>
|
|
423
467
|
),
|
|
424
468
|
};
|
|
425
469
|
|
|
@@ -474,6 +518,7 @@ export const AppChrome: React.FC<PropsWithChildren> = ({ children }) => {
|
|
|
474
518
|
className="flex flex-row gap-1"
|
|
475
519
|
minItems={0}
|
|
476
520
|
onAction={(panel) => openApplication(panel.type)}
|
|
521
|
+
onItemPreloadHint={(panel) => PANEL_PRELOADERS[panel.type]?.()}
|
|
477
522
|
renderItem={(panel) => (
|
|
478
523
|
<div
|
|
479
524
|
className={cn(
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/* Copyright 2026 Marimo. All rights reserved. */
|
|
2
|
+
|
|
3
|
+
import { reactLazyWithPreload } from "@/utils/lazy";
|
|
4
|
+
import { Logger } from "@/utils/Logger";
|
|
5
|
+
import type { PanelType } from "../types";
|
|
6
|
+
|
|
7
|
+
// Preloading is best-effort: a chunk-load failure here should not surface as
|
|
8
|
+
// an unhandled rejection (the panel will retry the import when actually
|
|
9
|
+
// rendered, where Suspense/ErrorBoundary handle the failure).
|
|
10
|
+
const safePreload = (lazy: { preload: () => Promise<unknown> }) => (): void => {
|
|
11
|
+
void lazy.preload().catch((error) => {
|
|
12
|
+
Logger.debug("Failed to preload panel chunk", error);
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// Centralized lazy panels. Using reactLazyWithPreload (instead of React.lazy)
|
|
17
|
+
// gives each panel a .preload() method so the chunk can be fetched on intent
|
|
18
|
+
// (hovering the sidebar icon or developer-panel tab) before the user clicks.
|
|
19
|
+
|
|
20
|
+
export const LazyTerminal = reactLazyWithPreload(
|
|
21
|
+
() => import("@/components/terminal/terminal"),
|
|
22
|
+
);
|
|
23
|
+
export const LazyChatPanel = reactLazyWithPreload(
|
|
24
|
+
() => import("@/components/chat/chat-panel"),
|
|
25
|
+
);
|
|
26
|
+
export const LazyAgentPanel = reactLazyWithPreload(
|
|
27
|
+
() => import("@/components/chat/acp/agent-panel"),
|
|
28
|
+
);
|
|
29
|
+
export const LazyDependencyGraphPanel = reactLazyWithPreload(
|
|
30
|
+
() => import("../panels/dependency-graph-panel"),
|
|
31
|
+
);
|
|
32
|
+
export const LazySessionPanel = reactLazyWithPreload(
|
|
33
|
+
() => import("../panels/session-panel"),
|
|
34
|
+
);
|
|
35
|
+
export const LazyDocumentationPanel = reactLazyWithPreload(
|
|
36
|
+
() => import("../panels/documentation-panel"),
|
|
37
|
+
);
|
|
38
|
+
export const LazyErrorsPanel = reactLazyWithPreload(
|
|
39
|
+
() => import("../panels/error-panel"),
|
|
40
|
+
);
|
|
41
|
+
export const LazyFileExplorerPanel = reactLazyWithPreload(
|
|
42
|
+
() => import("../panels/file-explorer-panel"),
|
|
43
|
+
);
|
|
44
|
+
export const LazyLogsPanel = reactLazyWithPreload(
|
|
45
|
+
() => import("../panels/logs-panel"),
|
|
46
|
+
);
|
|
47
|
+
export const LazyOutlinePanel = reactLazyWithPreload(
|
|
48
|
+
() => import("../panels/outline-panel"),
|
|
49
|
+
);
|
|
50
|
+
export const LazyPackagesPanel = reactLazyWithPreload(
|
|
51
|
+
() => import("../panels/packages-panel"),
|
|
52
|
+
);
|
|
53
|
+
export const LazyScratchpadPanel = reactLazyWithPreload(
|
|
54
|
+
() => import("../panels/scratchpad-panel"),
|
|
55
|
+
);
|
|
56
|
+
export const LazySecretsPanel = reactLazyWithPreload(
|
|
57
|
+
() => import("../panels/secrets-panel"),
|
|
58
|
+
);
|
|
59
|
+
export const LazySnippetsPanel = reactLazyWithPreload(
|
|
60
|
+
() => import("../panels/snippets-panel"),
|
|
61
|
+
);
|
|
62
|
+
export const LazyTracingPanel = reactLazyWithPreload(
|
|
63
|
+
() => import("../panels/tracing-panel"),
|
|
64
|
+
);
|
|
65
|
+
export const LazyCachePanel = reactLazyWithPreload(
|
|
66
|
+
() => import("../panels/cache-panel"),
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
// Preloader registry: hovering an icon/tab calls into this map to warm the
|
|
70
|
+
// corresponding chunk. Two panel types (chat and agents) share the "ai" slot,
|
|
71
|
+
// so we preload both.
|
|
72
|
+
export const PANEL_PRELOADERS: Record<PanelType, () => void> = {
|
|
73
|
+
files: safePreload(LazyFileExplorerPanel),
|
|
74
|
+
variables: safePreload(LazySessionPanel),
|
|
75
|
+
dependencies: safePreload(LazyDependencyGraphPanel),
|
|
76
|
+
packages: safePreload(LazyPackagesPanel),
|
|
77
|
+
outline: safePreload(LazyOutlinePanel),
|
|
78
|
+
documentation: safePreload(LazyDocumentationPanel),
|
|
79
|
+
snippets: safePreload(LazySnippetsPanel),
|
|
80
|
+
ai: () => {
|
|
81
|
+
safePreload(LazyChatPanel)();
|
|
82
|
+
safePreload(LazyAgentPanel)();
|
|
83
|
+
},
|
|
84
|
+
errors: safePreload(LazyErrorsPanel),
|
|
85
|
+
scratchpad: safePreload(LazyScratchpadPanel),
|
|
86
|
+
tracing: safePreload(LazyTracingPanel),
|
|
87
|
+
secrets: safePreload(LazySecretsPanel),
|
|
88
|
+
logs: safePreload(LazyLogsPanel),
|
|
89
|
+
terminal: safePreload(LazyTerminal),
|
|
90
|
+
cache: safePreload(LazyCachePanel),
|
|
91
|
+
};
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
PANELS,
|
|
23
23
|
type PanelDescriptor,
|
|
24
24
|
} from "../types";
|
|
25
|
+
import { PANEL_PRELOADERS } from "./lazy-panels";
|
|
25
26
|
|
|
26
27
|
export const Sidebar: React.FC = () => {
|
|
27
28
|
const { selectedPanel, selectedDeveloperPanelTab, isSidebarOpen } =
|
|
@@ -141,6 +142,7 @@ export const Sidebar: React.FC = () => {
|
|
|
141
142
|
className="flex flex-col gap-0"
|
|
142
143
|
minItems={0}
|
|
143
144
|
onAction={(panel) => toggleApplication(panel.type)}
|
|
145
|
+
onItemPreloadHint={(panel) => PANEL_PRELOADERS[panel.type]?.()}
|
|
144
146
|
renderItem={(panel) => (
|
|
145
147
|
<SidebarItem
|
|
146
148
|
tooltip={panel.tooltip}
|
|
@@ -14,6 +14,7 @@ import { Deck, Fragment, Slide, Stack } from "@revealjs/react";
|
|
|
14
14
|
import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";
|
|
15
15
|
import { Slide as CellOutputSlide } from "@/components/slides/slide";
|
|
16
16
|
import { Button } from "@/components/ui/button";
|
|
17
|
+
import { useFullScreenElement } from "@/components/ui/fullscreen";
|
|
17
18
|
import { Tooltip } from "@/components/ui/tooltip";
|
|
18
19
|
import type { CellId } from "@/core/cells/ids";
|
|
19
20
|
import type { RuntimeCell } from "@/core/cells/types";
|
|
@@ -274,6 +275,8 @@ const RevealSlidesComponent = ({
|
|
|
274
275
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
275
276
|
const deckRef = useRef<RevealApi | null>(null);
|
|
276
277
|
const { width, height } = useSlideDimensions(containerRef);
|
|
278
|
+
const isFullscreen = useFullScreenElement() != null;
|
|
279
|
+
|
|
277
280
|
// Skip the Notes plugin inside reveal's own speaker-view iframes so pressing
|
|
278
281
|
// `S` there doesn't try to spawn another popup.
|
|
279
282
|
const kioskMode = useAtomValue(kioskModeAtom);
|
|
@@ -607,6 +610,7 @@ const RevealSlidesComponent = ({
|
|
|
607
610
|
<PanelResizeHandle
|
|
608
611
|
className="mo-slides-notes-resize"
|
|
609
612
|
hitAreaMargins={{ coarse: 12, fine: 4 }}
|
|
613
|
+
disabled={isFullscreen}
|
|
610
614
|
/>
|
|
611
615
|
<Panel
|
|
612
616
|
defaultSize={10}
|
|
@@ -57,6 +57,12 @@ export interface ReorderableListProps<T> {
|
|
|
57
57
|
* Callback when an item is clicked
|
|
58
58
|
*/
|
|
59
59
|
onAction?: (item: T) => void;
|
|
60
|
+
/**
|
|
61
|
+
* Fired when an item is hovered or focused. Useful for preloading the
|
|
62
|
+
* resource the item points to before it is activated. Attached to the
|
|
63
|
+
* focusable list item so it works for both pointer and keyboard users.
|
|
64
|
+
*/
|
|
65
|
+
onItemPreloadHint?: (item: T) => void;
|
|
60
66
|
/**
|
|
61
67
|
* All available items that can be added to the list
|
|
62
68
|
*/
|
|
@@ -142,6 +148,7 @@ export const ReorderableList = <T extends object>({
|
|
|
142
148
|
ariaLabel = "Reorderable list",
|
|
143
149
|
className,
|
|
144
150
|
crossListDrag,
|
|
151
|
+
onItemPreloadHint,
|
|
145
152
|
}: ReorderableListProps<T>) => {
|
|
146
153
|
const mimeType = crossListDrag
|
|
147
154
|
? getDragMimeType(crossListDrag.dragType)
|
|
@@ -294,6 +301,12 @@ export const ReorderableList = <T extends object>({
|
|
|
294
301
|
key={getKey(item)}
|
|
295
302
|
id={getKey(item)}
|
|
296
303
|
className="active:cursor-grabbing data-[dragging]:opacity-60 outline-none"
|
|
304
|
+
onHoverStart={
|
|
305
|
+
onItemPreloadHint ? () => onItemPreloadHint(item) : undefined
|
|
306
|
+
}
|
|
307
|
+
onFocus={
|
|
308
|
+
onItemPreloadHint ? () => onItemPreloadHint(item) : undefined
|
|
309
|
+
}
|
|
297
310
|
>
|
|
298
311
|
{renderItem(item)}
|
|
299
312
|
</ListBoxItem>
|
package/src/utils/lazy.ts
CHANGED
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
import React from "react";
|
|
4
4
|
|
|
5
5
|
interface LazyComponentWithPreload<T> {
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Eagerly trigger the dynamic import. Returns the import promise so callers
|
|
8
|
+
* can await it or attach error handling; safe to call multiple times (the
|
|
9
|
+
* import is memoized).
|
|
10
|
+
*/
|
|
11
|
+
preload: () => Promise<{ default: React.ComponentType<T> }>;
|
|
7
12
|
Component: React.LazyExoticComponent<React.ComponentType<T>>;
|
|
8
13
|
}
|
|
9
14
|
|