@marimo-team/islands 0.23.10-dev8 → 0.23.10
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-CyV83R2m.js → ConnectedDataExplorerComponent-Z3RP7Vmm.js} +31 -31
- package/dist/{ErrorBoundary-rULOrC_p.js → ErrorBoundary-DpbaKVv7.js} +1 -1
- package/dist/{any-language-editor-CiES2a2h.js → any-language-editor-CAgFD4Kd.js} +20 -20
- package/dist/assets/__vite-browser-external-eshhtsgZ.js +1 -0
- package/dist/assets/worker-CC0Oul9k.js +73 -0
- package/dist/{chat-ui-K84W5ecY.js → chat-ui-C4-GMW9y.js} +77 -77
- package/dist/{check-DTbrK0zt.js → check-BCaJeT-J.js} +1 -1
- package/dist/{chunk-5FQGJX7Z-BNjes6Yx.js → chunk-5FQGJX7Z-BbqSm5gU.js} +1227 -1222
- package/dist/{code-block-37QAKDTI-m92Yc8pv.js → code-block-37QAKDTI-O6IH6wAi.js} +1 -1
- package/dist/{code-visibility-ChnpTxqU.js → code-visibility-DrFozVlm.js} +1943 -1223
- package/dist/{copy-5jQ_kGE1.js → copy-UqRYxiOg.js} +1 -1
- package/dist/dist-7QfXoMdB.js +5 -0
- package/dist/{dist-DgnE8F-r.js → dist-A2846XWO.js} +1 -1
- package/dist/dist-BEXXyZig.js +5 -0
- package/dist/{dist-B3pZ0Ab6.js → dist-BR_gyG9L.js} +3 -3
- package/dist/{dist-CcXxepx6.js → dist-BSAt6RhH.js} +27 -27
- package/dist/{dist-Bde4a2kU.js → dist-BY018Paw.js} +8 -8
- package/dist/dist-BYj57OV4.js +5 -0
- package/dist/{dist-CUCNs1ja.js → dist-BaoDKvdy.js} +2 -2
- package/dist/{dist-Cy1WxgBD.js → dist-Bf7SHuNp.js} +5 -5
- package/dist/{dist-Bz_sYWbr.js → dist-Bk75fBZA.js} +2 -2
- package/dist/dist-BlSvQzNr.js +5 -0
- package/dist/{dist-C5VC_yzu.js → dist-BzEzfugY.js} +1 -1
- package/dist/dist-CCBlxAgS.js +8 -0
- package/dist/dist-CIDTVIUf.js +5 -0
- package/dist/{dist-CLUtPrdy.js → dist-CIYBwstr.js} +1 -1
- package/dist/{dist-BotSqB48.js → dist-C_Y3oV3C.js} +12 -12
- package/dist/{dist-BTfv03uy.js → dist-CcWX6tmx.js} +2 -2
- package/dist/{dist-BhM8gdSO.js → dist-CoXAujgg.js} +4 -4
- package/dist/{dist-4j4c7bjm.js → dist-CpxNdDkw.js} +3 -3
- package/dist/dist-CqQyhAM8.js +8 -0
- package/dist/dist-CwRu2Xzh.js +5 -0
- package/dist/{dist-BcuoonNH.js → dist-CxJDU6Bh.js} +9 -9
- package/dist/{dist-DxvORzUR.js → dist-D-W5ny5a.js} +8 -8
- package/dist/dist-D8CDTVgf.js +6 -0
- package/dist/dist-D8DNB0nO.js +8 -0
- package/dist/dist-DL6N_q-A.js +5 -0
- package/dist/{dist-BbbIBDiQ.js → dist-DMjWuVs8.js} +1 -1
- package/dist/dist-DOFbNV_b.js +8 -0
- package/dist/dist-DPrYzMY0.js +6 -0
- package/dist/{dist-h2c8sZvT.js → dist-DZORgqKY.js} +1 -1
- package/dist/{dist-B3P2fFpz.js → dist-DZo4nSS0.js} +14 -14
- package/dist/{dist-D4CewLk6.js → dist-Dax--nl9.js} +1 -1
- package/dist/{dist-DRfcqpxJ.js → dist-DgGbNavJ.js} +2 -2
- package/dist/{dist-C1BYNeCR.js → dist-Dk6PV_d3.js} +10 -10
- package/dist/{dist-fQ0ViXGs.js → dist-Dv_Y15yk.js} +107 -107
- package/dist/{dist-Bfwsv11D.js → dist-DyyjKEYf.js} +2 -2
- package/dist/{dist-p2qyWijU.js → dist-GZXUmt0b.js} +2 -2
- package/dist/{dist-CLJWPTX2.js → dist-LTU8Hdvn.js} +3 -3
- package/dist/{dist-DqAWR3CS.js → dist-M9Vag9Y0.js} +20 -20
- package/dist/{dist-DNdhYsgW.js → dist-U4F-tbMs.js} +79 -62
- package/dist/{dist-RqXTaiir.js → dist-abid3KgM.js} +11 -11
- package/dist/dist-cdmMjgsn.js +5 -0
- package/dist/dist-hT4QzYX-.js +1247 -0
- package/dist/{dist-luvabDEB.js → dist-t9Kf7xqC.js} +2 -2
- package/dist/{error-banner-5bz0L9hS.js → error-banner-CJXYJ6Sb.js} +11 -6
- package/dist/esm-BaH2eg5-.js +1171 -0
- package/dist/{esm-Duie8iU-.js → esm-ga2Bf3O2.js} +43 -43
- package/dist/{extends-CkydH1Q5.js → extends-D_hDsj6R.js} +4 -4
- package/dist/files/wasm-intro.py +11 -8
- package/dist/{formats-DHxc-FdY.js → formats-C4wO47tk.js} +1 -1
- package/dist/{glide-data-editor-CgIxTzAP.js → glide-data-editor-BPkCPs7L.js} +255 -255
- package/dist/{html-to-image-B93KtAVY.js → html-to-image-BwfcJJxA.js} +2412 -2282
- package/dist/{input-_2sjvfne.js → input-OdWHkobi.js} +263 -245
- package/dist/{label-LWtdw5i8.js → label-CC4ytI1X.js} +1 -1
- package/dist/main.js +7630 -7558
- package/dist/{mermaid-4DMBBIKO-DIdL224_.js → mermaid-4DMBBIKO-Eg3D4FVz.js} +1 -1
- package/dist/{mermaid-lXOw5Py9.js → mermaid-BotvIKg9.js} +4 -4
- package/dist/{process-output-BOXi9fnS.js → process-output-DsloEDna.js} +3 -3
- package/dist/{reveal-component-OrljHylW.js → reveal-component-3YQBHWuD.js} +698 -620
- package/dist/{spec-B96zNUEA.js → spec-X7FwLJni.js} +4 -4
- package/dist/{strings-Bu3vlb6W.js → strings-J57tzLr3.js} +47 -46
- 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-BA4FCquG.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-DGPUhbDs.js} +8 -8
- package/dist/{zod-CoBiJ5v4.js → zod-aLSua2NL.js} +24 -23
- package/package.json +4 -3
- package/src/__tests__/setup.ts +16 -0
- package/src/components/chat/chat-display.tsx +2 -2
- package/src/components/data-table/TableBottomBar.tsx +1 -15
- package/src/components/data-table/TableTopBar.tsx +8 -13
- package/src/components/data-table/__tests__/TableBottomBar.test.tsx +6 -12
- package/src/components/data-table/__tests__/column-visibility-dropdown.test.tsx +227 -0
- package/src/components/data-table/column-visibility-dropdown.tsx +204 -0
- package/src/components/data-table/data-table.tsx +1 -1
- package/src/components/data-table/filter-by-values-picker.tsx +39 -17
- package/src/components/data-table/filter-pills.tsx +1 -1
- package/src/components/datasources/__tests__/filter-empty.test.ts +183 -0
- package/src/components/datasources/datasources.tsx +92 -3
- package/src/components/editor/cell/code/cell-editor.tsx +70 -32
- package/src/components/editor/cell/code/code-placeholder.css +18 -0
- package/src/components/editor/cell/code/code-placeholder.tsx +47 -0
- package/src/components/editor/cell/code/language-toggle.tsx +7 -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/editor/connections/storage/__tests__/__snapshots__/as-code.test.ts.snap +9 -2
- package/src/components/editor/connections/storage/__tests__/as-code.test.ts +62 -27
- package/src/components/editor/connections/storage/add-storage-form.tsx +5 -1
- package/src/components/editor/connections/storage/as-code.ts +20 -6
- package/src/components/editor/documentation.css +35 -0
- package/src/components/editor/file-tree/file-explorer.tsx +8 -18
- package/src/components/editor/file-tree/tree-actions.tsx +46 -1
- package/src/components/editor/notebook-cell.tsx +3 -3
- package/src/components/editor/renderers/slides-layout/__tests__/plugin.test.ts +20 -0
- package/src/components/editor/renderers/slides-layout/types.ts +1 -0
- package/src/components/markdown/__tests__/markdown-renderer.test.tsx +43 -0
- package/src/components/markdown/markdown-renderer.tsx +24 -1
- package/src/components/slides/__tests__/minimap-actions.test.tsx +166 -0
- package/src/components/slides/__tests__/reveal-component.test.ts +425 -0
- package/src/components/slides/minimap.tsx +127 -10
- package/src/components/slides/reveal-component.tsx +287 -61
- package/src/components/slides/slide-cell-view.tsx +26 -2
- package/src/components/slides/slide-form.tsx +26 -4
- package/src/components/storage/__tests__/storage-inspector.test.ts +180 -0
- package/src/components/storage/storage-inspector.tsx +535 -81
- package/src/components/ui/combobox.tsx +51 -32
- package/src/components/ui/number-field.tsx +5 -1
- package/src/components/ui/reorderable-list.tsx +13 -0
- package/src/components/ui/select-core/__tests__/use-select-list.test.ts +294 -0
- package/src/components/ui/select-core/__tests__/utils.test.ts +222 -0
- package/src/components/ui/select-core/index.ts +16 -0
- package/src/components/ui/select-core/option-row.tsx +33 -0
- package/src/components/ui/select-core/render-slot.ts +20 -0
- package/src/components/ui/select-core/select-list.tsx +248 -0
- package/src/components/ui/select-core/types.ts +44 -0
- package/src/components/ui/select-core/use-select-list.ts +347 -0
- package/src/components/ui/select-core/utils.ts +121 -0
- package/src/components/ui/toast.tsx +1 -0
- package/src/core/cells/__tests__/document-changes.test.ts +2 -2
- package/src/core/cells/__tests__/focus.test.ts +45 -2
- package/src/core/cells/focus.ts +1 -1
- package/src/core/cells/scrollCellIntoView.ts +4 -0
- package/src/core/cells/utils.ts +1 -1
- package/src/core/codemirror/__tests__/editor-mount-scheduler.test.ts +143 -0
- package/src/core/codemirror/copilot/getCodes.ts +3 -1
- package/src/core/codemirror/editor-mount-scheduler.ts +101 -0
- package/src/core/codemirror/language/languages/python.ts +2 -0
- package/src/core/codemirror/language/languages/sql/utils.ts +3 -1
- package/src/core/codemirror/lsp/__tests__/markdown-renderer.test.ts +41 -0
- package/src/core/codemirror/lsp/markdown-renderer.ts +59 -0
- package/src/core/datasets/data-source-connections.ts +2 -0
- package/src/core/errors/errors.ts +1 -1
- package/src/core/storage/__tests__/state.test.ts +49 -0
- package/src/core/storage/__tests__/useStorageEntries.test.tsx +199 -3
- package/src/core/storage/state.ts +124 -13
- package/src/core/storage/types.ts +6 -0
- package/src/core/wasm/worker/bootstrap.ts +12 -4
- package/src/plugins/core/__test__/registerReactComponent.test.ts +96 -0
- package/src/plugins/core/registerReactComponent.tsx +42 -10
- package/src/plugins/impl/MultiselectPlugin.tsx +19 -142
- package/src/plugins/impl/SearchableSelect.tsx +16 -97
- package/src/plugins/impl/SliderPlugin.tsx +132 -18
- package/src/plugins/impl/__tests__/DropdownPlugin.test.tsx +5 -2
- package/src/plugins/impl/__tests__/MultiSelectPlugin.test.ts +1 -1
- package/src/plugins/impl/__tests__/SliderPlugin.test.tsx +278 -8
- package/src/utils/__tests__/numbers.test.ts +20 -0
- package/src/utils/errors.ts +9 -0
- package/src/utils/lazy.ts +6 -1
- package/src/utils/numbers.ts +27 -0
- package/src/utils/schedule-task.ts +71 -0
- package/dist/assets/__vite-browser-external-Ci2ZQfXU.js +0 -1
- package/dist/assets/worker-ip3AI_sN.js +0 -73
- package/dist/dist-0Fif7jnk.js +0 -5
- package/dist/dist-B5h_9sHB.js +0 -6
- package/dist/dist-B9M6R5ye.js +0 -5
- package/dist/dist-BCt3tnck.js +0 -8
- package/dist/dist-BUIJwMwn.js +0 -8
- package/dist/dist-BpquMd3k.js +0 -5
- package/dist/dist-BzJsqYfz.js +0 -5
- package/dist/dist-CA5ELXAf.js +0 -6
- package/dist/dist-CLBRs6Uv.js +0 -5
- package/dist/dist-CStVCMbq.js +0 -5
- package/dist/dist-CZRIEY3Y.js +0 -8
- package/dist/dist-CuUHbFD0.js +0 -5
- package/dist/dist-DV7Iabxb.js +0 -8
- package/dist/dist-DhHh0jLg.js +0 -1247
- package/dist/dist-DuEeHMvL.js +0 -5
- package/dist/esm-CCuYCd3R.js +0 -1171
- package/src/plugins/impl/multiselectFilterFn.tsx +0 -22
- /package/src/components/{data-table → ui}/value-chips.tsx +0 -0
|
@@ -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}
|
package/src/components/editor/connections/storage/__tests__/__snapshots__/as-code.test.ts.snap
CHANGED
|
@@ -82,10 +82,17 @@ exports[`generateStorageCode > GCS > without service account key (default creden
|
|
|
82
82
|
store = GCSStore("my-bucket")"
|
|
83
83
|
`;
|
|
84
84
|
|
|
85
|
-
exports[`generateStorageCode > Google Drive > with
|
|
85
|
+
exports[`generateStorageCode > Google Drive > with default auth (no credentials) 1`] = `
|
|
86
86
|
"from gdrive_fsspec import GoogleDriveFileSystem
|
|
87
87
|
|
|
88
|
-
fs = GoogleDriveFileSystem(
|
|
88
|
+
fs = GoogleDriveFileSystem(use_listings_cache=False)"
|
|
89
|
+
`;
|
|
90
|
+
|
|
91
|
+
exports[`generateStorageCode > Google Drive > with embedded auth (no credentials) 1`] = `
|
|
92
|
+
"from gdrive_fsspec import GoogleDriveFileSystem
|
|
93
|
+
|
|
94
|
+
fs = GoogleDriveFileSystem(use_listings_cache=False, auth_kwargs={"use_local_webserver": False})
|
|
95
|
+
print("Google Drive connected! Important: Run this cell again to clear the console")"
|
|
89
96
|
`;
|
|
90
97
|
|
|
91
98
|
exports[`generateStorageCode > Google Drive > with service account credentials 1`] = `
|
|
@@ -43,7 +43,9 @@ describe("generateStorageCode", () => {
|
|
|
43
43
|
|
|
44
44
|
describe("S3", () => {
|
|
45
45
|
it("basic connection with all fields", () => {
|
|
46
|
-
expect(
|
|
46
|
+
expect(
|
|
47
|
+
generateStorageCode(baseS3, { library: "obstore" }),
|
|
48
|
+
).toMatchSnapshot();
|
|
47
49
|
});
|
|
48
50
|
|
|
49
51
|
it("minimal connection (bucket only)", () => {
|
|
@@ -51,7 +53,9 @@ describe("generateStorageCode", () => {
|
|
|
51
53
|
type: "s3",
|
|
52
54
|
bucket: "my-bucket",
|
|
53
55
|
};
|
|
54
|
-
expect(
|
|
56
|
+
expect(
|
|
57
|
+
generateStorageCode(conn, { library: "obstore" }),
|
|
58
|
+
).toMatchSnapshot();
|
|
55
59
|
});
|
|
56
60
|
|
|
57
61
|
it("with custom endpoint", () => {
|
|
@@ -59,7 +63,9 @@ describe("generateStorageCode", () => {
|
|
|
59
63
|
...baseS3,
|
|
60
64
|
endpoint_url: "https://minio.example.com:9000",
|
|
61
65
|
};
|
|
62
|
-
expect(
|
|
66
|
+
expect(
|
|
67
|
+
generateStorageCode(conn, { library: "obstore" }),
|
|
68
|
+
).toMatchSnapshot();
|
|
63
69
|
});
|
|
64
70
|
|
|
65
71
|
it("with secrets", () => {
|
|
@@ -70,13 +76,17 @@ describe("generateStorageCode", () => {
|
|
|
70
76
|
access_key_id: prefixSecret("AWS_ACCESS_KEY_ID"),
|
|
71
77
|
secret_access_key: prefixSecret("AWS_SECRET_ACCESS_KEY"),
|
|
72
78
|
};
|
|
73
|
-
expect(
|
|
79
|
+
expect(
|
|
80
|
+
generateStorageCode(conn, { library: "obstore" }),
|
|
81
|
+
).toMatchSnapshot();
|
|
74
82
|
});
|
|
75
83
|
});
|
|
76
84
|
|
|
77
85
|
describe("GCS", () => {
|
|
78
86
|
it("with service account key", () => {
|
|
79
|
-
expect(
|
|
87
|
+
expect(
|
|
88
|
+
generateStorageCode(baseGCS, { library: "obstore" }),
|
|
89
|
+
).toMatchSnapshot();
|
|
80
90
|
});
|
|
81
91
|
|
|
82
92
|
it("without service account key (default credentials)", () => {
|
|
@@ -84,13 +94,17 @@ describe("generateStorageCode", () => {
|
|
|
84
94
|
type: "gcs",
|
|
85
95
|
bucket: "my-bucket",
|
|
86
96
|
};
|
|
87
|
-
expect(
|
|
97
|
+
expect(
|
|
98
|
+
generateStorageCode(conn, { library: "obstore" }),
|
|
99
|
+
).toMatchSnapshot();
|
|
88
100
|
});
|
|
89
101
|
});
|
|
90
102
|
|
|
91
103
|
describe("Azure", () => {
|
|
92
104
|
it("basic connection with account key", () => {
|
|
93
|
-
expect(
|
|
105
|
+
expect(
|
|
106
|
+
generateStorageCode(baseAzure, { library: "obstore" }),
|
|
107
|
+
).toMatchSnapshot();
|
|
94
108
|
});
|
|
95
109
|
|
|
96
110
|
it("without account key", () => {
|
|
@@ -99,7 +113,9 @@ describe("generateStorageCode", () => {
|
|
|
99
113
|
container: "my-container",
|
|
100
114
|
account_name: "storageaccount",
|
|
101
115
|
};
|
|
102
|
-
expect(
|
|
116
|
+
expect(
|
|
117
|
+
generateStorageCode(conn, { library: "obstore" }),
|
|
118
|
+
).toMatchSnapshot();
|
|
103
119
|
});
|
|
104
120
|
|
|
105
121
|
it("with secrets", () => {
|
|
@@ -109,13 +125,17 @@ describe("generateStorageCode", () => {
|
|
|
109
125
|
account_name: prefixSecret("AZURE_ACCOUNT"),
|
|
110
126
|
account_key: prefixSecret("AZURE_KEY"),
|
|
111
127
|
};
|
|
112
|
-
expect(
|
|
128
|
+
expect(
|
|
129
|
+
generateStorageCode(conn, { library: "obstore" }),
|
|
130
|
+
).toMatchSnapshot();
|
|
113
131
|
});
|
|
114
132
|
});
|
|
115
133
|
|
|
116
134
|
describe("CoreWeave", () => {
|
|
117
135
|
it("basic connection with all fields", () => {
|
|
118
|
-
expect(
|
|
136
|
+
expect(
|
|
137
|
+
generateStorageCode(baseCoreWeave, { library: "obstore" }),
|
|
138
|
+
).toMatchSnapshot();
|
|
119
139
|
});
|
|
120
140
|
|
|
121
141
|
it("minimal connection (bucket and region only)", () => {
|
|
@@ -124,7 +144,9 @@ describe("generateStorageCode", () => {
|
|
|
124
144
|
bucket: "operator-bucket",
|
|
125
145
|
region: "US-EAST-04A",
|
|
126
146
|
};
|
|
127
|
-
expect(
|
|
147
|
+
expect(
|
|
148
|
+
generateStorageCode(conn, { library: "obstore" }),
|
|
149
|
+
).toMatchSnapshot();
|
|
128
150
|
});
|
|
129
151
|
|
|
130
152
|
it("with secrets", () => {
|
|
@@ -135,39 +157,52 @@ describe("generateStorageCode", () => {
|
|
|
135
157
|
access_key_id: prefixSecret("COREWEAVE_OBJECT_STORAGE_KEY"),
|
|
136
158
|
secret_access_key: prefixSecret("COREWEAVE_OBJECT_STORAGE_SECRET"),
|
|
137
159
|
};
|
|
138
|
-
expect(
|
|
160
|
+
expect(
|
|
161
|
+
generateStorageCode(conn, { library: "obstore" }),
|
|
162
|
+
).toMatchSnapshot();
|
|
139
163
|
});
|
|
140
164
|
});
|
|
141
165
|
|
|
142
166
|
describe("Google Drive", () => {
|
|
143
167
|
it("with service account credentials", () => {
|
|
144
|
-
expect(
|
|
168
|
+
expect(
|
|
169
|
+
generateStorageCode(baseGDrive, { library: "fsspec" }),
|
|
170
|
+
).toMatchSnapshot();
|
|
145
171
|
});
|
|
146
172
|
|
|
147
|
-
it("with
|
|
173
|
+
it("with default auth (no credentials)", () => {
|
|
148
174
|
const conn: StorageConnection = {
|
|
149
175
|
type: "gdrive",
|
|
150
176
|
};
|
|
151
|
-
expect(
|
|
177
|
+
expect(
|
|
178
|
+
generateStorageCode(conn, { library: "fsspec" }),
|
|
179
|
+
).toMatchSnapshot();
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it("with embedded auth (no credentials)", () => {
|
|
183
|
+
const conn: StorageConnection = {
|
|
184
|
+
type: "gdrive",
|
|
185
|
+
};
|
|
186
|
+
expect(
|
|
187
|
+
generateStorageCode(conn, { library: "fsspec", isEmbedded: true }),
|
|
188
|
+
).toMatchSnapshot();
|
|
152
189
|
});
|
|
153
190
|
});
|
|
154
191
|
|
|
155
192
|
describe("invalid cases", () => {
|
|
156
193
|
it("throws for empty S3 bucket", () => {
|
|
157
194
|
expect(() =>
|
|
158
|
-
generateStorageCode(
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
),
|
|
195
|
+
generateStorageCode({ type: "s3", bucket: "" } as StorageConnection, {
|
|
196
|
+
library: "obstore",
|
|
197
|
+
}),
|
|
162
198
|
).toThrow();
|
|
163
199
|
});
|
|
164
200
|
|
|
165
201
|
it("throws for empty GCS bucket", () => {
|
|
166
202
|
expect(() =>
|
|
167
|
-
generateStorageCode(
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
),
|
|
203
|
+
generateStorageCode({ type: "gcs", bucket: "" } as StorageConnection, {
|
|
204
|
+
library: "obstore",
|
|
205
|
+
}),
|
|
171
206
|
).toThrow();
|
|
172
207
|
});
|
|
173
208
|
|
|
@@ -179,7 +214,7 @@ describe("generateStorageCode", () => {
|
|
|
179
214
|
container: "",
|
|
180
215
|
account_name: "acct",
|
|
181
216
|
} as StorageConnection,
|
|
182
|
-
"obstore",
|
|
217
|
+
{ library: "obstore" },
|
|
183
218
|
),
|
|
184
219
|
).toThrow();
|
|
185
220
|
});
|
|
@@ -192,7 +227,7 @@ describe("generateStorageCode", () => {
|
|
|
192
227
|
container: "my-container",
|
|
193
228
|
account_name: "",
|
|
194
229
|
} as StorageConnection,
|
|
195
|
-
"obstore",
|
|
230
|
+
{ library: "obstore" },
|
|
196
231
|
),
|
|
197
232
|
).toThrow();
|
|
198
233
|
});
|
|
@@ -205,7 +240,7 @@ describe("generateStorageCode", () => {
|
|
|
205
240
|
bucket: "",
|
|
206
241
|
region: "US-EAST-04A",
|
|
207
242
|
} as StorageConnection,
|
|
208
|
-
"obstore",
|
|
243
|
+
{ library: "obstore" },
|
|
209
244
|
),
|
|
210
245
|
).toThrow();
|
|
211
246
|
});
|
|
@@ -218,7 +253,7 @@ describe("generateStorageCode", () => {
|
|
|
218
253
|
bucket: "operator-bucket",
|
|
219
254
|
region: "",
|
|
220
255
|
} as StorageConnection,
|
|
221
|
-
"obstore",
|
|
256
|
+
{ library: "obstore" },
|
|
222
257
|
),
|
|
223
258
|
).toThrow();
|
|
224
259
|
});
|
|
@@ -5,6 +5,7 @@ import type { FieldValues } from "react-hook-form";
|
|
|
5
5
|
import type { z } from "zod";
|
|
6
6
|
import { ProtocolIcon } from "@/components/storage/components";
|
|
7
7
|
import type { KnownStorageProtocol } from "@/core/storage/types";
|
|
8
|
+
import { useIframeCapabilities } from "@/hooks/useIframeCapabilities";
|
|
8
9
|
import { ConnectionForm, SelectorButton, SelectorGrid } from "../components";
|
|
9
10
|
import {
|
|
10
11
|
generateStorageCode,
|
|
@@ -108,6 +109,7 @@ export const AddStorageForm: React.FC<{
|
|
|
108
109
|
onSubmit: () => void;
|
|
109
110
|
header?: React.ReactNode;
|
|
110
111
|
}> = ({ onSubmit, header }) => {
|
|
112
|
+
const { isEmbedded } = useIframeCapabilities();
|
|
111
113
|
const [selectedSchema, setSelectedSchema] = useState<z.ZodType<
|
|
112
114
|
StorageConnection,
|
|
113
115
|
FieldValues
|
|
@@ -134,7 +136,9 @@ export const AddStorageForm: React.FC<{
|
|
|
134
136
|
preferredLibrary={libs?.preferred ?? "obstore"}
|
|
135
137
|
displayNames={StorageLibraryDisplayNames}
|
|
136
138
|
libraryLabel="Preferred storage library"
|
|
137
|
-
generateCode={(values, library) =>
|
|
139
|
+
generateCode={(values, library) =>
|
|
140
|
+
generateStorageCode(values, { library, isEmbedded })
|
|
141
|
+
}
|
|
138
142
|
onSubmit={onSubmit}
|
|
139
143
|
onBack={() => setSelectedSchema(null)}
|
|
140
144
|
/>
|
|
@@ -7,6 +7,11 @@ import { type StorageConnection, StorageConnectionSchema } from "./schemas";
|
|
|
7
7
|
|
|
8
8
|
export type StorageLibrary = "obstore" | "fsspec";
|
|
9
9
|
|
|
10
|
+
export interface StorageCodeOptions {
|
|
11
|
+
library: StorageLibrary;
|
|
12
|
+
isEmbedded?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
10
15
|
export const StorageLibraryDisplayNames: Record<StorageLibrary, string> = {
|
|
11
16
|
obstore: "obstore",
|
|
12
17
|
fsspec: "fsspec",
|
|
@@ -161,8 +166,9 @@ function generateCoreWeaveCode(
|
|
|
161
166
|
|
|
162
167
|
function generateGDriveCode(
|
|
163
168
|
connection: Extract<StorageConnection, { type: "gdrive" }>,
|
|
164
|
-
secrets: SecretContainer,
|
|
169
|
+
options: { secrets: SecretContainer; isEmbedded?: boolean },
|
|
165
170
|
): { imports: Set<string>; code: string } {
|
|
171
|
+
const { secrets, isEmbedded = false } = options;
|
|
166
172
|
const imports = new Set(["from gdrive_fsspec import GoogleDriveFileSystem"]);
|
|
167
173
|
|
|
168
174
|
if (connection.credentials_json) {
|
|
@@ -178,15 +184,20 @@ function generateGDriveCode(
|
|
|
178
184
|
return { imports, code };
|
|
179
185
|
}
|
|
180
186
|
|
|
181
|
-
const code =
|
|
182
|
-
|
|
183
|
-
|
|
187
|
+
const code = isEmbedded
|
|
188
|
+
? dedent(`
|
|
189
|
+
fs = GoogleDriveFileSystem(use_listings_cache=False, auth_kwargs={"use_local_webserver": False})
|
|
190
|
+
print("Google Drive connected! Important: Run this cell again to clear the console")
|
|
191
|
+
`)
|
|
192
|
+
: dedent(`
|
|
193
|
+
fs = GoogleDriveFileSystem(use_listings_cache=False)
|
|
194
|
+
`);
|
|
184
195
|
return { imports, code };
|
|
185
196
|
}
|
|
186
197
|
|
|
187
198
|
export function generateStorageCode(
|
|
188
199
|
connection: StorageConnection,
|
|
189
|
-
|
|
200
|
+
options: StorageCodeOptions,
|
|
190
201
|
): string {
|
|
191
202
|
StorageConnectionSchema.parse(connection);
|
|
192
203
|
|
|
@@ -207,7 +218,10 @@ export function generateStorageCode(
|
|
|
207
218
|
result = generateCoreWeaveCode(connection, secrets);
|
|
208
219
|
break;
|
|
209
220
|
case "gdrive":
|
|
210
|
-
result = generateGDriveCode(connection,
|
|
221
|
+
result = generateGDriveCode(connection, {
|
|
222
|
+
secrets,
|
|
223
|
+
isEmbedded: options.isEmbedded,
|
|
224
|
+
});
|
|
211
225
|
break;
|
|
212
226
|
default:
|
|
213
227
|
assertNever(connection);
|
|
@@ -51,6 +51,22 @@
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
a {
|
|
55
|
+
cursor: pointer;
|
|
56
|
+
text-decoration: inherit;
|
|
57
|
+
|
|
58
|
+
@apply text-link;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
a:hover,
|
|
62
|
+
a:active {
|
|
63
|
+
text-decoration: underline;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
a:visited {
|
|
67
|
+
@apply text-link-visited;
|
|
68
|
+
}
|
|
69
|
+
|
|
54
70
|
code {
|
|
55
71
|
@apply border px-1 rounded font-mono bg-[var(--slate-2)] text-sm mb-4 mt-2;
|
|
56
72
|
}
|
|
@@ -137,3 +153,22 @@
|
|
|
137
153
|
}
|
|
138
154
|
}
|
|
139
155
|
}
|
|
156
|
+
|
|
157
|
+
/* Syntax highlighting for LSP hover code blocks (lezer classHighlighter tok-* classes) */
|
|
158
|
+
.docs-documentation,
|
|
159
|
+
.cm-tooltip .documentation {
|
|
160
|
+
.tok-keyword { color: light-dark(#708, #c678dd); font-weight: 500; }
|
|
161
|
+
.tok-string,
|
|
162
|
+
.tok-string2 { color: light-dark(#a11, #98c379); }
|
|
163
|
+
.tok-number { color: light-dark(#164, #d19a66); }
|
|
164
|
+
.tok-bool,
|
|
165
|
+
.tok-atom { color: light-dark(#219, #d19a66); }
|
|
166
|
+
.tok-comment { color: var(--cm-comment); }
|
|
167
|
+
.tok-className { color: light-dark(#00f, #61afef); }
|
|
168
|
+
.tok-typeName,
|
|
169
|
+
.tok-namespace { color: light-dark(#085, #56b6c2); }
|
|
170
|
+
.tok-operator { color: light-dark(#a2f, #56b6c2); }
|
|
171
|
+
.tok-propertyName { color: light-dark(#05a, #e5c07b); }
|
|
172
|
+
.tok-variableName { color: light-dark(#000, #abb2bf); }
|
|
173
|
+
.tok-punctuation { color: light-dark(#000, #abb2bf); }
|
|
174
|
+
}
|