@workbench-kit/react 0.0.1-prototype.0 → 0.0.2-prototype.0.1.2

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 (155) hide show
  1. package/package.json +33 -9
  2. package/src/index.ts +545 -43
  3. package/src/jdw/JdwPreview.tsx +38 -0
  4. package/src/jdw/JsonCodeEditorPane.tsx +274 -0
  5. package/src/jdw/builtins/renderBuiltinWidgetLeaf.tsx +29 -0
  6. package/src/jdw/builtins/renderBuiltinWidgetNode.tsx +126 -0
  7. package/src/jdw/createBuiltinJdwRegistry.ts +111 -0
  8. package/src/jdw/cssRenderBackend.tsx +134 -0
  9. package/src/jdw/document.ts +38 -0
  10. package/src/jdw/fixtures/jdw-fixtures.ts +52 -0
  11. package/src/jdw/fixtures/jdw-sample-screens.ts +522 -0
  12. package/src/jdw/index.ts +45 -0
  13. package/src/jdw/parse.ts +1 -0
  14. package/src/jdw/renderJdw.tsx +32 -0
  15. package/src/json-config/JsonConfigWorkbench.tsx +316 -0
  16. package/src/json-config/index.ts +6 -0
  17. package/src/json-config/json-config-editor-state.ts +42 -0
  18. package/src/layout/Panel.tsx +146 -1
  19. package/src/layout/SideBarViewFrame.tsx +367 -328
  20. package/src/layout/WorkbenchCanvas.tsx +849 -0
  21. package/src/layout/WorkbenchFullscreen.tsx +368 -0
  22. package/src/layout/WorkbenchLayout.tsx +5 -0
  23. package/src/layout/WorkbenchLayoutBase.tsx +294 -0
  24. package/src/layout/WorkbenchPropertyPanel.tsx +497 -0
  25. package/src/layout/WorkbenchSidebarActions.tsx +274 -0
  26. package/src/layout/WorkbenchTree.tsx +351 -0
  27. package/src/layout/layoutHelpers.ts +25 -0
  28. package/src/modal/ConfirmDialog.tsx +61 -53
  29. package/src/modal/Modal.tsx +295 -35
  30. package/src/overlay/ContextMenu.tsx +146 -145
  31. package/src/primitives/AbsoluteBox.tsx +46 -0
  32. package/src/primitives/Badge.tsx +12 -12
  33. package/src/primitives/Button.tsx +44 -14
  34. package/src/primitives/Checkbox.tsx +11 -5
  35. package/src/primitives/EmptyState.tsx +27 -26
  36. package/src/primitives/Field.tsx +38 -38
  37. package/src/primitives/IconButton.tsx +5 -2
  38. package/src/primitives/List.tsx +111 -0
  39. package/src/primitives/NumberInput.tsx +38 -0
  40. package/src/primitives/ScrollArea.tsx +42 -0
  41. package/src/primitives/Select.tsx +1 -12
  42. package/src/primitives/StatusBar.tsx +46 -0
  43. package/src/primitives/TextArea.tsx +36 -0
  44. package/src/primitives/TextInput.tsx +11 -2
  45. package/src/primitives/WorkbenchChrome.tsx +424 -0
  46. package/src/primitives/WorkbenchEditor.tsx +394 -0
  47. package/src/primitives/index.ts +105 -0
  48. package/src/primitives/select/Select.tsx +266 -0
  49. package/src/primitives/select/index.ts +2 -0
  50. package/src/primitives/select/options.ts +38 -0
  51. package/src/primitives/select/overlay.ts +63 -0
  52. package/src/primitives/select/select.app.css +9 -0
  53. package/src/primitives/select/select.css +140 -0
  54. package/src/primitives/select/types.ts +18 -0
  55. package/src/primitives/styles.css +955 -0
  56. package/src/scrollbars.css +69 -0
  57. package/src/styles.css +7738 -1762
  58. package/src/utils/codicon.ts +17 -0
  59. package/src/widget-asset/WidgetAssetEditor.tsx +140 -0
  60. package/src/widget-asset/WidgetAssetMetadataForm.tsx +82 -0
  61. package/src/widget-asset/WidgetAssetModeControls.tsx +42 -0
  62. package/src/widget-asset/WidgetAssetSourceEditor.tsx +50 -0
  63. package/src/widget-asset/WidgetAssetWorkbench.tsx +112 -0
  64. package/src/widget-asset/index.ts +17 -0
  65. package/src/widget-asset/widget-asset-document.ts +37 -0
  66. package/src/widget-asset/widget-asset-mode.ts +3 -0
  67. package/src/widget-studio/builtin-widget-asset-catalog.ts +12 -0
  68. package/src/widget-studio/create-widget-studio-workspace-editor.tsx +79 -0
  69. package/src/widget-studio/index.ts +7 -0
  70. package/src/widget-studio/resolve-widget-studio-asset-catalog.ts +26 -0
  71. package/src/widget-tree/WidgetAssetPalette.tsx +77 -0
  72. package/src/widget-tree/WidgetInspectorPanel.tsx +266 -0
  73. package/src/widget-tree/WidgetSourceEditor.tsx +56 -0
  74. package/src/widget-tree/WidgetTreeLab.tsx +272 -0
  75. package/src/widget-tree/WidgetTreeModeControls.tsx +44 -0
  76. package/src/widget-tree/WidgetTreeSidePanel.tsx +49 -0
  77. package/src/widget-tree/WidgetTreeView.tsx +97 -0
  78. package/src/widget-tree/WidgetTreeWorkbench.tsx +111 -0
  79. package/src/widget-tree/WidgetTreeWorkspaceShell.tsx +154 -0
  80. package/src/widget-tree/demo-registry.ts +32 -0
  81. package/src/widget-tree/demo-widget-assets.ts +4 -0
  82. package/src/widget-tree/index.ts +27 -0
  83. package/src/widget-tree/widget-tree-document.ts +20 -0
  84. package/src/widget-tree/widget-tree-layout.ts +31 -0
  85. package/src/widget-tree/widget-tree-mode.ts +7 -0
  86. package/src/widget-tree/widget-tree-play-helpers.ts +74 -0
  87. package/src/workbench/ActivityBar.tsx +52 -52
  88. package/src/workbench/ArtifactShell.tsx +397 -0
  89. package/src/workbench/CommandPalette.tsx +819 -0
  90. package/src/workbench/ConfirmationFlow.tsx +245 -0
  91. package/src/workbench/MarkdownPreview.tsx +151 -0
  92. package/src/workbench/ShortcutCommandBridge.tsx +368 -0
  93. package/src/workbench/SplitView.tsx +136 -136
  94. package/src/workbench/StatusBar.tsx +178 -123
  95. package/src/workbench/StructuredArtifactEditor.tsx +205 -0
  96. package/src/workbench/Timeline.tsx +302 -0
  97. package/src/workbench/WorkbenchCanvasShell.tsx +941 -0
  98. package/src/workbench/WorkbenchShell.tsx +74 -70
  99. package/src/workbench/WorkbenchStandaloneShell.tsx +318 -291
  100. package/src/workbench/auth/WorkbenchAuthGate.tsx +61 -0
  101. package/src/workbench/auth/WorkbenchLoginView.tsx +635 -0
  102. package/src/workbench/auth/index.ts +19 -0
  103. package/src/workbench/chat/ChatComposer.tsx +165 -148
  104. package/src/workbench/chat/ChatMessageItem.tsx +10 -1
  105. package/src/workbench/chat/index.ts +9 -0
  106. package/src/workbench/chat/slashCommand.ts +28 -0
  107. package/src/workbench/chat/useChatRuntimeState.ts +76 -0
  108. package/src/workbench/chat/useSlashCommandSuggest.ts +101 -0
  109. package/src/workbench/commands.ts +520 -490
  110. package/src/workbench/index.ts +443 -98
  111. package/src/workbench/keyboard.ts +53 -0
  112. package/src/workbench/schema/index.ts +48 -0
  113. package/src/workbench/schema/workbenchDocument.ts +31 -0
  114. package/src/workbench/schema/workbenchDocumentActions.ts +6 -0
  115. package/src/workbench/schema/workbenchDocumentAdapter.ts +9 -0
  116. package/src/workbench/schema/workbenchDocumentPatch.ts +13 -0
  117. package/src/workbench/schema/workbenchDocumentRenderer.tsx +702 -0
  118. package/src/workbench/settings/NavigationPanel.tsx +47 -0
  119. package/src/workbench/settings/SchemaForm.tsx +420 -0
  120. package/src/workbench/settings/SectionedPanel.tsx +415 -0
  121. package/src/workbench/settings/StructuredDataForm.tsx +539 -0
  122. package/src/workbench/settings/StructuredDataSchemaPanel.tsx +559 -0
  123. package/src/workbench/settings/StructuredDataSchemaPanelEmbed.tsx +21 -0
  124. package/src/workbench/settings/StructuredDataSchemaPanelFrame.tsx +76 -0
  125. package/src/workbench/settings/StructuredDataTableView.tsx +127 -0
  126. package/src/workbench/settings/WorkbenchPanelRegion.tsx +46 -0
  127. package/src/workbench/settings/WorkbenchSettingsModal.tsx +21 -12
  128. package/src/workbench/settings/WorkbenchSettingsNav.tsx +38 -22
  129. package/src/workbench/settings/index.ts +135 -0
  130. package/src/workbench/settings/panel-region.css +21 -0
  131. package/src/workbench/settings/sectionedPanelScrollSpy.ts +143 -0
  132. package/src/workbench/settings/structured-data-schema-panel.css +330 -0
  133. package/src/workbench/settings/structured-data-table-view.css +85 -0
  134. package/src/workbench/settings/structuredDataSchema.ts +886 -0
  135. package/src/workbench/shell.ts +15 -0
  136. package/src/workbench/shellState.ts +203 -203
  137. package/src/workbench/standalone.ts +101 -94
  138. package/src/workbench/status.ts +129 -0
  139. package/src/workbench/theme.ts +44 -0
  140. package/src/workbench/workspace/MultiProviderExplorer.tsx +625 -0
  141. package/src/workbench/workspace/WorkspaceDraftsContext.tsx +111 -0
  142. package/src/workbench/workspace/WorkspaceEditor.tsx +47 -12
  143. package/src/workbench/workspace/WorkspaceEditorPanel.tsx +334 -353
  144. package/src/workbench/workspace/WorkspaceExplorer.tsx +532 -524
  145. package/src/workbench/workspace/WorkspaceFileIcon.tsx +32 -2
  146. package/src/workbench/workspace/WorkspaceSearchPanel.tsx +113 -113
  147. package/src/workbench/workspace/WorkspaceSearchResults.tsx +47 -47
  148. package/src/workbench/workspace/index.ts +156 -98
  149. package/src/workbench/workspace/mimeType.ts +45 -0
  150. package/src/workbench/workspace/path.ts +10 -10
  151. package/src/workbench/workspace/search.ts +6 -6
  152. package/src/workbench/workspace/tree.ts +1 -1
  153. package/src/workbench/workspace/types.ts +10 -10
  154. package/src/workbench/workspace/useVirtualWorkspace.ts +111 -98
  155. package/src/workbench/workspace/workspaceJsonDiagnostics.ts +83 -0
@@ -0,0 +1,111 @@
1
+ import { createContext, useContext, useState, type ReactNode } from 'react';
2
+ import {
3
+ type WorkspaceFileDraftMap,
4
+ resolveWorkspaceFileDraft,
5
+ updateWorkspaceFileDraft,
6
+ saveWorkspaceFileDraft,
7
+ discardWorkspaceDraft,
8
+ } from '@workbench-kit/workspace';
9
+
10
+ export interface WorkspaceDraftsContextValue {
11
+ drafts: WorkspaceFileDraftMap;
12
+ getDraft: (path: string, fileContent: string) => string;
13
+ isDirty: (path: string, fileContent: string) => boolean;
14
+ updateDraft: (path: string, content: string, fileContent: string) => void;
15
+ saveDraft: (path: string, content: string) => void;
16
+ discardDraft: (path: string, fileContent: string) => void;
17
+ }
18
+
19
+ export const WorkspaceDraftsContext = createContext<WorkspaceDraftsContextValue | null>(null);
20
+
21
+ export interface WorkspaceDraftsProviderProps {
22
+ children: ReactNode;
23
+ }
24
+
25
+ export function WorkspaceDraftsProvider({ children }: WorkspaceDraftsProviderProps) {
26
+ const [drafts, setDrafts] = useState<WorkspaceFileDraftMap>({});
27
+
28
+ const updateDraft = (path: string, content: string, fileContent: string) => {
29
+ setDrafts((prev) => updateWorkspaceFileDraft({ content, drafts: prev, fileContent, path }));
30
+ };
31
+
32
+ const saveDraft = (path: string, content: string) => {
33
+ setDrafts((prev) => saveWorkspaceFileDraft({ content, drafts: prev, path }));
34
+ };
35
+
36
+ const discardDraft = (path: string, fileContent: string) => {
37
+ setDrafts((prev) => discardWorkspaceDraft({ drafts: prev, fileContent, path }));
38
+ };
39
+
40
+ const getDraft = (path: string, fileContent: string): string => {
41
+ const draft = drafts[path];
42
+ return resolveWorkspaceFileDraft({ draft, file: { path, content: fileContent } }).content;
43
+ };
44
+
45
+ const isDirty = (path: string, fileContent: string): boolean => {
46
+ const draft = drafts[path];
47
+ return (
48
+ resolveWorkspaceFileDraft({ draft, file: { path, content: fileContent } }).content !==
49
+ fileContent
50
+ );
51
+ };
52
+
53
+ return (
54
+ <WorkspaceDraftsContext.Provider
55
+ value={{
56
+ drafts,
57
+ getDraft,
58
+ isDirty,
59
+ updateDraft,
60
+ saveDraft,
61
+ discardDraft,
62
+ }}
63
+ >
64
+ {children}
65
+ </WorkspaceDraftsContext.Provider>
66
+ );
67
+ }
68
+
69
+ export function useWorkspaceDrafts(): WorkspaceDraftsContextValue {
70
+ const context = useContext(WorkspaceDraftsContext);
71
+ if (context) return context;
72
+
73
+ // Context fallback
74
+ const [localDrafts, setLocalDrafts] = useState<WorkspaceFileDraftMap>({});
75
+
76
+ const updateDraft = (path: string, content: string, fileContent: string) => {
77
+ setLocalDrafts((prev) =>
78
+ updateWorkspaceFileDraft({ content, drafts: prev, fileContent, path }),
79
+ );
80
+ };
81
+
82
+ const saveDraft = (path: string, content: string) => {
83
+ setLocalDrafts((prev) => saveWorkspaceFileDraft({ content, drafts: prev, path }));
84
+ };
85
+
86
+ const discardDraft = (path: string, fileContent: string) => {
87
+ setLocalDrafts((prev) => discardWorkspaceDraft({ drafts: prev, fileContent, path }));
88
+ };
89
+
90
+ const getDraft = (path: string, fileContent: string): string => {
91
+ const draft = localDrafts[path];
92
+ return resolveWorkspaceFileDraft({ draft, file: { path, content: fileContent } }).content;
93
+ };
94
+
95
+ const isDirty = (path: string, fileContent: string): boolean => {
96
+ const draft = localDrafts[path];
97
+ return (
98
+ resolveWorkspaceFileDraft({ draft, file: { path, content: fileContent } }).content !==
99
+ fileContent
100
+ );
101
+ };
102
+
103
+ return {
104
+ drafts: localDrafts,
105
+ getDraft,
106
+ isDirty,
107
+ updateDraft,
108
+ saveDraft,
109
+ discardDraft,
110
+ };
111
+ }
@@ -7,16 +7,21 @@ import { Toolbar } from '../../primitives/Toolbar';
7
7
  import { extensionOfPath } from './path';
8
8
  import { WorkspaceFileIcon } from './WorkspaceFileIcon';
9
9
  import type { WorkspaceFile } from './types';
10
+ import { JDW_DOCUMENT_MIME } from '../../jdw/document';
11
+ import {
12
+ configureWorkspaceEditorJsonDiagnostics,
13
+ monacoModelPathForWorkspaceFile,
14
+ } from './workspaceJsonDiagnostics';
10
15
 
11
16
  loader.config({ monaco });
12
17
 
13
18
  export type WorkspaceEditorTheme = 'dark' | 'light';
14
19
 
15
- const MONACO_DARK_THEME_ID = 'newchobo-workbench-dark';
16
- const MONACO_LIGHT_THEME_ID = 'newchobo-workbench-light';
20
+ export const MONACO_DARK_THEME_ID = 'newchobo-workbench-dark';
21
+ export const MONACO_LIGHT_THEME_ID = 'newchobo-workbench-light';
17
22
  let monacoThemeDefined = false;
18
23
 
19
- function defineMonacoWorkbenchTheme(monacoInstance: typeof monaco) {
24
+ export function defineMonacoWorkbenchTheme(monacoInstance: typeof monaco) {
20
25
  if (monacoThemeDefined) return;
21
26
 
22
27
  monacoInstance.editor.defineTheme(MONACO_DARK_THEME_ID, {
@@ -98,12 +103,33 @@ export function monacoThemeForWorkspaceTheme(theme: WorkspaceEditorTheme) {
98
103
  }
99
104
 
100
105
  export function languageForFile(path: string, mimeType?: string) {
101
- const extension = extensionOfPath(path);
102
- if (mimeType === 'application/json') return 'json';
103
- if (mimeType === 'text/css') return 'css';
104
- if (mimeType === 'text/html') return 'html';
105
- if (mimeType === 'text/markdown') return 'markdown';
106
+ switch (mimeType) {
107
+ case 'application/javascript':
108
+ case 'text/javascript':
109
+ return 'javascript';
110
+ case 'application/json':
111
+ case JDW_DOCUMENT_MIME:
112
+ case 'application/vnd.workbench-kit.widget+json':
113
+ return 'json';
114
+ case 'application/typescript':
115
+ case 'text/typescript':
116
+ return 'typescript';
117
+ case 'application/xml':
118
+ case 'text/xml':
119
+ return 'xml';
120
+ case 'text/css':
121
+ return 'css';
122
+ case 'text/html':
123
+ return 'html';
124
+ case 'text/markdown':
125
+ return 'markdown';
126
+ case 'text/x-sql':
127
+ return 'sql';
128
+ case 'text/yaml':
129
+ return 'yaml';
130
+ }
106
131
 
132
+ const extension = extensionOfPath(path);
107
133
  switch (extension) {
108
134
  case 'css':
109
135
  return 'css';
@@ -119,6 +145,8 @@ export function languageForFile(path: string, mimeType?: string) {
119
145
  case 'md':
120
146
  case 'mdx':
121
147
  return 'markdown';
148
+ case 'sql':
149
+ return 'sql';
122
150
  case 'ts':
123
151
  case 'tsx':
124
152
  return 'typescript';
@@ -136,8 +164,10 @@ export interface WorkspaceEditorProps {
136
164
  compact?: boolean;
137
165
  file: WorkspaceFile;
138
166
  onChange?: (content: string) => void;
167
+ onEditorMount?: OnMount;
139
168
  onSave?: (content: string) => void;
140
169
  readOnly?: boolean;
170
+ showFileBar?: boolean;
141
171
  showHeader?: boolean;
142
172
  theme?: WorkspaceEditorTheme;
143
173
  value?: string;
@@ -147,14 +177,19 @@ export function WorkspaceEditor({
147
177
  compact,
148
178
  file,
149
179
  onChange,
180
+ onEditorMount,
150
181
  onSave,
151
182
  readOnly = !onChange,
183
+ showFileBar = true,
152
184
  showHeader = true,
153
185
  theme = 'dark',
154
186
  value = file.content,
155
187
  }: WorkspaceEditorProps) {
156
188
  const language = languageForFile(file.path, file.mimeType);
157
189
  const handleMount: OnMount = (editor, monacoInstance) => {
190
+ configureWorkspaceEditorJsonDiagnostics(monacoInstance, file);
191
+ onEditorMount?.(editor, monacoInstance);
192
+
158
193
  if (!onSave) return;
159
194
 
160
195
  editor.addCommand(monacoInstance.KeyMod.CtrlCmd | monacoInstance.KeyCode.KeyS, () => {
@@ -170,7 +205,7 @@ export function WorkspaceEditor({
170
205
  <Toolbar>
171
206
  <Badge variant="muted">{language}</Badge>
172
207
  {file.source ? <Badge variant="muted">{file.source}</Badge> : null}
173
- <IconButton icon="codicon-split" label="Split editor" />
208
+ <IconButton icon="codicon-split-horizontal" label="Split editor" />
174
209
  </Toolbar>
175
210
  }
176
211
  >
@@ -179,13 +214,13 @@ export function WorkspaceEditor({
179
214
  {file.path}
180
215
  </span>
181
216
  </PanelHeader>
182
- ) : (
217
+ ) : showFileBar ? (
183
218
  <div className="workspace-editor__file-bar" title={file.path}>
184
219
  <WorkspaceFileIcon mimeType={file.mimeType} path={file.path} />
185
220
  <span className="workspace-editor__file-path">{file.path}</span>
186
221
  <span className="workspace-editor__file-meta">{file.mimeType ?? language}</span>
187
222
  </div>
188
- )}
223
+ ) : null}
189
224
  <PanelBody className="workbench-monaco-panel__body">
190
225
  <div className="workspace-editor__monaco">
191
226
  <Editor
@@ -213,7 +248,7 @@ export function WorkspaceEditor({
213
248
  tabSize: 2,
214
249
  wordWrap: 'on',
215
250
  }}
216
- path={file.path}
251
+ path={monacoModelPathForWorkspaceFile(file.path)}
217
252
  theme={monacoThemeForWorkspaceTheme(theme)}
218
253
  value={value}
219
254
  onChange={(nextValue) => onChange?.(nextValue ?? '')}