@malloy-publisher/sdk 0.0.31 → 0.0.33

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.
Files changed (33) hide show
  1. package/dist/{RenderedResult-Bvw1-OOH.cjs → RenderedResult-B9Gth8IY.cjs} +1 -1
  2. package/dist/{RenderedResult-BSo_9A4J.js → RenderedResult-Drg_uJPZ.js} +1 -1
  3. package/dist/components/Home/Home.d.ts +1 -1
  4. package/dist/components/Package/Connections.d.ts +1 -1
  5. package/dist/components/Package/FileTreeView.d.ts +2 -1
  6. package/dist/components/Package/Models.d.ts +1 -1
  7. package/dist/components/Package/Notebooks.d.ts +1 -1
  8. package/dist/components/Package/Package.d.ts +1 -1
  9. package/dist/components/Project/Packages.d.ts +1 -1
  10. package/dist/components/Project/Project.d.ts +1 -1
  11. package/dist/components/click_helper.d.ts +8 -0
  12. package/dist/components/index.d.ts +1 -0
  13. package/dist/index.cjs.js +329 -324
  14. package/dist/index.es.js +1299 -1273
  15. package/dist/{vendor-DldTUzr7.cjs → vendor-BH1c2Hhy.cjs} +164 -182
  16. package/dist/{vendor-CYQMs_sd.js → vendor-DfRellEl.js} +15811 -18411
  17. package/package.json +4 -4
  18. package/src/components/Home/Home.tsx +4 -2
  19. package/src/components/MutableNotebook/MutableCell.tsx +3 -1
  20. package/src/components/MutableNotebook/MutableNotebook.tsx +5 -5
  21. package/src/components/Notebook/NotebookCell.tsx +39 -26
  22. package/src/components/Package/Connections.tsx +1 -1
  23. package/src/components/Package/FileTreeView.tsx +6 -6
  24. package/src/components/Package/Models.tsx +1 -1
  25. package/src/components/Package/Notebooks.tsx +1 -1
  26. package/src/components/Package/Package.tsx +2 -2
  27. package/src/components/Project/Packages.tsx +4 -8
  28. package/src/components/Project/Project.tsx +1 -1
  29. package/src/components/RenderedResult/ResultContainer.tsx +13 -21
  30. package/src/components/click_helper.ts +37 -0
  31. package/src/components/highlighter.ts +1 -1
  32. package/src/components/index.ts +1 -0
  33. package/vite.config.ts +0 -1
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@malloy-publisher/sdk",
3
3
  "description": "Malloy Publisher SDK",
4
- "version": "0.0.31",
4
+ "version": "0.0.33",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs.js",
7
7
  "module": "dist/index.es.js",
@@ -28,7 +28,8 @@
28
28
  },
29
29
  "peerDependencies": {
30
30
  "react": "^19.1.0",
31
- "react-dom": "^19.1.0"
31
+ "react-dom": "^19.1.0",
32
+ "react-router-dom": "^7.6.2"
32
33
  },
33
34
  "dependencies": {
34
35
  "@emotion/react": "^11.14.0",
@@ -45,8 +46,7 @@
45
46
  "@tanstack/react-query": "^5.59.16",
46
47
  "@uiw/react-md-editor": "^4.0.6",
47
48
  "axios": "^1.7.7",
48
- "markdown-to-jsx": "^7.7.6",
49
- "react-router-dom": "^7.6.2"
49
+ "markdown-to-jsx": "^7.7.6"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@openapitools/openapi-generator-cli": "^2.13.5",
@@ -9,7 +9,7 @@ const queryClient = new QueryClient();
9
9
 
10
10
  interface HomeProps {
11
11
  server?: string;
12
- navigate?: (to: string) => void;
12
+ navigate?: (to: string, event?: React.MouseEvent) => void;
13
13
  }
14
14
 
15
15
  export default function Home({ server, navigate }: HomeProps) {
@@ -44,7 +44,9 @@ export default function Home({ server, navigate }: HomeProps) {
44
44
  <Grid key={project.name}>
45
45
  <Typography
46
46
  variant="h1"
47
- onClick={() => navigate(`/${project.name}/`)}
47
+ onClick={(event) =>
48
+ navigate(`/${project.name}/`, event)
49
+ }
48
50
  >
49
51
  {project.name}
50
52
  </Typography>
@@ -311,7 +311,9 @@ export function MutableCell({
311
311
  }
312
312
 
313
313
  function useDebounce<T>(callback: (value: T) => void, delay: number = 2000) {
314
- const timeoutRef = React.useRef<ReturnType<typeof setTimeout>>();
314
+ const timeoutRef = React.useRef<ReturnType<typeof setTimeout> | undefined>(
315
+ undefined,
316
+ );
315
317
 
316
318
  return React.useCallback(
317
319
  (value: T) => {
@@ -16,7 +16,7 @@ import {
16
16
  } from "@mui/material";
17
17
  import Stack from "@mui/material/Stack";
18
18
  import React from "react";
19
- import { useNavigate } from "react-router-dom";
19
+ import { useRouterClickHandler } from "../click_helper";
20
20
  import { Configuration, ModelsApi } from "../../client";
21
21
  import { SourceAndPath } from "../Model/SourcesExplorer";
22
22
  import { NotebookManager } from "../NotebookManager";
@@ -46,7 +46,7 @@ export default function MutableNotebook({
46
46
  expandCodeCells,
47
47
  expandEmbeddings,
48
48
  }: MutableNotebookProps) {
49
- const navigate = useNavigate();
49
+ const navigate = useRouterClickHandler();
50
50
  const { server, projectName, packageName, versionId, accessToken } =
51
51
  usePublisherPackage();
52
52
  if (!projectName || !packageName) {
@@ -107,12 +107,12 @@ export default function MutableNotebook({
107
107
  setDeleteDialogOpen(true);
108
108
  };
109
109
 
110
- const handleDeleteConfirm = () => {
110
+ const handleDeleteConfirm = (event?: React.MouseEvent) => {
111
111
  if (notebookPath && notebookStorage && userContext) {
112
112
  notebookStorage.deleteNotebook(userContext, notebookPath);
113
113
  }
114
114
  setDeleteDialogOpen(false);
115
- navigate(`/${projectName}/${packageName}`);
115
+ navigate(`/${projectName}/${packageName}`, event);
116
116
  };
117
117
 
118
118
  const handleDeleteCancel = () => {
@@ -286,7 +286,7 @@ export default function MutableNotebook({
286
286
  Cancel
287
287
  </Button>
288
288
  <Button
289
- onClick={handleDeleteConfirm}
289
+ onClick={(event) => handleDeleteConfirm(event)}
290
290
  color="error"
291
291
  autoFocus
292
292
  >
@@ -5,20 +5,26 @@ import LinkOutlinedIcon from "@mui/icons-material/LinkOutlined";
5
5
  import {
6
6
  CardActions,
7
7
  Collapse,
8
- Divider,
9
8
  IconButton,
10
9
  Stack,
11
10
  Tooltip,
12
11
  Typography,
13
- Box,
14
12
  } from "@mui/material";
15
13
  import Markdown from "markdown-to-jsx";
16
- import React, { Suspense, lazy, useEffect } from "react";
14
+ import React, { useEffect } from "react";
17
15
  import { NotebookCell as ClientNotebookCell } from "../../client";
18
16
  import { highlight } from "../highlighter";
19
17
  import { SourcesExplorer } from "../Model";
20
- import { StyledCard, StyledCardContent } from "../styles";
21
18
  import ResultContainer from "../RenderedResult/ResultContainer";
19
+ import { StyledCard, StyledCardContent } from "../styles";
20
+
21
+ // Add global style for code display
22
+ const codeStyle = `
23
+ .code-display pre {
24
+ margin: 0;
25
+ padding: 0;
26
+ }
27
+ `;
22
28
 
23
29
  interface NotebookCellProps {
24
30
  cell: ClientNotebookCell;
@@ -39,9 +45,8 @@ export function NotebookCell({
39
45
  expandEmbedding,
40
46
  hideEmbeddingIcon,
41
47
  }: NotebookCellProps) {
42
- const [codeExpanded, setCodeExpanded] = React.useState<boolean>(
43
- expandCodeCell || (cell.type === "code" && !cell.result),
44
- );
48
+ const [codeExpanded, setCodeExpanded] =
49
+ React.useState<boolean>(expandCodeCell);
45
50
  const [embeddingExpanded, setEmbeddingExpanded] =
46
51
  React.useState<boolean>(expandEmbedding);
47
52
  const [highlightedMalloyCode, setHighlightedMalloyCode] =
@@ -73,7 +78,12 @@ export function NotebookCell({
73
78
  (cell.type === "code" && (
74
79
  <StyledCard variant="outlined" sx={{ height: "auto" }}>
75
80
  {(!hideCodeCellIcon || (!hideEmbeddingIcon && cell.result)) && (
76
- <Stack sx={{ flexDirection: "row", justifyContent: "right" }}>
81
+ <Stack
82
+ sx={{
83
+ flexDirection: "row",
84
+ justifyContent: "right",
85
+ }}
86
+ >
77
87
  <CardActions
78
88
  sx={{
79
89
  padding: "0px 10px 0px 10px",
@@ -142,7 +152,6 @@ export function NotebookCell({
142
152
  </Stack>
143
153
  )}
144
154
  <Collapse in={embeddingExpanded} timeout="auto" unmountOnExit>
145
- <Divider />
146
155
  <Stack
147
156
  sx={{
148
157
  p: "10px",
@@ -176,29 +185,35 @@ export function NotebookCell({
176
185
  </Stack>
177
186
  </Collapse>
178
187
  <Collapse in={codeExpanded} timeout="auto" unmountOnExit>
179
- <Divider />
188
+ <style>{codeStyle}</style>
180
189
  <Stack
181
190
  sx={{
182
- p: "10px",
191
+ mx: "15px",
192
+ mb: "10px",
183
193
  borderRadius: 0,
184
194
  flexDirection: "row",
185
195
  justifyContent: "space-between",
186
196
  }}
187
197
  >
188
- <Typography
189
- component="div"
190
- className="content"
191
- sx={{ fontSize: "12px", "& .line": { textWrap: "wrap" } }}
198
+ <div
199
+ className="code-display"
200
+ style={{
201
+ fontSize: "12px",
202
+ width: "800px",
203
+ border: "1px solid rgb(220,220,220)",
204
+ }}
192
205
  dangerouslySetInnerHTML={{
193
206
  __html: highlightedMalloyCode,
194
207
  }}
195
208
  />
196
209
  </Stack>
197
210
  </Collapse>
198
- <Collapse in={sourcesExpanded} timeout="auto" unmountOnExit>
199
- <Stack sx={{ p: "10px" }}>
200
- <Typography>Sources</Typography>
201
- </Stack>
211
+ <Collapse
212
+ in={sourcesExpanded}
213
+ timeout="auto"
214
+ unmountOnExit
215
+ sx={{ p: "5px" }}
216
+ >
202
217
  <SourcesExplorer
203
218
  sourceAndPaths={cell.newSources.map((source) => {
204
219
  const sourceInfo = JSON.parse(source) as Malloy.SourceInfo;
@@ -210,13 +225,11 @@ export function NotebookCell({
210
225
  />
211
226
  </Collapse>
212
227
  {cell.result && !sourcesExpanded && (
213
- <>
214
- <ResultContainer
215
- result={cell.result}
216
- minHeight={200}
217
- maxHeight={800}
218
- />
219
- </>
228
+ <ResultContainer
229
+ result={cell.result}
230
+ minHeight={200}
231
+ maxHeight={800}
232
+ />
220
233
  )}
221
234
  </StyledCard>
222
235
  ))
@@ -19,7 +19,7 @@ interface ConnectionsProps {
19
19
  server?: string;
20
20
  projectName: string;
21
21
  accessToken: string;
22
- navigate: (to: string) => void;
22
+ navigate: (to: string, event?: React.MouseEvent) => void;
23
23
  }
24
24
 
25
25
  // TODO(jjs) - Move this UI to the ConnectionExplorer component
@@ -27,7 +27,7 @@ import { Typography } from "@mui/material";
27
27
  interface FiieTreeViewProps {
28
28
  items: Model[] | Database[];
29
29
  defaultExpandedItems: string[];
30
- navigate?: (to: string) => void;
30
+ navigate?: (to: string, event?: React.MouseEvent) => void;
31
31
  }
32
32
 
33
33
  export function FileTreeView({
@@ -64,7 +64,7 @@ type ExtendedTreeItemProps = {
64
64
  label: string;
65
65
  fileType: FileType;
66
66
  selectable: boolean;
67
- link: () => void | undefined;
67
+ link: ((event?: React.MouseEvent) => void) | undefined;
68
68
  };
69
69
 
70
70
  interface CustomLabelProps {
@@ -135,7 +135,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(
135
135
  <TreeItem2Content
136
136
  {...getContentProps()}
137
137
  {...(item.link && {
138
- onClick: () => item.link(),
138
+ onClick: (event) => item.link(event),
139
139
  })}
140
140
  sx={{
141
141
  // If the item is not selectable, disable pointer events.
@@ -159,7 +159,7 @@ const CustomTreeItem = React.forwardRef(function CustomTreeItem(
159
159
 
160
160
  function getTreeView(
161
161
  metadataEntries: Model[] | Database[],
162
- navigate: (to: string) => void,
162
+ navigate: (to: string, event?: React.MouseEvent) => void,
163
163
  ): TreeViewBaseItem<ExtendedTreeItemProps>[] {
164
164
  const tree = new Map<string, unknown>();
165
165
  metadataEntries.map((entry: Model | Database) => {
@@ -182,7 +182,7 @@ function getTreeView(
182
182
  function getTreeViewRecursive(
183
183
  node: Map<string, unknown>,
184
184
  path: string,
185
- navigate: (to: string) => void,
185
+ navigate: (to: string, event?: React.MouseEvent) => void,
186
186
  ): TreeViewBaseItem<ExtendedTreeItemProps>[] {
187
187
  const treeViewItems: TreeViewBaseItem<ExtendedTreeItemProps>[] = [];
188
188
  node.forEach((value, key) => {
@@ -199,7 +199,7 @@ function getTreeViewRecursive(
199
199
  fileType: fileType,
200
200
  link:
201
201
  fileType === "model" || fileType === "notebook"
202
- ? navigate.bind(null, path + key)
202
+ ? (event) => navigate(path + key, event)
203
203
  : undefined,
204
204
  selectable: fileType === "model" || fileType === "notebook",
205
205
  });
@@ -16,7 +16,7 @@ interface ModelsProps {
16
16
  projectName: string;
17
17
  packageName: string;
18
18
  versionId?: string;
19
- navigate: (to: string) => void;
19
+ navigate: (to: string, event?: React.MouseEvent) => void;
20
20
  accessToken?: string;
21
21
  }
22
22
 
@@ -14,7 +14,7 @@ interface ModelsProps {
14
14
  projectName: string;
15
15
  packageName: string;
16
16
  versionId?: string;
17
- navigate: (to: string) => void;
17
+ navigate: (to: string, event?: React.MouseEvent) => void;
18
18
  accessToken?: string;
19
19
  }
20
20
 
@@ -15,7 +15,7 @@ interface PackageProps {
15
15
  projectName: string;
16
16
  packageName: string;
17
17
  versionId?: string;
18
- navigate?: (to: string) => void;
18
+ navigate?: (to: string, event?: React.MouseEvent) => void;
19
19
  accessToken?: string;
20
20
  }
21
21
 
@@ -105,7 +105,7 @@ export default function Package({
105
105
  <Grid size={{ xs: 12, md: 12 }}>
106
106
  <Notebook
107
107
  notebookPath={README_NOTEBOOK}
108
- expandCodeCells={true}
108
+ expandCodeCells={false}
109
109
  hideEmbeddingIcons={true}
110
110
  />
111
111
  </Grid>
@@ -9,7 +9,7 @@ const queryClient = new QueryClient();
9
9
  interface ProjectProps {
10
10
  server?: string;
11
11
  projectName: string;
12
- navigate?: (to: string) => void;
12
+ navigate: (to: string, event?: React.MouseEvent) => void;
13
13
  accessToken?: string;
14
14
  }
15
15
 
@@ -34,12 +34,6 @@ export default function Project({
34
34
  queryClient,
35
35
  );
36
36
 
37
- if (!navigate) {
38
- navigate = (to: string) => {
39
- window.location.href = to;
40
- };
41
- }
42
-
43
37
  return (
44
38
  <>
45
39
  {!isSuccess && !isError && (
@@ -74,7 +68,9 @@ export default function Project({
74
68
  <StyledCard
75
69
  variant="outlined"
76
70
  sx={{ padding: "10px", cursor: "pointer" }}
77
- onClick={() => navigate(p.name + "/")}
71
+ onClick={(event) =>
72
+ navigate(p.name + "/", event)
73
+ }
78
74
  >
79
75
  <StyledCardContent>
80
76
  <Typography
@@ -5,7 +5,7 @@ import Packages from "./Packages";
5
5
  interface ProjectProps {
6
6
  server?: string;
7
7
  projectName: string;
8
- navigate?: (to: string) => void;
8
+ navigate: (to: string, event?: React.MouseEvent) => void;
9
9
  accessToken?: string;
10
10
  }
11
11
 
@@ -1,13 +1,13 @@
1
- import React, {
1
+ import { ExpandLess, ExpandMore } from "@mui/icons-material";
2
+ import { Box, IconButton } from "@mui/material";
3
+ import {
2
4
  lazy,
3
5
  Suspense,
4
- useState,
5
- useRef,
6
6
  useCallback,
7
7
  useEffect,
8
+ useRef,
9
+ useState,
8
10
  } from "react";
9
- import { Box, IconButton } from "@mui/material";
10
- import { ExpandMore, ExpandLess } from "@mui/icons-material";
11
11
 
12
12
  const RenderedResult = lazy(() => import("../RenderedResult/RenderedResult"));
13
13
 
@@ -65,12 +65,6 @@ export default function ResultContainer({
65
65
  if (contentHeight < availableHeight) {
66
66
  setExplicitHeight(contentHeight + 20);
67
67
  }
68
- console.log("Height comparison:", {
69
- contentHeight,
70
- minHeight,
71
- availableHeight,
72
- exceedsHeight,
73
- });
74
68
  setShouldShowToggle(exceedsHeight);
75
69
  }, [contentHeight, minHeight]);
76
70
 
@@ -80,9 +74,9 @@ export default function ResultContainer({
80
74
 
81
75
  const height = explicitHeight
82
76
  ? {
83
- minHeight: `${explicitHeight}px`,
84
- height: `${explicitHeight}px`,
85
- }
77
+ minHeight: `${explicitHeight}px`,
78
+ height: `${explicitHeight}px`,
79
+ }
86
80
  : {};
87
81
  return (
88
82
  <>
@@ -92,8 +86,8 @@ export default function ResultContainer({
92
86
  position: "relative",
93
87
  minHeight: `${minHeight}px`,
94
88
  maxHeight: `${isExpanded ? maxHeight : minHeight}px`,
95
- border: "1px solid #e0e0e0",
96
- borderRadius: 1,
89
+ border: "0px",
90
+ borderRadius: 0,
97
91
  overflow: "hidden",
98
92
  display: "flex",
99
93
  flexDirection: "column",
@@ -130,12 +124,10 @@ export default function ResultContainer({
130
124
  left: 0,
131
125
  right: 0,
132
126
  height: "32px",
133
- backgroundColor: "rgba(255, 255, 255, 0.9)",
134
- borderTop: "1px solid #e0e0e0",
127
+ backgroundColor: "rgba(255,255,255,0.75)",
135
128
  display: "flex",
136
129
  alignItems: "center",
137
130
  justifyContent: "center",
138
- backdropFilter: "blur(2px)",
139
131
  }}
140
132
  >
141
133
  <IconButton
@@ -154,9 +146,9 @@ export default function ResultContainer({
154
146
  }
155
147
  >
156
148
  {isExpanded ? (
157
- <ExpandLess sx={{ fontSize: 20 }} />
149
+ <ExpandLess sx={{ fontSize: 30 }} />
158
150
  ) : (
159
- <ExpandMore sx={{ fontSize: 20 }} />
151
+ <ExpandMore sx={{ fontSize: 30 }} />
160
152
  )}
161
153
  </IconButton>
162
154
  </Box>
@@ -0,0 +1,37 @@
1
+ import { useNavigate } from "react-router-dom";
2
+ import { MouseEvent } from "react";
3
+
4
+ /**
5
+ * Custom hook that returns a function for handling clicks with proper modifier key support.
6
+ * The returned function handles CMD/Ctrl clicks to open in new tabs, regular clicks for navigation.
7
+ *
8
+ * @returns A function that takes a relative URL and either navigates or opens in new tab
9
+ */
10
+ export function useRouterClickHandler() {
11
+ const navigate = useNavigate();
12
+
13
+ return (to: string, event?: MouseEvent) => {
14
+ // If no event or no modifier keys, use normal navigation
15
+ if (
16
+ !event ||
17
+ (!event.metaKey &&
18
+ !event.ctrlKey &&
19
+ !event.shiftKey &&
20
+ event.button !== 1)
21
+ ) {
22
+ navigate(to);
23
+ return;
24
+ }
25
+
26
+ // For modifier keys or middle mouse, let browser handle it by opening URL
27
+ const href = new URL(to, window.location.href).href;
28
+
29
+ if (event.metaKey || event.ctrlKey || event.button === 1) {
30
+ // CMD/Ctrl click or middle mouse - open in new tab
31
+ window.open(href, "_blank");
32
+ } else if (event.shiftKey) {
33
+ // Shift click - open in new window
34
+ window.open(href, "_blank");
35
+ }
36
+ };
37
+ }
@@ -617,7 +617,7 @@ const malloySQLTMGrammar = {
617
617
  },
618
618
  };
619
619
 
620
- const THEME = "light-plus";
620
+ const THEME = "catppuccin-latte";
621
621
  const HIGHLIGHTER = createHighlighter({
622
622
  themes: [THEME],
623
623
  langs: [
@@ -5,3 +5,4 @@ export * from "./Package";
5
5
  export * from "./Project";
6
6
  export * from "./QueryResult";
7
7
  export * from "./Home";
8
+ export { useRouterClickHandler } from "./click_helper";
package/vite.config.ts CHANGED
@@ -42,7 +42,6 @@ export default ({ mode }) => {
42
42
  "@uiw/react-md-editor",
43
43
  "axios",
44
44
  "markdown-to-jsx",
45
- "react-router-dom",
46
45
  ],
47
46
  },
48
47
  },