@typespec/playground 0.1.0-alpha.4-dev.13 → 0.1.0-alpha.4-dev.15

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 (50) hide show
  1. package/README.md +3 -0
  2. package/dist/index.css +2 -2
  3. package/dist/index.js +33 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/react/index.js +98 -88
  6. package/dist/react/index.js.map +1 -1
  7. package/dist/src/core.d.ts.map +1 -1
  8. package/dist/src/index.d.ts +3 -3
  9. package/dist/src/index.d.ts.map +1 -1
  10. package/dist/src/monaco-worker.d.ts +1 -1
  11. package/dist/src/monaco-worker.d.ts.map +1 -1
  12. package/dist/src/react/diagnostic-list.d.ts.map +1 -1
  13. package/dist/src/react/editor-command-bar.d.ts +2 -2
  14. package/dist/src/react/editor-command-bar.d.ts.map +1 -1
  15. package/dist/src/react/editor.d.ts.map +1 -1
  16. package/dist/src/react/error-tab.d.ts.map +1 -1
  17. package/dist/src/react/footer.d.ts +5 -1
  18. package/dist/src/react/footer.d.ts.map +1 -1
  19. package/dist/src/react/index.d.ts +2 -2
  20. package/dist/src/react/index.d.ts.map +1 -1
  21. package/dist/src/react/output-tabs.d.ts.map +1 -1
  22. package/dist/src/react/output-view.d.ts +2 -0
  23. package/dist/src/react/output-view.d.ts.map +1 -1
  24. package/dist/src/react/playground.d.ts +4 -0
  25. package/dist/src/react/playground.d.ts.map +1 -1
  26. package/dist/src/react/settings/compiler-settings.d.ts +2 -2
  27. package/dist/src/react/settings/compiler-settings.d.ts.map +1 -1
  28. package/dist/src/react/settings/emitter-options-form.d.ts +2 -2
  29. package/dist/src/react/settings/emitter-options-form.d.ts.map +1 -1
  30. package/dist/src/react/settings/linter-form.d.ts +1 -1
  31. package/dist/src/react/settings/linter-form.d.ts.map +1 -1
  32. package/dist/src/react/standalone.d.ts +2 -0
  33. package/dist/src/react/standalone.d.ts.map +1 -1
  34. package/dist/src/react/typespec-editor.d.ts +2 -0
  35. package/dist/src/react/typespec-editor.d.ts.map +1 -1
  36. package/dist/src/services.d.ts.map +1 -1
  37. package/dist/src/tooling/index.d.ts +6 -0
  38. package/dist/src/tooling/index.d.ts.map +1 -0
  39. package/dist/src/tooling/types.d.ts +3 -0
  40. package/dist/src/tooling/types.d.ts.map +1 -0
  41. package/dist/src/vite/types.d.ts +2 -3
  42. package/dist/src/vite/types.d.ts.map +1 -1
  43. package/dist/{state-storage-ad8a9d39.js → state-storage-1ccb8536.js} +14 -33
  44. package/dist/state-storage-1ccb8536.js.map +1 -0
  45. package/dist/tooling/index.js +30 -0
  46. package/dist/tooling/index.js.map +1 -0
  47. package/dist/vite/index.js +2 -2
  48. package/dist/vite/index.js.map +1 -1
  49. package/package.json +5 -1
  50. package/dist/state-storage-ad8a9d39.js.map +0 -1
package/README.md CHANGED
@@ -42,6 +42,7 @@ export default config;
42
42
  In `src/main.tsx`:
43
43
 
44
44
  ```tsx
45
+ import { registerMonacoDefaultWorkersForVite } from "@typespec/playground";
45
46
  import PlaygroundManifest from "@typespec/playground/manifest";
46
47
  import { renderReactPlayground } from "@typespec/playground/react";
47
48
  import { SwaggerUIViewer } from "@typespec/playground/react/viewers";
@@ -49,6 +50,8 @@ import { SwaggerUIViewer } from "@typespec/playground/react/viewers";
49
50
  // Import styles
50
51
  import "@typespec/playground/styles.css";
51
52
 
53
+ registerMonacoDefaultWorkersForVite();
54
+
52
55
  await renderReactPlayground({
53
56
  ...PlaygroundManifest,
54
57
  emitterViewers: {
package/dist/index.css CHANGED
@@ -41,12 +41,12 @@
41
41
  .split-pane-module_sash-content__DLAt4 {
42
42
  width: 100%;
43
43
  height: 100%;
44
- background-color: #e5e5e5;
44
+ background-color: var(--colorNeutralStroke2);
45
45
  }
46
46
 
47
47
  .split-pane-module_sash-content-dragging__NkKQP,
48
48
  .split-pane-module_sash-content__DLAt4:hover {
49
- background-color: #c3c3c3;
49
+ background-color: var(--colorNeutralStroke1Pressed);
50
50
  }
51
51
 
52
52
  .split-pane-module_pane__m1zQB {
package/dist/index.js CHANGED
@@ -1,7 +1,39 @@
1
- export { c as createBrowserHost, b as createUrlStateStorage, r as registerMonacoDefaultWorkers, a as registerMonacoLanguage } from './state-storage-ad8a9d39.js';
1
+ export { c as createBrowserHost, a as createUrlStateStorage, r as registerMonacoLanguage } from './state-storage-1ccb8536.js';
2
2
  import '@typespec/compiler';
3
3
  import 'monaco-editor';
4
4
  import 'vscode-languageserver';
5
5
  import 'vscode-languageserver-textdocument';
6
6
  import 'lzutf8';
7
+
8
+ function registerMonacoDefaultWorkersForVite() {
9
+ self.MonacoEnvironment = {
10
+ getWorker: function (workerId, label) {
11
+ const getWorkerModule = (moduleUrl, label) => {
12
+ return new Worker(self.MonacoEnvironment.getWorkerUrl(moduleUrl), {
13
+ name: label,
14
+ type: "module",
15
+ });
16
+ };
17
+ switch (label) {
18
+ case "json":
19
+ return getWorkerModule("/monaco-editor/esm/vs/language/json/json.worker?worker", label);
20
+ case "css":
21
+ case "scss":
22
+ case "less":
23
+ return getWorkerModule("/monaco-editor/esm/vs/language/css/css.worker?worker", label);
24
+ case "html":
25
+ case "handlebars":
26
+ case "razor":
27
+ return getWorkerModule("/monaco-editor/esm/vs/language/html/html.worker?worker", label);
28
+ case "typescript":
29
+ case "javascript":
30
+ return getWorkerModule("/monaco-editor/esm/vs/language/typescript/ts.worker?worker", label);
31
+ default:
32
+ return getWorkerModule("/monaco-editor/esm/vs/editor/editor.worker?worker", label);
33
+ }
34
+ },
35
+ };
36
+ }
37
+
38
+ export { registerMonacoDefaultWorkersForVite };
7
39
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/monaco-worker.ts"],"sourcesContent":["export function registerMonacoDefaultWorkersForVite() {\n self.MonacoEnvironment = {\n getWorker: function (workerId, label) {\n const getWorkerModule = (moduleUrl: string, label: string) => {\n return new Worker((self.MonacoEnvironment as any).getWorkerUrl(moduleUrl), {\n name: label,\n type: \"module\",\n });\n };\n\n switch (label) {\n case \"json\":\n return getWorkerModule(\"/monaco-editor/esm/vs/language/json/json.worker?worker\", label);\n case \"css\":\n case \"scss\":\n case \"less\":\n return getWorkerModule(\"/monaco-editor/esm/vs/language/css/css.worker?worker\", label);\n case \"html\":\n case \"handlebars\":\n case \"razor\":\n return getWorkerModule(\"/monaco-editor/esm/vs/language/html/html.worker?worker\", label);\n case \"typescript\":\n case \"javascript\":\n return getWorkerModule(\n \"/monaco-editor/esm/vs/language/typescript/ts.worker?worker\",\n label\n );\n default:\n return getWorkerModule(\"/monaco-editor/esm/vs/editor/editor.worker?worker\", label);\n }\n },\n };\n}\n"],"names":[],"mappings":";;;;;;;SAAgB,mCAAmC,GAAA;IACjD,IAAI,CAAC,iBAAiB,GAAG;AACvB,QAAA,SAAS,EAAE,UAAU,QAAQ,EAAE,KAAK,EAAA;AAClC,YAAA,MAAM,eAAe,GAAG,CAAC,SAAiB,EAAE,KAAa,KAAI;gBAC3D,OAAO,IAAI,MAAM,CAAE,IAAI,CAAC,iBAAyB,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE;AACzE,oBAAA,IAAI,EAAE,KAAK;AACX,oBAAA,IAAI,EAAE,QAAQ;AACf,iBAAA,CAAC,CAAC;AACL,aAAC,CAAC;AAEF,YAAA,QAAQ,KAAK;AACX,gBAAA,KAAK,MAAM;AACT,oBAAA,OAAO,eAAe,CAAC,wDAAwD,EAAE,KAAK,CAAC,CAAC;AAC1F,gBAAA,KAAK,KAAK,CAAC;AACX,gBAAA,KAAK,MAAM,CAAC;AACZ,gBAAA,KAAK,MAAM;AACT,oBAAA,OAAO,eAAe,CAAC,sDAAsD,EAAE,KAAK,CAAC,CAAC;AACxF,gBAAA,KAAK,MAAM,CAAC;AACZ,gBAAA,KAAK,YAAY,CAAC;AAClB,gBAAA,KAAK,OAAO;AACV,oBAAA,OAAO,eAAe,CAAC,wDAAwD,EAAE,KAAK,CAAC,CAAC;AAC1F,gBAAA,KAAK,YAAY,CAAC;AAClB,gBAAA,KAAK,YAAY;AACf,oBAAA,OAAO,eAAe,CACpB,4DAA4D,EAC5D,KAAK,CACN,CAAC;AACJ,gBAAA;AACE,oBAAA,OAAO,eAAe,CAAC,mDAAmD,EAAE,KAAK,CAAC,CAAC;AACtF,aAAA;SACF;KACF,CAAC;AACJ;;;;"}
@@ -1,15 +1,15 @@
1
1
  import { jsx, jsxs, Fragment } from '@emotion/react/jsx-runtime';
2
2
  import debounce from 'debounce';
3
3
  import { editor, Uri, MarkerSeverity, KeyMod, KeyCode } from 'monaco-editor';
4
- import { useCallback, useMemo, useState, useEffect, useRef, useId as useId$1 } from 'react';
4
+ import { useCallback, useMemo, useRef, useEffect, useState, useId as useId$1 } from 'react';
5
5
  import { CompletionItemTag } from 'vscode-languageserver';
6
- import { g as getMarkerLocation, c as createBrowserHost, a as registerMonacoLanguage, r as registerMonacoDefaultWorkers, b as createUrlStateStorage } from '../state-storage-ad8a9d39.js';
7
- import { Select, useId, Label, RadioGroup, Radio, Input, Switch, Checkbox, Link, Toolbar, Tooltip, ToolbarButton, Dialog, DialogTrigger, DialogSurface, DialogBody, mergeClasses, useToastController, Toast, ToastTitle, ToastBody, FluentProvider, webLightTheme, Toaster } from '@fluentui/react-components';
6
+ import { g as getMarkerLocation, c as createBrowserHost, r as registerMonacoLanguage, a as createUrlStateStorage } from '../state-storage-1ccb8536.js';
7
+ import { Select, useId, Label, RadioGroup, Radio, Input, Switch, Checkbox, Link, tokens, Toolbar, Tooltip, ToolbarButton, Dialog, DialogTrigger, DialogSurface, DialogBody, mergeClasses, useToastController, Toast, ToastTitle, ToastBody, Toaster, FluentProvider, webLightTheme } from '@fluentui/react-components';
8
8
  import { Save16Regular, Broom16Filled, Settings24Regular, Bug16Regular } from '@fluentui/react-icons';
9
9
  import { css } from '@emotion/react';
10
- import { MANIFEST } from '@typespec/compiler';
11
10
  import { TypeSpecProgramViewer } from '@typespec/html-program-viewer';
12
11
  import { createRoot } from 'react-dom/client';
12
+ import '@typespec/compiler';
13
13
  import 'vscode-languageserver-textdocument';
14
14
  import 'lzutf8';
15
15
 
@@ -36,8 +36,8 @@ const SamplesDropdown = ({ samples, selectedSampleName, onSelectedSampleNameChan
36
36
  };
37
37
 
38
38
  const EmitterOptionsForm = ({ library, options, optionsChanged, }) => {
39
- var _a, _b;
40
- const emitterOptionsSchema = (_b = (_a = library.emitter) === null || _a === void 0 ? void 0 : _a.options) === null || _b === void 0 ? void 0 : _b.properties;
39
+ var _a, _b, _c;
40
+ const emitterOptionsSchema = (_c = (_b = (_a = library.definition) === null || _a === void 0 ? void 0 : _a.emitter) === null || _b === void 0 ? void 0 : _b.options) === null || _c === void 0 ? void 0 : _c.properties;
41
41
  if (emitterOptionsSchema === undefined) {
42
42
  return jsx(Fragment, { children: "\"No options\"" });
43
43
  }
@@ -72,7 +72,7 @@ const JsonSchemaPropertyInput = ({ emitterOptions, name, prop, onChange, }) => {
72
72
  };
73
73
 
74
74
  const LinterForm = ({ libraries, linterRuleSet, onLinterRuleSetChanged, }) => {
75
- const rulesets = libraries.flatMap((lib) => {
75
+ const rulesets = Object.values(libraries).flatMap((lib) => {
76
76
  var _a, _b, _c;
77
77
  return Object.keys((_c = (_b = (_a = lib.definition) === null || _a === void 0 ? void 0 : _a.linter) === null || _b === void 0 ? void 0 : _b.ruleSets) !== null && _c !== void 0 ? _c : {}).map((x) => `${lib.name}/${x}`);
78
78
  });
@@ -101,7 +101,7 @@ const RuleSetCheckbox = ({ ruleSet, checked, onChange }) => {
101
101
  return jsx(Checkbox, { label: ruleSet, checked: checked, onChange: handleChange });
102
102
  };
103
103
 
104
- const CompilerSettings = ({ selectedEmitter, libraries, options, onOptionsChanged, }) => {
104
+ const CompilerSettings = ({ selectedEmitter, host, options, onOptionsChanged, }) => {
105
105
  var _a, _b;
106
106
  const emitterOptionsChanged = useCallback((emitterOptions) => {
107
107
  onOptionsChanged({
@@ -109,7 +109,7 @@ const CompilerSettings = ({ selectedEmitter, libraries, options, onOptionsChange
109
109
  options: emitterOptions,
110
110
  });
111
111
  }, [options]);
112
- const library = useTypeSpecLibrary(selectedEmitter);
112
+ const library = host.libraries[selectedEmitter];
113
113
  const linterRuleSet = (_a = options.linterRuleSet) !== null && _a !== void 0 ? _a : {};
114
114
  const linterRuleSetChanged = useCallback((linterRuleSet) => {
115
115
  onOptionsChanged({
@@ -117,32 +117,16 @@ const CompilerSettings = ({ selectedEmitter, libraries, options, onOptionsChange
117
117
  linterRuleSet,
118
118
  });
119
119
  }, [options]);
120
- return (jsxs("div", { css: { padding: 10 }, children: [jsx("h2", { children: "Settings" }), jsxs(Fragment, { children: ["Emitter: ", selectedEmitter] }), jsx("h3", { children: "Options" }), library && (jsx(EmitterOptionsForm, { library: library, options: (_b = options.options) !== null && _b !== void 0 ? _b : {}, optionsChanged: emitterOptionsChanged })), jsx("h3", { children: "Linter" }), jsx(LinterForm, { libraries: libraries, linterRuleSet: linterRuleSet, onLinterRuleSetChanged: linterRuleSetChanged })] }));
120
+ return (jsxs("div", { css: { padding: 10 }, children: [jsx("h2", { children: "Settings" }), jsxs(Fragment, { children: ["Emitter: ", selectedEmitter] }), jsx("h3", { children: "Options" }), library && (jsx(EmitterOptionsForm, { library: library, options: (_b = options.options) !== null && _b !== void 0 ? _b : {}, optionsChanged: emitterOptionsChanged })), jsx("h3", { children: "Linter" }), jsx(LinterForm, { libraries: host.libraries, linterRuleSet: linterRuleSet, onLinterRuleSetChanged: linterRuleSetChanged })] }));
121
121
  };
122
- function useTypeSpecLibrary(name) {
123
- const [lib, setLib] = useState();
124
- useEffect(() => {
125
- setLib(undefined);
126
- import(/* @vite-ignore */ name)
127
- .then((module) => {
128
- if (module.$lib === undefined) {
129
- // eslint-disable-next-line no-console
130
- console.error(`Couldn't load library ${name} missing $lib export`);
131
- }
132
- setLib(module.$lib);
133
- })
134
- .catch((e) => {
135
- // eslint-disable-next-line no-console
136
- console.error("Failed to load library", name);
137
- });
138
- }, [name]);
139
- return lib;
140
- }
141
122
 
142
- const EditorCommandBar = ({ documentationUrl, saveCode, formatCode, newIssue, libraries, selectedEmitter, onSelectedEmitterChange, compilerOptions: emitterOptions, onCompilerOptionsChange, samples, selectedSampleName, onSelectedSampleNameChange, }) => {
123
+ const EditorCommandBar = ({ documentationUrl, saveCode, formatCode, newIssue, host, selectedEmitter, onSelectedEmitterChange, compilerOptions: emitterOptions, onCompilerOptionsChange, samples, selectedSampleName, onSelectedSampleNameChange, }) => {
143
124
  const documentation = documentationUrl ? (jsx("label", { children: jsx(Link, { href: documentationUrl, target: "_blank", children: "Docs" }) })) : undefined;
144
125
  const bugButton = newIssue ? jsx(FileBugButton, { onClick: newIssue }) : undefined;
145
- return (jsx("div", { css: { borderBottom: "1px solid #f5f5f5" }, children: jsxs(Toolbar, { children: [jsx(Tooltip, { content: "Save", relationship: "description", withArrow: true, children: jsx(ToolbarButton, { "aria-label": "Save", icon: jsx(Save16Regular, {}), onClick: saveCode }) }), jsx(Tooltip, { content: "Format", relationship: "description", withArrow: true, children: jsx(ToolbarButton, { "aria-label": "Format", icon: jsx(Broom16Filled, {}), onClick: formatCode }) }), samples && (jsx(SamplesDropdown, { samples: samples, selectedSampleName: selectedSampleName, onSelectedSampleNameChange: onSelectedSampleNameChange })), jsx(EmitterDropdown, { emitters: libraries.filter((x) => x.isEmitter).map((x) => x.name), onSelectedEmitterChange: onSelectedEmitterChange, selectedEmitter: selectedEmitter }), jsxs(Dialog, { children: [jsx(DialogTrigger, { children: jsx(ToolbarButton, { icon: jsx(Settings24Regular, {}) }) }), jsx(DialogSurface, { children: jsx(DialogBody, { children: jsx(CompilerSettings, { libraries: libraries, selectedEmitter: selectedEmitter, options: emitterOptions, onOptionsChanged: onCompilerOptionsChange }) }) })] }), documentation, jsx("div", { css: { flex: "1" } }), bugButton] }) }));
126
+ const emitters = useMemo(() => Object.values(host.libraries)
127
+ .filter((x) => x.isEmitter)
128
+ .map((x) => x.name), [host.libraries]);
129
+ return (jsx("div", { css: { borderBottom: `1px solid ${tokens.colorNeutralStroke1}` }, children: jsxs(Toolbar, { children: [jsx(Tooltip, { content: "Save", relationship: "description", withArrow: true, children: jsx(ToolbarButton, { "aria-label": "Save", icon: jsx(Save16Regular, {}), onClick: saveCode }) }), jsx(Tooltip, { content: "Format", relationship: "description", withArrow: true, children: jsx(ToolbarButton, { "aria-label": "Format", icon: jsx(Broom16Filled, {}), onClick: formatCode }) }), samples && (jsx(SamplesDropdown, { samples: samples, selectedSampleName: selectedSampleName, onSelectedSampleNameChange: onSelectedSampleNameChange })), jsx(EmitterDropdown, { emitters: emitters, onSelectedEmitterChange: onSelectedEmitterChange, selectedEmitter: selectedEmitter }), jsxs(Dialog, { children: [jsx(DialogTrigger, { children: jsx(ToolbarButton, { icon: jsx(Settings24Regular, {}) }) }), jsx(DialogSurface, { children: jsx(DialogBody, { children: jsx(CompilerSettings, { host: host, selectedEmitter: selectedEmitter, options: emitterOptions, onOptionsChanged: onCompilerOptionsChange }) }) })] }), documentation, jsx("div", { css: { flex: "1" } }), bugButton] }) }));
146
130
  };
147
131
  const FileBugButton = ({ onClick }) => {
148
132
  return (jsx(Tooltip, { content: "File Bug Report", relationship: "description", withArrow: true, children: jsx(ToolbarButton, { appearance: "subtle", "aria-label": "File Bug Report", icon: jsx(Bug16Regular, {}), onClick: onClick, children: "File bug" }) }));
@@ -159,6 +143,10 @@ const Editor = ({ model, options, actions, onMount }) => {
159
143
  });
160
144
  onMount === null || onMount === void 0 ? void 0 : onMount({ editor: editorRef.current });
161
145
  }, []);
146
+ useEffect(() => {
147
+ var _a;
148
+ editor.setTheme((_a = options.theme) !== null && _a !== void 0 ? _a : "typespec");
149
+ }, [options.theme]);
162
150
  useEffect(() => {
163
151
  const disposables = [];
164
152
  for (const command of actions !== null && actions !== void 0 ? actions : []) {
@@ -183,7 +171,8 @@ function useMonacoModel(uri, language) {
183
171
  }, [uri, language]);
184
172
  }
185
173
 
186
- const Footer = () => {
174
+ const Footer = ({ host }) => {
175
+ const { MANIFEST } = host.compiler;
187
176
  const prItem = MANIFEST.pr ? (jsxs(FooterItem, { link: `https://github.com/microsoft/typespec/pull/${MANIFEST.pr}`, children: [jsx("span", { children: "PR " }), jsx("span", { children: MANIFEST.pr })] })) : (jsx(Fragment, {}));
188
177
  return (jsxs("div", { css: [
189
178
  {
@@ -267,17 +256,17 @@ const DiagnosticList = ({ diagnostics }) => {
267
256
  }) }));
268
257
  };
269
258
  const DiagnosticItem = ({ diagnostic }) => {
270
- return (jsxs("div", { css: { display: "flex" }, children: [jsx("div", { css: [{ padding: "0 5px" }, diagnostic.severity === "error" ? errorColor : warningColor], children: diagnostic.severity }), jsx("div", { css: { padding: "0 5px", color: "#333333" }, children: diagnostic.code }), jsx("div", { css: { padding: "0 5px" }, children: diagnostic.message })] }));
259
+ return (jsxs("div", { css: { display: "flex" }, children: [jsx("div", { css: [{ padding: "0 5px" }, diagnostic.severity === "error" ? errorColor : warningColor], children: diagnostic.severity }), jsx("div", { css: { padding: "0 5px", color: tokens.colorNeutralForeground2 }, children: diagnostic.code }), jsx("div", { css: { padding: "0 5px" }, children: diagnostic.message })] }));
271
260
  };
272
- const errorColor = css({ color: "#cc2222" });
273
- const warningColor = css({ color: "orange" });
261
+ const errorColor = css({ color: tokens.colorStatusDangerForeground1 });
262
+ const warningColor = css({ color: tokens.colorStatusWarningForeground1 });
274
263
 
275
264
  const ErrorTab = ({ internalCompilerError, diagnostics, }) => {
276
265
  return (jsxs(Fragment, { children: [internalCompilerError && jsx(InternalCompilerError, { error: internalCompilerError }), diagnostics && jsx(DiagnosticList, { diagnostics: diagnostics })] }));
277
266
  };
278
267
  const InternalCompilerError = ({ error }) => {
279
268
  return (jsx("div", { css: { CenterStyles }, children: jsxs("div", { css: {
280
- border: "1px solid #cc2222",
269
+ border: `1px solid ${tokens.colorStatusDangerBorder1}`,
281
270
  padding: "10px",
282
271
  margin: "20px",
283
272
  }, children: [jsx("h3", { children: "Internal Compiler error" }), jsx("div", { children: "File issue at https://github.com/microsoft/typespec" }), jsx("hr", {}), jsx("div", { children: error.stack })] }) }));
@@ -318,25 +307,24 @@ const DropdownStyle = css({
318
307
 
319
308
  const OutputTabs = ({ tabs, selected, onSelect }) => {
320
309
  const [leftTabs, rightTabs] = chunk(tabs, (x) => x.align === "left");
321
- return (jsxs("div", { css: { display: "flex", borderBottom: "1px solid #c5c5c5" }, children: [leftTabs.map((tab) => {
310
+ return (jsxs("div", { css: { display: "flex", borderBottom: `1px solid ${tokens.colorNeutralStroke1}` }, children: [leftTabs.map((tab) => {
322
311
  return (jsx(OutputTab, { tab: tab, selected: selected === tab.id, onSelect: onSelect }, tab.id));
323
- }), jsx("span", { css: { flex: 1, borderRight: "1px solid #ccc" } }), rightTabs.map((tab) => {
312
+ }), jsx("span", { css: { flex: 1, borderRight: `1px solid ${tokens.colorNeutralStroke1}` } }), rightTabs.map((tab) => {
324
313
  return (jsx(OutputTab, { tab: tab, selected: selected === tab.id, onSelect: onSelect }, tab.id));
325
314
  })] }));
326
315
  };
327
316
  const OutputTab = ({ tab, selected, onSelect }) => {
328
- return (jsx("a", { css: [
317
+ return (jsx("div", { tabIndex: 0, css: [
329
318
  {
330
319
  height: "26px",
331
320
  padding: "0 5px",
332
- borderRight: "1px solid #ccc",
321
+ borderRight: `1px solid ${tokens.colorNeutralStroke1}`,
333
322
  borderTop: "none",
334
323
  borderBottom: "none",
335
- color: "#000",
336
324
  textDecoration: "none",
337
325
  cursor: "pointer",
338
326
  },
339
- selected ? { fontWeight: "bold", backgroundColor: "#eee" } : {},
327
+ selected ? { fontWeight: "bold", backgroundColor: tokens.colorNeutralBackground5 } : {},
340
328
  ], onClick: () => onSelect(tab.id), children: tab.name }));
341
329
  };
342
330
  function chunk(items, condition) {
@@ -365,11 +353,12 @@ const TypeSpecEditor = ({ actions, options, ...other }) => {
365
353
  };
366
354
  return jsx(Editor, { actions: actions, options: resolvedOptions, ...other });
367
355
  };
368
- const OutputEditor = ({ filename, value, }) => {
356
+ const OutputEditor = ({ filename, value, editorOptions }) => {
369
357
  if (filename === "") {
370
358
  return null;
371
359
  }
372
360
  const options = {
361
+ ...editorOptions,
373
362
  readOnly: true,
374
363
  automaticLayout: true,
375
364
  minimap: {
@@ -381,16 +370,16 @@ const OutputEditor = ({ filename, value, }) => {
381
370
  return jsx(Editor, { model: model, options: options });
382
371
  };
383
372
 
384
- const OutputView = ({ compilationState, viewers }) => {
373
+ const OutputView = ({ compilationState, viewers, editorOptions, }) => {
385
374
  if (compilationState === undefined) {
386
375
  return jsx(Fragment, {});
387
376
  }
388
377
  if ("internalCompilerError" in compilationState) {
389
378
  return jsx(InternalCompilerError, { error: compilationState.internalCompilerError });
390
379
  }
391
- return jsx(OutputViewInternal, { compilationResult: compilationState, viewers: viewers });
380
+ return (jsx(OutputViewInternal, { compilationResult: compilationState, viewers: viewers, editorOptions: editorOptions }));
392
381
  };
393
- const OutputViewInternal = ({ compilationResult, viewers }) => {
382
+ const OutputViewInternal = ({ compilationResult, viewers, editorOptions }) => {
394
383
  const { program, outputFiles } = compilationResult;
395
384
  const [viewSelection, setViewSelection] = useState({
396
385
  type: "file",
@@ -439,15 +428,17 @@ const OutputViewInternal = ({ compilationResult, viewers }) => {
439
428
  void loadOutputFile(tabId);
440
429
  }
441
430
  }, []);
442
- return (jsxs(Fragment, { children: [jsx(OutputTabs, { tabs: tabs, selected: viewSelection.type === "file" ? viewSelection.filename : viewSelection.type, onSelect: handleTabSelection }), jsx("div", { className: "output-content", css: { width: "100%", height: "100%", overflow: "hidden" }, children: jsx(OutputContent, { viewSelection: viewSelection, program: program, viewers: viewers }) })] }));
431
+ return (jsxs(Fragment, { children: [jsx(OutputTabs, { tabs: tabs, selected: viewSelection.type === "file" ? viewSelection.filename : viewSelection.type, onSelect: handleTabSelection }), jsx("div", { className: "output-content", css: { width: "100%", height: "100%", overflow: "hidden" }, children: jsx(OutputContent, { viewSelection: viewSelection, editorOptions: editorOptions, program: program, viewers: viewers }) })] }));
443
432
  };
444
- const rawFileViewer = {
445
- key: "raw",
446
- label: "File",
447
- render: ({ filename, content }) => (jsx(OutputEditor, { filename: filename, value: content })),
448
- };
449
- const OutputContent = ({ viewSelection, program, viewers, }) => {
450
- const resolvedViewers = useMemo(() => [rawFileViewer, ...(viewers !== null && viewers !== void 0 ? viewers : [])], [viewers]);
433
+ function getRawFileViewer(editorOptions) {
434
+ return {
435
+ key: "raw",
436
+ label: "File",
437
+ render: ({ filename, content }) => (jsx(OutputEditor, { editorOptions: editorOptions, filename: filename, value: content })),
438
+ };
439
+ }
440
+ const OutputContent = ({ viewSelection, program, viewers, editorOptions, }) => {
441
+ const resolvedViewers = useMemo(() => [getRawFileViewer(editorOptions), ...(viewers !== null && viewers !== void 0 ? viewers : [])], [viewers]);
451
442
  switch (viewSelection.type) {
452
443
  case "file":
453
444
  return (jsx(FileOutput, { filename: viewSelection.filename, content: viewSelection.content, viewers: resolvedViewers }));
@@ -465,8 +456,8 @@ const ErrorTabLabel = ({ diagnostics }) => {
465
456
  return (jsxs("div", { children: ["Errors ", errorCount > 0 ? jsx("span", { css: ErrorTabCountStyles, children: errorCount }) : ""] }));
466
457
  };
467
458
  const ErrorTabCountStyles = css({
468
- backgroundColor: "#cc2222",
469
- color: "#f5f5f5",
459
+ backgroundColor: tokens.colorStatusDangerBackground3,
460
+ color: tokens.colorNeutralForegroundOnBrand,
470
461
  padding: "0 5px",
471
462
  borderRadius: "20px",
472
463
  });
@@ -732,7 +723,6 @@ const Playground = (props) => {
732
723
  const onTypeSpecEditorMount = useCallback(({ editor }) => {
733
724
  editorRef.current = editor;
734
725
  }, []);
735
- const libraries = useMemo(() => Object.values(host.libraries), [host.libraries]);
736
726
  return (jsxs("div", { css: {
737
727
  display: "grid",
738
728
  gridTemplateColumns: "1",
@@ -742,7 +732,7 @@ const Playground = (props) => {
742
732
  height: "100%",
743
733
  overflow: "hidden",
744
734
  fontFamily: `"Segoe UI", Tahoma, Geneva, Verdana, sans-serif`,
745
- }, children: [jsxs(SplitPane, { initialSizes: ["50%", "50%"], css: { gridArea: "typespeceditor", width: "100%", height: "100%", overflow: "hidden" }, children: [jsxs(Pane, { children: [jsx(EditorCommandBar, { libraries: libraries, selectedEmitter: selectedEmitter, onSelectedEmitterChange: onSelectedEmitterChange, compilerOptions: compilerOptions, onCompilerOptionsChange: onCompilerOptionsChange, samples: props.samples, selectedSampleName: selectedSampleName, onSelectedSampleNameChange: onSelectedSampleNameChange, saveCode: saveCode, formatCode: formatCode, newIssue: ((_b = props === null || props === void 0 ? void 0 : props.links) === null || _b === void 0 ? void 0 : _b.githubIssueUrl) ? newIssue : undefined, documentationUrl: (_c = props.links) === null || _c === void 0 ? void 0 : _c.documentationUrl }), jsx(TypeSpecEditor, { model: typespecModel, actions: typespecEditorActions, onMount: onTypeSpecEditorMount })] }), jsx(Pane, { children: jsx(OutputView, { compilationState: compilationState, viewers: (_d = props.emitterViewers) === null || _d === void 0 ? void 0 : _d[selectedEmitter] }) })] }), jsx(Footer, {})] }));
735
+ }, children: [jsxs(SplitPane, { initialSizes: ["50%", "50%"], css: { gridArea: "typespeceditor", width: "100%", height: "100%", overflow: "hidden" }, children: [jsxs(Pane, { children: [jsx(EditorCommandBar, { host: host, selectedEmitter: selectedEmitter, onSelectedEmitterChange: onSelectedEmitterChange, compilerOptions: compilerOptions, onCompilerOptionsChange: onCompilerOptionsChange, samples: props.samples, selectedSampleName: selectedSampleName, onSelectedSampleNameChange: onSelectedSampleNameChange, saveCode: saveCode, formatCode: formatCode, newIssue: ((_b = props === null || props === void 0 ? void 0 : props.links) === null || _b === void 0 ? void 0 : _b.githubIssueUrl) ? newIssue : undefined, documentationUrl: (_c = props.links) === null || _c === void 0 ? void 0 : _c.documentationUrl }), jsx(TypeSpecEditor, { model: typespecModel, actions: typespecEditorActions, options: props.editorOptions, onMount: onTypeSpecEditorMount })] }), jsx(Pane, { children: jsx(OutputView, { compilationState: compilationState, editorOptions: props.editorOptions, viewers: (_d = props.emitterViewers) === null || _d === void 0 ? void 0 : _d[selectedEmitter] }) })] }), jsx(Footer, { host: host })] }));
746
736
  };
747
737
  const outputDir = "./tsp-output";
748
738
  async function compile(host, content, selectedEmitter, options) {
@@ -803,40 +793,60 @@ async function emptyOutputDir(host) {
803
793
  }
804
794
  }
805
795
 
806
- async function createReactPlayground(config) {
807
- const host = await createBrowserHost(config.libraries, config.importConfig);
808
- await registerMonacoLanguage(host);
809
- registerMonacoDefaultWorkers();
810
- const stateStorage = createStandalonePlaygroundStateStorage();
811
- const initialState = stateStorage.load();
812
- const App = () => {
813
- const toasterId = useId$1();
814
- const { dispatchToast } = useToastController(toasterId);
815
- const options = useMemo(() => {
816
- var _a;
817
- return ({
818
- ...config,
819
- host,
820
- libraries: config.libraries,
821
- defaultContent: initialState.content,
822
- defaultEmitter: (_a = initialState.emitter) !== null && _a !== void 0 ? _a : config.defaultEmitter,
823
- defaultCompilerOptions: initialState.options,
824
- defaultSampleName: initialState.sampleName,
825
- onSave: (value) => {
826
- stateStorage.save(value);
827
- void navigator.clipboard.writeText(window.location.toString());
828
- dispatchToast(jsxs(Toast, { children: [jsx(ToastTitle, { children: "Saved!" }), jsx(ToastBody, { children: "Playground link has been copied to the clipboard." })] }), { intent: "success" });
829
- },
830
- });
831
- }, [dispatchToast]);
832
- return (jsxs(FluentProvider, { theme: webLightTheme, children: [jsx(Toaster, { toasterId: toasterId }), jsx("div", { css: { height: "100vh" }, children: jsx(Playground, { ...options }) })] }));
796
+ function useStandalonePlaygroundContext(config) {
797
+ const [context, setContext] = useState();
798
+ useEffect(() => {
799
+ const load = async () => {
800
+ const host = await createBrowserHost(config.libraries, config.importConfig);
801
+ await registerMonacoLanguage(host);
802
+ const stateStorage = createStandalonePlaygroundStateStorage();
803
+ const initialState = stateStorage.load();
804
+ setContext({ host, initialState, stateStorage });
805
+ };
806
+ void load();
807
+ }, []);
808
+ return context;
809
+ }
810
+ const StandalonePlayground = (config) => {
811
+ const context = useStandalonePlaygroundContext(config);
812
+ const toasterId = useId$1();
813
+ const { dispatchToast } = useToastController(toasterId);
814
+ const onSave = useCallback((value) => {
815
+ if (!context) {
816
+ return;
817
+ }
818
+ context.stateStorage.save(value);
819
+ void navigator.clipboard.writeText(window.location.toString());
820
+ dispatchToast(jsxs(Toast, { children: [jsx(ToastTitle, { children: "Saved!" }), jsx(ToastBody, { children: "Playground link has been copied to the clipboard." })] }), { intent: "success" });
821
+ }, [dispatchToast, context]);
822
+ const fixedOptions = useMemo(() => {
823
+ var _a;
824
+ return context && {
825
+ host: context.host,
826
+ libraries: config.libraries,
827
+ defaultContent: context.initialState.content,
828
+ defaultEmitter: (_a = context.initialState.emitter) !== null && _a !== void 0 ? _a : config.defaultEmitter,
829
+ defaultCompilerOptions: context.initialState.options,
830
+ defaultSampleName: context.initialState.sampleName,
831
+ };
832
+ }, [context]);
833
+ if (context === undefined || fixedOptions === undefined) {
834
+ return jsx(Fragment, {});
835
+ }
836
+ const options = {
837
+ ...config,
838
+ ...fixedOptions,
839
+ onSave,
833
840
  };
834
- return jsx(App, {});
841
+ return (jsxs(Fragment, { children: [jsx(Toaster, { toasterId: toasterId }), options && jsx(Playground, { ...options })] }));
842
+ };
843
+ async function createReactPlayground(config) {
844
+ return jsx(StandalonePlayground, { ...config });
835
845
  }
836
846
  async function renderReactPlayground(config) {
837
847
  const app = await createReactPlayground(config);
838
848
  const root = createRoot(document.getElementById("root"));
839
- root.render(app);
849
+ root.render(jsx(FluentProvider, { theme: webLightTheme, style: { height: "100vh" }, children: app }));
840
850
  }
841
851
  function createStandalonePlaygroundStateStorage() {
842
852
  const stateStorage = createUrlStateStorage({
@@ -863,5 +873,5 @@ function createStandalonePlaygroundStateStorage() {
863
873
  };
864
874
  }
865
875
 
866
- export { Playground, createReactPlayground, renderReactPlayground };
876
+ export { Playground, StandalonePlayground, createReactPlayground, renderReactPlayground };
867
877
  //# sourceMappingURL=index.js.map