vzcode 2.3.0 → 2.4.0

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 (196) hide show
  1. package/package.json +3 -2
  2. package/src/cli.ts +208 -0
  3. package/src/client/AIAssist/AIAssistCodeMirrorKeyMap.ts +42 -0
  4. package/src/client/AIAssist/AIAssistWidget/index.tsx +135 -0
  5. package/src/client/AIAssist/AIAssistWidget/style.scss +47 -0
  6. package/src/client/AIAssist/Spinner.jsx +76 -0
  7. package/src/client/AIAssist/formatFile.ts +27 -0
  8. package/src/client/AIAssist/generateFilesContext.ts +25 -0
  9. package/src/client/AIAssist/index.ts +2 -0
  10. package/src/client/AIAssist/startAIAssist.ts +95 -0
  11. package/src/client/App/index.tsx +152 -0
  12. package/src/client/App/style.scss +82 -0
  13. package/src/client/App/usePending.ts +51 -0
  14. package/src/client/App/useShareDB.ts +161 -0
  15. package/src/client/CodeEditor/Copilot/index.ts +74 -0
  16. package/src/client/CodeEditor/InteractiveWidgets/boolToggler.ts +12 -0
  17. package/src/client/CodeEditor/InteractiveWidgets/colorPicker.ts +68 -0
  18. package/src/client/CodeEditor/InteractiveWidgets/colorsInTextPlugin.ts +174 -0
  19. package/src/client/CodeEditor/InteractiveWidgets/highlightWidgets.ts +79 -0
  20. package/src/client/CodeEditor/InteractiveWidgets/index.ts +44 -0
  21. package/src/client/CodeEditor/InteractiveWidgets/markdownCheckboxToggler.ts +12 -0
  22. package/src/client/CodeEditor/InteractiveWidgets/numberDragger.ts +20 -0
  23. package/src/client/CodeEditor/InteractiveWidgets/rotateWidget.ts +143 -0
  24. package/src/client/CodeEditor/InteractiveWidgets/urlClicker.test.ts +48 -0
  25. package/src/client/CodeEditor/InteractiveWidgets/urlClicker.ts +12 -0
  26. package/src/client/CodeEditor/InteractiveWidgets/vec2Slider.ts +25 -0
  27. package/src/client/CodeEditor/basicSetup.ts +73 -0
  28. package/src/client/CodeEditor/getOrCreateEditor.tsx +615 -0
  29. package/src/client/CodeEditor/index.tsx +202 -0
  30. package/src/client/CodeEditor/json1PresenceBroadcast.ts +41 -0
  31. package/src/client/CodeEditor/json1PresenceDisplay.ts +350 -0
  32. package/src/client/CodeEditor/rainbowBrackets.ts +122 -0
  33. package/src/client/CodeEditor/style.scss +156 -0
  34. package/src/client/CodeEditor/typescriptExtension/worker.ts +32 -0
  35. package/src/client/CodeErrorOverlay/index.tsx +77 -0
  36. package/src/client/CodeErrorOverlay/style.scss +33 -0
  37. package/src/client/Fonts/fonts.ts +8 -0
  38. package/src/client/Icons/AdjustmentSVG.tsx +19 -0
  39. package/src/client/Icons/BugSVG.tsx +20 -0
  40. package/src/client/Icons/CloseSVG.tsx +19 -0
  41. package/src/client/Icons/CssSVG.tsx +16 -0
  42. package/src/client/Icons/DirectoryArrowSVG.tsx +19 -0
  43. package/src/client/Icons/EditSVG.tsx +19 -0
  44. package/src/client/Icons/FileSVG.tsx +19 -0
  45. package/src/client/Icons/FolderSVG.tsx +20 -0
  46. package/src/client/Icons/GearSVG.tsx +16 -0
  47. package/src/client/Icons/HtmlSVG.tsx +16 -0
  48. package/src/client/Icons/JavaScriptSVG.tsx +16 -0
  49. package/src/client/Icons/JsonSVG.tsx +16 -0
  50. package/src/client/Icons/MarkdownSVG.tsx +16 -0
  51. package/src/client/Icons/MicOffSVG.tsx +35 -0
  52. package/src/client/Icons/MicSVG.tsx +25 -0
  53. package/src/client/Icons/NewSVG.tsx +19 -0
  54. package/src/client/Icons/PinSVG.tsx +14 -0
  55. package/src/client/Icons/PlaySVG.tsx +16 -0
  56. package/src/client/Icons/QuestionMarkSVG.tsx +18 -0
  57. package/src/client/Icons/ReactSVG.tsx +16 -0
  58. package/src/client/Icons/SearchSVG.tsx +20 -0
  59. package/src/client/Icons/SparklesSVG.tsx +23 -0
  60. package/src/client/Icons/SplitEditorSVG.tsx +34 -0
  61. package/src/client/Icons/StopSVG.tsx +15 -0
  62. package/src/client/Icons/SvelteSVG.tsx +16 -0
  63. package/src/client/Icons/TrashSVG.tsx +19 -0
  64. package/src/client/Icons/TypeScriptSVG.tsx +16 -0
  65. package/src/client/Icons/index.tsx +26 -0
  66. package/src/client/ImageViewer/index.tsx +91 -0
  67. package/src/client/ImageViewer/style.scss +41 -0
  68. package/src/client/PresenceNotifications/PresenceNotifications.test.ts +134 -0
  69. package/src/client/PresenceNotifications/index.tsx +158 -0
  70. package/src/client/PresenceNotifications/style.scss +17 -0
  71. package/src/client/RunCodeWidget/index.tsx +117 -0
  72. package/src/client/RunCodeWidget/style.scss +24 -0
  73. package/src/client/SplitPaneResizeContext.tsx +159 -0
  74. package/src/client/TabList/Tab.tsx +73 -0
  75. package/src/client/TabList/index.tsx +35 -0
  76. package/src/client/TabList/style.scss +51 -0
  77. package/src/client/VZCodeContext/index.tsx +29 -0
  78. package/src/client/VZCodeContext/types.ts +248 -0
  79. package/src/client/VZCodeContext/useVZCodeState.ts +602 -0
  80. package/src/client/VZKeyboardShortcutsDoc.tsx +148 -0
  81. package/src/client/VZLeft.tsx +28 -0
  82. package/src/client/VZMiddle.tsx +172 -0
  83. package/src/client/VZResizer/index.tsx +128 -0
  84. package/src/client/VZResizer/styles.scss +33 -0
  85. package/src/client/VZRight.tsx +113 -0
  86. package/src/client/VZSettings.tsx +275 -0
  87. package/src/client/VZSidebar/AIChat/ChatInput.tsx +243 -0
  88. package/src/client/VZSidebar/AIChat/DiffView.scss +136 -0
  89. package/src/client/VZSidebar/AIChat/DiffView.tsx +176 -0
  90. package/src/client/VZSidebar/AIChat/Message.tsx +79 -0
  91. package/src/client/VZSidebar/AIChat/MessageList.tsx +190 -0
  92. package/src/client/VZSidebar/AIChat/StreamingMessage.tsx +35 -0
  93. package/src/client/VZSidebar/AIChat/ThinkingScratchpad.tsx +156 -0
  94. package/src/client/VZSidebar/AIChat/TypingIndicator.tsx +19 -0
  95. package/src/client/VZSidebar/AIChat/index.tsx +357 -0
  96. package/src/client/VZSidebar/AIChat/styles.scss +646 -0
  97. package/src/client/VZSidebar/AIChat/useSpeechRecognition.ts +117 -0
  98. package/src/client/VZSidebar/CreateDirModal.tsx +111 -0
  99. package/src/client/VZSidebar/CreateFileModal.tsx +111 -0
  100. package/src/client/VZSidebar/DeleteConfirmationModal.tsx +76 -0
  101. package/src/client/VZSidebar/DirectoryListing.tsx +89 -0
  102. package/src/client/VZSidebar/EmptyState.tsx +11 -0
  103. package/src/client/VZSidebar/FileListing.tsx +91 -0
  104. package/src/client/VZSidebar/FileTypeIcon.tsx +49 -0
  105. package/src/client/VZSidebar/Item.tsx +237 -0
  106. package/src/client/VZSidebar/Listing.tsx +47 -0
  107. package/src/client/VZSidebar/Search.tsx +527 -0
  108. package/src/client/VZSidebar/VisualEditor.tsx +282 -0
  109. package/src/client/VZSidebar/VoiceChatModal.tsx +121 -0
  110. package/src/client/VZSidebar/aiCopyPaste.ts +199 -0
  111. package/src/client/VZSidebar/index.tsx +728 -0
  112. package/src/client/VZSidebar/styles.scss +612 -0
  113. package/src/client/VZSidebar/useDragAndDrop.tsx +408 -0
  114. package/src/client/bootstrap.ts +26 -0
  115. package/src/client/buildWorker.ts +3 -0
  116. package/src/client/featureFlags.ts +8 -0
  117. package/src/client/generateRequestId.ts +6 -0
  118. package/src/client/getFileTree.ts +53 -0
  119. package/src/client/index.ts +19 -0
  120. package/src/client/main.jsx +10 -0
  121. package/src/client/presenceColor.ts +8 -0
  122. package/src/client/shouldTriggerRun.ts +31 -0
  123. package/src/client/sortFileTree.ts +21 -0
  124. package/src/client/tabsSearchParameters.test.ts +79 -0
  125. package/src/client/tabsSearchParameters.ts +137 -0
  126. package/src/client/themes/index.ts +7 -0
  127. package/src/client/themes/themes.ts +77 -0
  128. package/src/client/themes/uiwImports.ts +32 -0
  129. package/src/client/themes/useDynamicTheme.ts +29 -0
  130. package/src/client/themes/vizhubTheme/colors.ts +80 -0
  131. package/src/client/themes/vizhubTheme/index.ts +193 -0
  132. package/src/client/useActions.ts +288 -0
  133. package/src/client/useESLint/index.ts +72 -0
  134. package/src/client/useESLint/worker.ts +113 -0
  135. package/src/client/useEditorCache.ts +35 -0
  136. package/src/client/useFileCRUD.ts +228 -0
  137. package/src/client/useKeyboardShortcuts.ts +451 -0
  138. package/src/client/useOpenDirectories.ts +99 -0
  139. package/src/client/usePresenceAutoFollow.ts +85 -0
  140. package/src/client/usePrettier/index.ts +178 -0
  141. package/src/client/usePrettier/worker.ts +109 -0
  142. package/src/client/useRunCode.tsx +15 -0
  143. package/src/client/useRuntimeError.ts +32 -0
  144. package/src/client/useSubmitOperation.ts +15 -0
  145. package/src/client/useURLSync.ts +137 -0
  146. package/src/client/usernameLocalStorage.ts +43 -0
  147. package/src/client/utils/fileExtension.ts +10 -0
  148. package/src/client/utils/isImageFile.ts +12 -0
  149. package/src/client/vzReducer/aiChatReducer.ts +44 -0
  150. package/src/client/vzReducer/closeTabReducer.test.ts +205 -0
  151. package/src/client/vzReducer/closeTabsReducer.ts +96 -0
  152. package/src/client/vzReducer/createInitialState.ts +38 -0
  153. package/src/client/vzReducer/editorNoLongerWantsFocusReducer.ts +9 -0
  154. package/src/client/vzReducer/findPane.ts +19 -0
  155. package/src/client/vzReducer/index.ts +250 -0
  156. package/src/client/vzReducer/openTabReducer.test.ts +127 -0
  157. package/src/client/vzReducer/openTabReducer.ts +74 -0
  158. package/src/client/vzReducer/searchReducer.test.ts +292 -0
  159. package/src/client/vzReducer/searchReducer.ts +181 -0
  160. package/src/client/vzReducer/setActiveFileIdReducer.ts +28 -0
  161. package/src/client/vzReducer/setActiveFileLeftRightReducer.ts +76 -0
  162. package/src/client/vzReducer/setIsDocOpenReducer.ts +9 -0
  163. package/src/client/vzReducer/setIsSettingsOpenReducer.ts +9 -0
  164. package/src/client/vzReducer/setThemeReducer.ts +9 -0
  165. package/src/client/vzReducer/setUsernameReducer.ts +9 -0
  166. package/src/client/vzReducer/splitCurrentPaneReducer.ts +66 -0
  167. package/src/client/vzReducer/toggleAutoFollowReducer.ts +12 -0
  168. package/src/client/vzReducer/updatePane.ts +40 -0
  169. package/src/client/vzReducer/updatePresenceIndicatorReducer.ts +30 -0
  170. package/src/client/vzReducer/visualEditorReducer.ts +9 -0
  171. package/src/ot.ts +24 -0
  172. package/src/randomId.ts +15 -0
  173. package/src/reactRouterExports.ts +15 -0
  174. package/src/runCode.ts +27 -0
  175. package/src/server/aiChatHandler/aiEditing.ts +151 -0
  176. package/src/server/aiChatHandler/chatOperations.ts +476 -0
  177. package/src/server/aiChatHandler/errorHandling.ts +66 -0
  178. package/src/server/aiChatHandler/index.ts +199 -0
  179. package/src/server/aiChatHandler/llmStreaming.ts +419 -0
  180. package/src/server/aiChatHandler/validation.ts +24 -0
  181. package/src/server/computeInitialDocument.ts +220 -0
  182. package/src/server/config.ts +24 -0
  183. package/src/server/featureFlags.ts +8 -0
  184. package/src/server/generateAIResponse.ts +188 -0
  185. package/src/server/handleAIAssist.ts +53 -0
  186. package/src/server/handleAIChatMessage.ts +2 -0
  187. package/src/server/handleAICopilot.ts +97 -0
  188. package/src/server/index.ts +379 -0
  189. package/src/server/isDirectory.ts +1 -0
  190. package/src/server/livekit.ts +24 -0
  191. package/src/server/prettier.ts +115 -0
  192. package/src/server/setupEnv.ts +8 -0
  193. package/src/submitOperation.ts +25 -0
  194. package/src/types.ts +205 -0
  195. package/src/utils/fileDiff.ts +117 -0
  196. package/src/vite-env.d.ts +10 -0
@@ -0,0 +1,122 @@
1
+ import {
2
+ EditorView,
3
+ Decoration,
4
+ ViewPlugin,
5
+ } from '@codemirror/view';
6
+
7
+ function generateColors() {
8
+ return ['red', 'orange', 'yellow', 'green'];
9
+ }
10
+
11
+ let isRainbowEnabled = true;
12
+
13
+ export const toggleRainbowBrackets = (enabled: boolean) => {
14
+ isRainbowEnabled = enabled;
15
+ };
16
+
17
+ const rainbowBracketsPlugin = ViewPlugin.fromClass(
18
+ class {
19
+ decorations;
20
+
21
+ constructor(view) {
22
+ this.decorations = this.getBracketDecorations(view);
23
+ }
24
+
25
+ update(update) {
26
+ if (
27
+ update.docChanged ||
28
+ update.selectionSet ||
29
+ update.viewportChanged
30
+ ) {
31
+ this.decorations = this.getBracketDecorations(
32
+ update.view,
33
+ );
34
+ }
35
+ }
36
+
37
+ getBracketDecorations(view) {
38
+ const { doc } = view.state;
39
+ const decorations = [];
40
+ const stack = [];
41
+ const colors = generateColors();
42
+
43
+ for (let pos = 0; pos < doc.length; pos += 1) {
44
+ const char = doc.sliceString(pos, pos + 1);
45
+ if (char === '(' || char === '[' || char === '{') {
46
+ stack.push({ type: char, from: pos });
47
+ } else if (
48
+ char === ')' ||
49
+ char === ']' ||
50
+ char === '}'
51
+ ) {
52
+ const open = stack.pop();
53
+ if (
54
+ open &&
55
+ open.type === this.getMatchingBracket(char)
56
+ ) {
57
+ const color =
58
+ colors[stack.length % colors.length];
59
+ const bracketClass = isRainbowEnabled
60
+ ? `rainbow-bracket-${color}`
61
+ : `default-bracket`;
62
+
63
+ decorations.push(
64
+ Decoration.mark({
65
+ class: bracketClass,
66
+ }).range(open.from, open.from + 1),
67
+ Decoration.mark({
68
+ class: bracketClass,
69
+ }).range(pos, pos + 1),
70
+ );
71
+ }
72
+ }
73
+ }
74
+
75
+ decorations.sort(
76
+ (a, b) =>
77
+ a.from - b.from || a.startSide - b.startSide,
78
+ );
79
+
80
+ return Decoration.set(decorations);
81
+ }
82
+
83
+ // eslint-disable-next-line class-methods-use-this
84
+ getMatchingBracket(closingBracket) {
85
+ switch (closingBracket) {
86
+ case ')':
87
+ return '(';
88
+ case ']':
89
+ return '[';
90
+ case '}':
91
+ return '{';
92
+ default:
93
+ return null;
94
+ }
95
+ }
96
+ },
97
+ {
98
+ decorations: (v) => v.decorations,
99
+ },
100
+ );
101
+
102
+ export default function rainbowBrackets() {
103
+ return [
104
+ rainbowBracketsPlugin,
105
+ EditorView.baseTheme({
106
+ '.rainbow-bracket-red': { color: 'white' },
107
+ '.rainbow-bracket-red > span': { color: 'white' },
108
+ '.rainbow-bracket-orange': { color: '#FFFFB2' },
109
+ '.rainbow-bracket-orange > span': {
110
+ color: '#FFFFB2',
111
+ },
112
+ '.rainbow-bracket-yellow': { color: '#FFB2DA' },
113
+ '.rainbow-bracket-yellow > span': {
114
+ color: '#FFB2DA',
115
+ },
116
+ '.rainbow-bracket-green': { color: '#B2FFB2' },
117
+ '.rainbow-bracket-green > span': { color: '#B2FFB2' },
118
+ '.default-bracket': { color: 'currentColor' },
119
+ '.default-bracket > span': { color: 'currentColor' },
120
+ }),
121
+ ];
122
+ }
@@ -0,0 +1,156 @@
1
+ .vz-code-editor {
2
+ flex: 1;
3
+ display: flex;
4
+ font-family: var(--vzcode-font-family);
5
+ overflow-x: auto;
6
+
7
+ .cm-editor {
8
+ flex: 1;
9
+ width: 100%;
10
+ }
11
+
12
+ .cm-scroller {
13
+ font-family: var(--vzcode-font-family);
14
+ font-size: var(--vzcode-font-size);
15
+ }
16
+
17
+ .remote-cursor-username {
18
+ transition: opacity 1s ease-in-out;
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: center;
22
+ border-radius: 4px;
23
+ }
24
+
25
+ .cm-tooltip-lint {
26
+ max-width: 500px;
27
+ }
28
+
29
+ /* Style the completion tooltip container */
30
+ .cm-tooltip.cm-tooltip-autocomplete {
31
+ border: 1px solid #888;
32
+ background-color: #1f2022;
33
+ }
34
+
35
+ /* Style the individual completion items */
36
+ .cm-tooltip-autocomplete .cm-completionLabel {
37
+ color: #bdc7dc;
38
+ }
39
+
40
+ /* Style the selected completion item */
41
+ .cm-tooltip-autocomplete
42
+ .cm-completionLabel
43
+ .cm-completion-active {
44
+ background-color: #0077cc;
45
+ color: white;
46
+ }
47
+
48
+ .cm-line {
49
+ font-family: var(--vzcode-font-family);
50
+ }
51
+
52
+ .tooltip_hover_circle {
53
+ color: white;
54
+ text-align: center;
55
+ position: fixed;
56
+ background-color: black;
57
+ padding: 5px;
58
+ border-radius: 5px;
59
+ white-space: nowrap;
60
+ opacity: 0;
61
+ transition: opacity 0.3s ease;
62
+ z-index: 1000;
63
+ pointer-events: none;
64
+ }
65
+
66
+ .tooltip_hover_circle strong {
67
+ font-size: 14px;
68
+ }
69
+
70
+ .tooltip_hover_circle div {
71
+ font-size: 12px;
72
+ }
73
+
74
+ .cm-panel.cm-search {
75
+ padding: 5px;
76
+ position: relative;
77
+ background-color: var(--vh-color-neutral-01);
78
+ border-radius: 6px;
79
+ color: var(--vh-color-neutral-04);
80
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
81
+ }
82
+
83
+ .cm-panels {
84
+ background-color: #333338;
85
+ color: var(--vh-color-neutral-04);
86
+ border: 2px solid var(--vh-color-neutral-02);
87
+ border-radius: 6px;
88
+ }
89
+
90
+ .cm-textfield {
91
+ background-color: var(--vh-color-neutral-01);
92
+ color: #efe7dc;
93
+ border: 1px solid var(--vh-color-neutral-04);
94
+ padding: 8px;
95
+ border-radius: 6px;
96
+ font-size: 14px;
97
+ }
98
+
99
+ .cm-button {
100
+ background-color: var(--vh-color-neutral-01);
101
+ border: 1px solid #193350;
102
+ color: var(--vh-color-neutral-04);
103
+ border: 1px solid var(--vh-color-neutral-04);
104
+ border-radius: 5px;
105
+ padding: 6px 12px;
106
+ font-weight: bold;
107
+ cursor: pointer;
108
+ transition: all 0.3s ease-in-out;
109
+ }
110
+
111
+ .cm-button:hover {
112
+ background-color: #50c878;
113
+ color: #ffffff;
114
+ transform: scale(1.1);
115
+ }
116
+
117
+ .cm-button:active {
118
+ background-color: #202e46;
119
+ transform: scale(0.95);
120
+ }
121
+
122
+ .cm-searchMatch {
123
+ background-color: rgba(255, 255, 0, 0.5);
124
+ border-radius: 2px;
125
+ }
126
+
127
+ .cm-searchMatch-selected {
128
+ background-color: rgba(255, 140, 0, 0.5);
129
+ border: 2px solid #ff8800;
130
+ border-radius: 2px;
131
+ }
132
+ .cm-panel.cm-search [name='close'] {
133
+ position: absolute;
134
+ top: 0;
135
+ right: 4px;
136
+ background-color: var(--vh-color-neutral-01);
137
+ color: var(--vh-color-neutral-04);
138
+ border: none;
139
+ font: inherit;
140
+ padding: 4px 8px;
141
+ margin: 4px;
142
+ border-radius: 4px;
143
+ cursor: pointer;
144
+ transition: all 0.3s ease-in-out;
145
+ }
146
+
147
+ .cm-panel.cm-search [name='close']:hover {
148
+ background-color: var(--vh-color-caution-01);
149
+ color: #ffffff;
150
+ }
151
+
152
+ .cm-panel.cm-search [name='close']:active {
153
+ background-color: var(--vh-color-caution-02);
154
+ transform: scale(0.95);
155
+ }
156
+ }
@@ -0,0 +1,32 @@
1
+ import {
2
+ createDefaultMapFromCDN,
3
+ createSystem,
4
+ createVirtualTypeScriptEnvironment,
5
+ } from '@typescript/vfs';
6
+ import ts from 'typescript';
7
+ import * as Comlink from 'comlink';
8
+
9
+ // When importing this module, typescript says that it "cannot find the module or its corresponding type declarations"
10
+ // However, when this file is used as a web worker, no error occurs.
11
+ // As a result, this error is suppressed to avoid future confusion.
12
+ // @ts-expect-error
13
+ import { createWorker } from '@valtown/codemirror-ts/worker';
14
+
15
+ Comlink.expose(
16
+ createWorker(async function () {
17
+ const fsMap = await createDefaultMapFromCDN(
18
+ { target: ts.ScriptTarget.ES2022 },
19
+ '3.7.3',
20
+ false,
21
+ ts,
22
+ );
23
+ const system = createSystem(fsMap);
24
+ const compilerOpts = {};
25
+ return createVirtualTypeScriptEnvironment(
26
+ system,
27
+ [],
28
+ ts,
29
+ compilerOpts,
30
+ );
31
+ }),
32
+ );
@@ -0,0 +1,77 @@
1
+ import { useState, useCallback, useEffect } from 'react';
2
+ import { VizContent } from '@vizhub/viz-types';
3
+ import { CloseSVG } from '../Icons';
4
+ import './style.scss';
5
+
6
+ const enableErrorDismiss = true;
7
+
8
+ export const CodeErrorOverlay = ({
9
+ errorMessage,
10
+ content,
11
+ }: {
12
+ errorMessage: string | null;
13
+ content: VizContent;
14
+ }) => {
15
+ // console.log(
16
+ // 'errorMessage in CodeErrorOverlay: ',
17
+ // errorMessage,
18
+ // );
19
+ const [isOverlayVisible, setIsOverlayVisible] =
20
+ useState(true);
21
+
22
+ // If errorMessage changes, set the overlay to be visible
23
+ useEffect(() => {
24
+ if (errorMessage !== null) {
25
+ setIsOverlayVisible(true);
26
+ }
27
+ }, [errorMessage]);
28
+
29
+ // If the content changes, set the overlay to be not visible.
30
+ // Removed because it was interfering in the case of
31
+ // server-side build errors on page load.
32
+ // useEffect(() => {
33
+ // setIsOverlayVisible(false);
34
+ // }, [content]);
35
+
36
+ // Set the visibility state to false when the button is clicked
37
+ const handleCloseClick = useCallback(() => {
38
+ setIsOverlayVisible(false);
39
+ }, []);
40
+
41
+ // If the user presses the escape key, close the overlay.
42
+ useEffect(() => {
43
+ const handleKeyDown = (event: KeyboardEvent) => {
44
+ if (event.key === 'Escape') {
45
+ handleCloseClick();
46
+ }
47
+ };
48
+ document.addEventListener(
49
+ 'keydown',
50
+ handleKeyDown,
51
+ true,
52
+ );
53
+
54
+ // Remove the event listener when the component unmounts
55
+ return () => {
56
+ document.removeEventListener(
57
+ 'keydown',
58
+ handleKeyDown,
59
+ true,
60
+ );
61
+ };
62
+ }, [handleCloseClick]);
63
+
64
+ return isOverlayVisible && errorMessage !== null ? (
65
+ <div className="vz-code-error-overlay">
66
+ <pre>{errorMessage}</pre>
67
+ {enableErrorDismiss ? (
68
+ <i
69
+ className="icon-button icon-button-dark error-dismiss-button"
70
+ onClick={handleCloseClick}
71
+ >
72
+ <CloseSVG />
73
+ </i>
74
+ ) : null}
75
+ </div>
76
+ ) : null;
77
+ };
@@ -0,0 +1,33 @@
1
+ .vz-code-error-overlay {
2
+ color: var(--vh-color-neutral-04);
3
+ background: var(--vh-color-neutral-01);
4
+ opacity: 0.9;
5
+ border-left: 4px solid var(--vh-color-warning-01);
6
+ position: absolute;
7
+ bottom: 0;
8
+ left: 0;
9
+ right: 0;
10
+ margin: 0 12px;
11
+ /* Right padding is so that the wrapped text
12
+ doesn't overlap with the .error-dismiss-button */
13
+ padding: 14px 38px 14px 16px;
14
+ border-top-left-radius: 4px;
15
+ border-top-right-radius: 4px;
16
+
17
+ /* Style the monospace font */
18
+ pre {
19
+ font-family: var(--vzcode-font-family);
20
+ font-size: var(--vzcode-font-size);
21
+ margin: 0;
22
+
23
+ /* Wrap long lines */
24
+ white-space: pre-wrap;
25
+ }
26
+
27
+ /* Customize the dismiss button style */
28
+ .error-dismiss-button {
29
+ position: absolute;
30
+ top: 8px;
31
+ right: 8px;
32
+ }
33
+ }
@@ -0,0 +1,8 @@
1
+ export const fonts = [
2
+ 'Roboto Mono',
3
+ 'Inconsolata',
4
+ 'Source Code Pro',
5
+ 'Ubuntu Mono',
6
+ 'JetBrains Mono',
7
+ 'Fira Code',
8
+ ];
@@ -0,0 +1,19 @@
1
+ //From Hero Icons
2
+ export const AdjustmentSVG = () => (
3
+ <svg
4
+ xmlns="http://www.w3.org/2000/svg"
5
+ fill="none"
6
+ viewBox="0 0 24 24"
7
+ strokeWidth={1.5}
8
+ stroke="currentColor"
9
+ className="size-6"
10
+ width={32}
11
+ height={32}
12
+ >
13
+ <path
14
+ strokeLinecap="round"
15
+ strokeLinejoin="round"
16
+ d="M10.5 6h9.75M10.5 6a1.5 1.5 0 1 1-3 0m3 0a1.5 1.5 0 1 0-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 0 1-3 0m3 0a1.5 1.5 0 0 0-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 0 1-3 0m3 0a1.5 1.5 0 0 0-3 0m-9.75 0h9.75"
17
+ />
18
+ </svg>
19
+ );
@@ -0,0 +1,20 @@
1
+ // From Heroicons
2
+ export const BugSVG = () => {
3
+ return (
4
+ <svg
5
+ width="24"
6
+ height="24"
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ fill="none"
9
+ viewBox="0 0 24 24"
10
+ strokeWidth="1.5"
11
+ stroke="currentColor"
12
+ >
13
+ <path
14
+ strokeLinecap="round"
15
+ strokeLinejoin="round"
16
+ d="M12 12.75c1.148 0 2.278.08 3.383.237 1.037.146 1.866.966 1.866 2.013 0 3.728-2.35 6.75-5.25 6.75S6.75 18.728 6.75 15c0-1.046.83-1.867 1.866-2.013A24.204 24.204 0 0 1 12 12.75Zm0 0c2.883 0 5.647.508 8.207 1.44a23.91 23.91 0 0 1-1.152 6.06M12 12.75c-2.883 0-5.647.508-8.208 1.44.125 2.104.52 4.136 1.153 6.06M12 12.75a2.25 2.25 0 0 0 2.248-2.354M12 12.75a2.25 2.25 0 0 1-2.248-2.354M12 8.25c.995 0 1.971-.08 2.922-.236.403-.066.74-.358.795-.762a3.778 3.778 0 0 0-.399-2.25M12 8.25c-.995 0-1.97-.08-2.922-.236-.402-.066-.74-.358-.795-.762a3.734 3.734 0 0 1 .4-2.253M12 8.25a2.25 2.25 0 0 0-2.248 2.146M12 8.25a2.25 2.25 0 0 1 2.248 2.146M8.683 5a6.032 6.032 0 0 1-1.155-1.002c.07-.63.27-1.222.574-1.747m.581 2.749A3.75 3.75 0 0 1 15.318 5m0 0c.427-.283.815-.62 1.155-.999a4.471 4.471 0 0 0-.575-1.752M4.921 6a24.048 24.048 0 0 0-.392 3.314c1.668.546 3.416.914 5.223 1.082M19.08 6c.205 1.08.337 2.187.392 3.314a23.882 23.882 0 0 1-5.223 1.082"
17
+ />
18
+ </svg>
19
+ );
20
+ };
@@ -0,0 +1,19 @@
1
+ export const CloseSVG = () => {
2
+ return (
3
+ <svg
4
+ xmlns="http://www.w3.org/2000/svg"
5
+ width="24"
6
+ height="24"
7
+ viewBox="0 0 24 24"
8
+ fill="none"
9
+ >
10
+ <path
11
+ d="M6 18L18 6M6 6L18 18"
12
+ stroke="currentColor"
13
+ strokeWidth="1.5"
14
+ strokeLinecap="round"
15
+ strokeLinejoin="round"
16
+ />
17
+ </svg>
18
+ );
19
+ };
@@ -0,0 +1,16 @@
1
+ // https://reactsvgicons.com/
2
+ export const CssSVG = () => {
3
+ return (
4
+ <svg
5
+ width="24"
6
+ height="24"
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ fill="currentColor"
9
+ viewBox="0 0 24 24"
10
+ strokeWidth="1.5"
11
+ stroke="none"
12
+ >
13
+ <path d="M4.192 3.143h15.615l-1.42 16.034-6.404 1.812-6.369-1.813L4.192 3.143zM16.9 6.424l-9.8-.002.158 1.949 7.529.002-.189 2.02H9.66l.179 1.913h4.597l-.272 2.62-2.164.598-2.197-.603-.141-1.569h-1.94l.216 2.867L12 17.484l3.995-1.137.905-9.923z" />
14
+ </svg>
15
+ );
16
+ };
@@ -0,0 +1,19 @@
1
+ export const DirectoryArrowSVG = ({
2
+ height = 16,
3
+ fill = 'currentcolor',
4
+ }) => (
5
+ <svg
6
+ xmlns="http://www.w3.org/2000/svg"
7
+ height={height}
8
+ viewBox={'4 4 16 16'}
9
+ >
10
+ <path
11
+ stroke={fill}
12
+ fill="none"
13
+ d="M8 17l9-5-9-5v10z"
14
+ strokeLinecap="round"
15
+ strokeLinejoin="round"
16
+ strokeWidth="1.5"
17
+ />
18
+ </svg>
19
+ );
@@ -0,0 +1,19 @@
1
+ export const EditSVG = () => {
2
+ return (
3
+ <svg
4
+ xmlns="http://www.w3.org/2000/svg"
5
+ width="24"
6
+ height="24"
7
+ viewBox="0 0 24 24"
8
+ >
9
+ <path
10
+ fill="none"
11
+ stroke="currentColor"
12
+ strokeLinecap="round"
13
+ strokeLinejoin="round"
14
+ strokeWidth="1.5"
15
+ d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10"
16
+ />
17
+ </svg>
18
+ );
19
+ };
@@ -0,0 +1,19 @@
1
+ export const FileSVG = () => {
2
+ return (
3
+ <svg
4
+ xmlns="http://www.w3.org/2000/svg"
5
+ width="24"
6
+ height="24"
7
+ fill="none"
8
+ viewBox="0 0 24 24"
9
+ >
10
+ <path
11
+ stroke="currentColor"
12
+ strokeLinecap="round"
13
+ strokeLinejoin="round"
14
+ strokeWidth="1.5"
15
+ d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z"
16
+ />
17
+ </svg>
18
+ );
19
+ };
@@ -0,0 +1,20 @@
1
+ // From Heroicons
2
+ export const FolderSVG = () => {
3
+ return (
4
+ <svg
5
+ width="24"
6
+ height="24"
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ fill="none"
9
+ viewBox="0 0 24 24"
10
+ strokeWidth="1.5"
11
+ stroke="currentColor"
12
+ >
13
+ <path
14
+ strokeLinecap="round"
15
+ strokeLinejoin="round"
16
+ d="M2.25 12.75V12A2.25 2.25 0 0 1 4.5 9.75h15A2.25 2.25 0 0 1 21.75 12v.75m-8.69-6.44-2.12-2.12a1.5 1.5 0 0 0-1.061-.44H4.5A2.25 2.25 0 0 0 2.25 6v12a2.25 2.25 0 0 0 2.25 2.25h15A2.25 2.25 0 0 0 21.75 18V9a2.25 2.25 0 0 0-2.25-2.25h-5.379a1.5 1.5 0 0 1-1.06-.44Z"
17
+ />
18
+ </svg>
19
+ );
20
+ };
@@ -0,0 +1,16 @@
1
+ export const GearSVG = () => (
2
+ <svg
3
+ xmlns="http://www.w3.org/2000/svg"
4
+ width="24"
5
+ height="24"
6
+ viewBox="0 0 24 24"
7
+ fill="none"
8
+ stroke="currentColor"
9
+ strokeLinecap="round"
10
+ strokeLinejoin="round"
11
+ strokeWidth="1.5"
12
+ >
13
+ <path d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 0 1 0 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 0 1 0-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.281Z" />
14
+ <path d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
15
+ </svg>
16
+ );
@@ -0,0 +1,16 @@
1
+ // https://reactsvgicons.com/
2
+ export const HtmlSVG = () => {
3
+ return (
4
+ <svg
5
+ width="24"
6
+ height="24"
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ fill="currentColor"
9
+ viewBox="0 0 24 24"
10
+ strokeWidth="1.5"
11
+ stroke="none"
12
+ >
13
+ <path d="M4.136 3.012h15.729l-1.431 16.15-6.451 1.826-6.414-1.826-1.433-16.15zm5.266 7.302l-.173-2.035 7.533.002.173-1.963-9.87-.002.522 5.998h6.835l-.243 2.566-2.179.602-2.214-.605-.141-1.58H7.691l.247 3.123L12 17.506l4.028-1.08.558-6.111H9.402v-.001z" />
14
+ </svg>
15
+ );
16
+ };
@@ -0,0 +1,16 @@
1
+ // https://reactsvgicons.com/
2
+ export const JavaScriptSVG = () => {
3
+ return (
4
+ <svg
5
+ width="24"
6
+ height="24"
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ fill="currentColor"
9
+ viewBox="0 0 24 24"
10
+ strokeWidth="1.5"
11
+ stroke="none"
12
+ >
13
+ <path d="M3 3h18v18H3V3zm16.525 13.707c-.131-.821-.666-1.511-2.252-2.155-.552-.259-1.165-.438-1.349-.854-.068-.248-.078-.382-.034-.529.113-.484.687-.629 1.137-.495.293.09.563.315.732.676.775-.507.775-.507 1.316-.844-.203-.314-.304-.451-.439-.586-.473-.528-1.103-.798-2.126-.775l-.528.067c-.507.124-.991.395-1.283.754-.855.968-.608 2.655.427 3.354 1.023.765 2.521.933 2.712 1.653.18.878-.652 1.159-1.475 1.058-.607-.136-.945-.439-1.316-1.002l-1.372.788c.157.359.337.517.607.832 1.305 1.316 4.568 1.249 5.153-.754.021-.067.18-.528.056-1.237l.034.049zm-6.737-5.434h-1.686c0 1.453-.007 2.898-.007 4.354 0 .924.047 1.772-.104 2.033-.247.517-.886.451-1.175.359-.297-.146-.448-.349-.623-.641-.047-.078-.082-.146-.095-.146l-1.368.844c.229.473.563.879.994 1.137.641.383 1.502.507 2.404.305.588-.17 1.095-.519 1.358-1.059.384-.697.302-1.553.299-2.509.008-1.541 0-3.083 0-4.635l.003-.042z" />
14
+ </svg>
15
+ );
16
+ };
@@ -0,0 +1,16 @@
1
+ // https://reactsvgicons.com/
2
+ export const JsonSVG = () => {
3
+ return (
4
+ <svg
5
+ width="24"
6
+ height="24"
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ fill="currentColor"
9
+ viewBox="0 0 24 24"
10
+ strokeWidth="1.5"
11
+ stroke="none"
12
+ >
13
+ <path d="M5 3h2v2H5v5a2 2 0 01-2 2 2 2 0 012 2v5h2v2H5c-1.07-.27-2-.9-2-2v-4a2 2 0 00-2-2H0v-2h1a2 2 0 002-2V5a2 2 0 012-2m14 0a2 2 0 012 2v4a2 2 0 002 2h1v2h-1a2 2 0 00-2 2v4a2 2 0 01-2 2h-2v-2h2v-5a2 2 0 012-2 2 2 0 01-2-2V5h-2V3h2m-7 12a1 1 0 011 1 1 1 0 01-1 1 1 1 0 01-1-1 1 1 0 011-1m-4 0a1 1 0 011 1 1 1 0 01-1 1 1 1 0 01-1-1 1 1 0 011-1m8 0a1 1 0 011 1 1 1 0 01-1 1 1 1 0 01-1-1 1 1 0 011-1z" />
14
+ </svg>
15
+ );
16
+ };
@@ -0,0 +1,16 @@
1
+ // https://reactsvgicons.com/
2
+ export const MarkdownSVG = () => {
3
+ return (
4
+ <svg
5
+ width="24"
6
+ height="24"
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ fill="currentColor"
9
+ viewBox="0 0 24 24"
10
+ strokeWidth="1.5"
11
+ stroke="none"
12
+ >
13
+ <path d="M20.56 18H3.44C2.65 18 2 17.37 2 16.59V7.41C2 6.63 2.65 6 3.44 6h17.12c.79 0 1.44.63 1.44 1.41v9.18c0 .78-.65 1.41-1.44 1.41M6.81 15.19v-3.66l1.92 2.35 1.92-2.35v3.66h1.93V8.81h-1.93l-1.92 2.35-1.92-2.35H4.89v6.38h1.92M19.69 12h-1.92V8.81h-1.92V12h-1.93l2.89 3.28L19.69 12z" />
14
+ </svg>
15
+ );
16
+ };