@typespec/playground 0.13.0-dev.2 → 0.13.0-dev.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- export { c as createBrowserHost, r as registerMonacoLanguage } from './services-CzxNzZLi.js';
1
+ export { c as createBrowserHost, r as registerMonacoLanguage } from './services-Z619RuQS.js';
2
2
  export { createUrlStateStorage } from './state-storage.js';
3
3
 
4
4
  function registerMonacoDefaultWorkersForVite() {
@@ -1,13 +1,14 @@
1
1
  import require$$0, { createContext, useContext, memo, useCallback, useRef, useEffect, useMemo, useState, useId as useId$1 } from 'react';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
- import { mergeClasses, Popover, PopoverTrigger, PopoverSurface, Title3, Table, TableHeader, TableRow, TableHeaderCell, TableBody, TableCell, Select, tokens, Card, Text, Tooltip, ToolbarButton, OverlayDrawer, DrawerHeader, DrawerHeaderTitle, Button, DrawerBody, useId, Label, Checkbox, RadioGroup, Radio, Input, Switch, Divider, Dialog, DialogTrigger, DialogSurface, DialogBody, DialogTitle, DialogContent, Toolbar, Link, TabList, Tab, useToastController, Toast, ToastTitle, ToastBody, Toaster, FluentProvider, webLightTheme } from '@fluentui/react-components';
3
+ import { mergeClasses, Popover, PopoverTrigger, PopoverSurface, Title3, Table, TableHeader, TableRow, TableHeaderCell, TableBody, TableCell, Select, tokens, Card, Text, Tooltip, ToolbarButton, OverlayDrawer, DrawerHeader, DrawerHeaderTitle, Button, DrawerBody, Toolbar, Link, useId, Label, Checkbox, RadioGroup, Radio, Input, Switch, Subtitle2, TabList, Tab, useToastController, Toast, ToastTitle, ToastBody, Toaster, FluentProvider, webLightTheme } from '@fluentui/react-components';
4
4
  import { getSourceLocation } from '@typespec/compiler';
5
5
  import { editor, Uri, MarkerSeverity, KeyMod, KeyCode } from 'monaco-editor';
6
6
  import { $ } from '@typespec/compiler/typekit';
7
- import { DocumentBulletList24Regular, Dismiss24Regular, Settings24Regular, Save16Regular, Broom16Filled, Bug16Regular, FolderListRegular, DataLineRegular, ErrorCircle16Filled, Warning16Filled, ChevronDown16Regular } from '@fluentui/react-icons';
7
+ import { DocumentBulletList24Regular, Dismiss24Regular, Save16Regular, Broom16Filled, Bug16Regular, SettingsRegular, FolderListRegular, DataLineRegular, ErrorCircle16Filled, Warning16Filled, ChevronDown16Regular } from '@fluentui/react-icons';
8
8
  import debounce from 'debounce';
9
9
  import { CompletionItemTag } from 'vscode-languageserver';
10
- import { a as resolveVirtualPath, p as printDebugInfo, d as debugGlobals, g as getMonacoRange, u as updateDiagnosticsForCodeFixes, c as createBrowserHost, r as registerMonacoLanguage } from '../services-CzxNzZLi.js';
10
+ import { a as resolveVirtualPath, p as printDebugInfo, d as debugGlobals, g as getMonacoRange, u as updateDiagnosticsForCodeFixes, c as createBrowserHost, r as registerMonacoLanguage } from '../services-Z619RuQS.js';
11
+ import { stringify, parse } from 'yaml';
11
12
  import { ErrorBoundary } from 'react-error-boundary';
12
13
  import { TypeGraph } from '@typespec/html-program-viewer/react';
13
14
  import '@typespec/html-program-viewer/style.css';
@@ -26,7 +27,7 @@ function usePlaygroundContext() {
26
27
 
27
28
  const list = "_list_wrnwm_1";
28
29
  const item$1 = "_item_wrnwm_4";
29
- const style$b = {
30
+ const style$e = {
30
31
  list: list,
31
32
  item: item$1,
32
33
  "item--error": "_item--error_wrnwm_15",
@@ -46,9 +47,9 @@ const DiagnosticList = ({
46
47
  [onDiagnosticSelected]
47
48
  );
48
49
  if (diagnostics.length === 0) {
49
- return /* @__PURE__ */ jsx("div", { className: style$b["list"], children: "No errors" });
50
+ return /* @__PURE__ */ jsx("div", { className: style$e["list"], children: "No errors" });
50
51
  }
51
- return /* @__PURE__ */ jsx("div", { className: style$b["list"], children: diagnostics.map((x, i) => {
52
+ return /* @__PURE__ */ jsx("div", { className: style$e["list"], children: diagnostics.map((x, i) => {
52
53
  return /* @__PURE__ */ jsx(DiagnosticItem, { diagnostic: x, onItemSelected: handleItemSelected }, i);
53
54
  }) });
54
55
  };
@@ -56,19 +57,19 @@ const DiagnosticItem = ({ diagnostic, onItemSelected }) => {
56
57
  const handleClick = useCallback(() => {
57
58
  onItemSelected(diagnostic);
58
59
  }, [diagnostic, onItemSelected]);
59
- return /* @__PURE__ */ jsxs("div", { tabIndex: 0, className: style$b["item"], onClick: handleClick, children: [
60
+ return /* @__PURE__ */ jsxs("div", { tabIndex: 0, className: style$e["item"], onClick: handleClick, children: [
60
61
  /* @__PURE__ */ jsx(
61
62
  "div",
62
63
  {
63
64
  className: mergeClasses(
64
- (style$b[diagnostic.severity === "error" ? "item--error" : "item--warning"])
65
+ (style$e[diagnostic.severity === "error" ? "item--error" : "item--warning"])
65
66
  ),
66
67
  children: diagnostic.severity
67
68
  }
68
69
  ),
69
- /* @__PURE__ */ jsx("div", { className: style$b["item-code"], children: diagnostic.code }),
70
- /* @__PURE__ */ jsx("div", { className: style$b["item-message"], children: diagnostic.message }),
71
- /* @__PURE__ */ jsx("div", { className: style$b["item-loc"], children: /* @__PURE__ */ jsx(DiagnosticTargetLink, { target: diagnostic.target }) })
70
+ /* @__PURE__ */ jsx("div", { className: style$e["item-code"], children: diagnostic.code }),
71
+ /* @__PURE__ */ jsx("div", { className: style$e["item-message"], children: diagnostic.message }),
72
+ /* @__PURE__ */ jsx("div", { className: style$e["item-loc"], children: /* @__PURE__ */ jsx(DiagnosticTargetLink, { target: diagnostic.target }) })
72
73
  ] });
73
74
  };
74
75
  const DiagnosticTargetLink = memo(({ target }) => {
@@ -133,18 +134,18 @@ function useMonacoModel(uri, language) {
133
134
  }
134
135
 
135
136
  const footer = "_footer_e6dic_1";
136
- const style$a = {
137
+ const style$d = {
137
138
  footer: footer,
138
139
  "footer-item": "_footer-item_e6dic_9"
139
140
  };
140
141
 
141
142
  const FooterItem = ({ children, link, className }) => {
142
- const resolvedClassName = mergeClasses(style$a["footer-item"], className);
143
+ const resolvedClassName = mergeClasses(style$d["footer-item"], className);
143
144
  return link ? /* @__PURE__ */ jsx("a", { className: resolvedClassName, href: link, target: "_blank", rel: "noopener noreferrer", children }) : /* @__PURE__ */ jsx("div", { className: resolvedClassName, children });
144
145
  };
145
146
 
146
147
  const button = "_button_1c15n_4";
147
- const style$9 = {
148
+ const style$c = {
148
149
  "version-item": "_version-item_1c15n_1",
149
150
  button: button
150
151
  };
@@ -153,8 +154,8 @@ const FooterVersionItem = memo(({ versionSelector }) => {
153
154
  const { host } = usePlaygroundContext();
154
155
  const latest = versionSelector?.latest;
155
156
  const selected = versionSelector?.selected ?? host.compiler.MANIFEST.version;
156
- return /* @__PURE__ */ jsx(FooterItem, { className: style$9["version-item"], children: /* @__PURE__ */ jsxs(Popover, { children: [
157
- /* @__PURE__ */ jsx(PopoverTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ jsxs("div", { className: style$9["button"], children: [
157
+ return /* @__PURE__ */ jsx(FooterItem, { className: style$c["version-item"], children: /* @__PURE__ */ jsxs(Popover, { children: [
158
+ /* @__PURE__ */ jsx(PopoverTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ jsxs("div", { className: style$c["button"], children: [
158
159
  /* @__PURE__ */ jsx("span", { children: "Version " }),
159
160
  /* @__PURE__ */ jsx("span", { children: selected }),
160
161
  /* @__PURE__ */ jsx("span", { children: latest ? latest === selected ? " (latest)" : " (old)" : "" })
@@ -200,7 +201,7 @@ const VersionSelector = memo(({ versions, selected, latest, onChange }) => {
200
201
  });
201
202
 
202
203
  const Footer = ({ className, children }) => {
203
- return /* @__PURE__ */ jsx("div", { className: mergeClasses(style$a.footer, className), children });
204
+ return /* @__PURE__ */ jsx("div", { className: mergeClasses(style$d.footer, className), children });
204
205
  };
205
206
 
206
207
  function useControllableValue(controlledValue, defaultUncontrolledValue, onChange) {
@@ -988,7 +989,7 @@ const EmitterDropdown = ({
988
989
  );
989
990
  };
990
991
 
991
- const style$8 = {
992
+ const style$b = {
992
993
  "samples-grid": "_samples-grid_1dkte_1",
993
994
  "sample-card": "_sample-card_1dkte_8",
994
995
  "sample-card-content": "_sample-card-content_1dkte_26",
@@ -1075,9 +1076,9 @@ const SampleIcon = ({ name }) => {
1075
1076
  );
1076
1077
  }
1077
1078
  };
1078
- return /* @__PURE__ */ jsxs("div", { className: style$8["sample-icon"], style: { backgroundColor: colors.bg }, "aria-hidden": "true", children: [
1079
- /* @__PURE__ */ jsx("svg", { width: "48", height: "48", viewBox: "0 0 48 48", className: style$8["sample-icon-pattern"], children: renderPattern() }),
1080
- /* @__PURE__ */ jsx("span", { className: style$8["sample-icon-initials"], style: { color: colors.fg }, children: initials })
1079
+ return /* @__PURE__ */ jsxs("div", { className: style$b["sample-icon"], style: { backgroundColor: colors.bg }, "aria-hidden": "true", children: [
1080
+ /* @__PURE__ */ jsx("svg", { width: "48", height: "48", viewBox: "0 0 48 48", className: style$b["sample-icon-pattern"], children: renderPattern() }),
1081
+ /* @__PURE__ */ jsx("span", { className: style$b["sample-icon-initials"], style: { color: colors.fg }, children: initials })
1081
1082
  ] });
1082
1083
  };
1083
1084
 
@@ -1085,7 +1086,7 @@ const SampleCard = ({ name, sample, onSelect }) => {
1085
1086
  return /* @__PURE__ */ jsx(
1086
1087
  Card,
1087
1088
  {
1088
- className: style$8["sample-card"],
1089
+ className: style$b["sample-card"],
1089
1090
  onClick: () => onSelect(name),
1090
1091
  role: "button",
1091
1092
  tabIndex: 0,
@@ -1095,11 +1096,11 @@ const SampleCard = ({ name, sample, onSelect }) => {
1095
1096
  onSelect(name);
1096
1097
  }
1097
1098
  },
1098
- children: /* @__PURE__ */ jsxs("div", { className: style$8["sample-card-content"], children: [
1099
+ children: /* @__PURE__ */ jsxs("div", { className: style$b["sample-card-content"], children: [
1099
1100
  /* @__PURE__ */ jsx(SampleIcon, { name }),
1100
- /* @__PURE__ */ jsxs("div", { className: style$8["sample-card-text"], children: [
1101
- /* @__PURE__ */ jsx(Text, { as: "h3", weight: "semibold", className: style$8["sample-title"], children: name }),
1102
- sample.description && /* @__PURE__ */ jsx(Text, { as: "p", className: style$8["sample-description"], children: sample.description })
1101
+ /* @__PURE__ */ jsxs("div", { className: style$b["sample-card-text"], children: [
1102
+ /* @__PURE__ */ jsx(Text, { as: "h3", weight: "semibold", className: style$b["sample-title"], children: name }),
1103
+ sample.description && /* @__PURE__ */ jsx(Text, { as: "p", className: style$b["sample-description"], children: sample.description })
1103
1104
  ] })
1104
1105
  ] })
1105
1106
  }
@@ -1151,19 +1152,140 @@ const SamplesDrawerTrigger = ({
1151
1152
  children: "Sample Gallery"
1152
1153
  }
1153
1154
  ) }),
1154
- /* @__PURE__ */ jsx(DrawerBody, { children: /* @__PURE__ */ jsx("div", { className: style$8["samples-grid"], children: Object.entries(samples).map(([name, sample]) => /* @__PURE__ */ jsx(SampleCard, { name, sample, onSelect: handleSampleSelect }, name)) }) })
1155
+ /* @__PURE__ */ jsx(DrawerBody, { children: /* @__PURE__ */ jsx("div", { className: style$b["samples-grid"], children: Object.entries(samples).map(([name, sample]) => /* @__PURE__ */ jsx(SampleCard, { name, sample, onSelect: handleSampleSelect }, name)) }) })
1155
1156
  ]
1156
1157
  }
1157
1158
  )
1158
1159
  ] });
1159
1160
  };
1160
1161
 
1161
- const form = "_form_sqeas_1";
1162
- const item = "_item_sqeas_7";
1163
- const style$7 = {
1162
+ const bar = "_bar_15c2c_1";
1163
+ const divider = "_divider_15c2c_5";
1164
+ const spacer = "_spacer_15c2c_9";
1165
+ const style$a = {
1166
+ bar: bar,
1167
+ divider: divider,
1168
+ spacer: spacer
1169
+ };
1170
+
1171
+ const EditorCommandBar = ({
1172
+ documentationUrl,
1173
+ saveCode,
1174
+ formatCode,
1175
+ fileBug,
1176
+ host,
1177
+ selectedEmitter,
1178
+ onSelectedEmitterChange,
1179
+ samples,
1180
+ selectedSampleName,
1181
+ onSelectedSampleNameChange,
1182
+ commandBarButtons
1183
+ }) => {
1184
+ const documentation = documentationUrl ? /* @__PURE__ */ jsx("label", { children: /* @__PURE__ */ jsx(Link, { href: documentationUrl, target: "_blank", children: "Docs" }) }) : void 0;
1185
+ const bugButton = fileBug ? /* @__PURE__ */ jsx(FileBugButton, { onClick: fileBug }) : void 0;
1186
+ const emitters = useMemo(
1187
+ () => Object.values(host.libraries).filter((x) => x.isEmitter).map((x) => x.name),
1188
+ [host.libraries]
1189
+ );
1190
+ return /* @__PURE__ */ jsx("div", { className: style$a["bar"], children: /* @__PURE__ */ jsxs(Toolbar, { children: [
1191
+ /* @__PURE__ */ jsx(Tooltip, { content: "Save", relationship: "description", withArrow: true, children: /* @__PURE__ */ jsx(ToolbarButton, { "aria-label": "Save", icon: /* @__PURE__ */ jsx(Save16Regular, {}), onClick: saveCode }) }),
1192
+ /* @__PURE__ */ jsx(Tooltip, { content: "Format", relationship: "description", withArrow: true, children: /* @__PURE__ */ jsx(ToolbarButton, { "aria-label": "Format", icon: /* @__PURE__ */ jsx(Broom16Filled, {}), onClick: formatCode }) }),
1193
+ samples && /* @__PURE__ */ jsxs(Fragment, { children: [
1194
+ /* @__PURE__ */ jsx(
1195
+ SamplesDrawerTrigger,
1196
+ {
1197
+ samples,
1198
+ onSelectedSampleNameChange
1199
+ }
1200
+ ),
1201
+ /* @__PURE__ */ jsx("div", { className: style$a["spacer"] })
1202
+ ] }),
1203
+ /* @__PURE__ */ jsx(
1204
+ EmitterDropdown,
1205
+ {
1206
+ emitters,
1207
+ onSelectedEmitterChange,
1208
+ selectedEmitter
1209
+ }
1210
+ ),
1211
+ documentation && /* @__PURE__ */ jsxs(Fragment, { children: [
1212
+ /* @__PURE__ */ jsx("div", { className: style$a["spacer"] }),
1213
+ documentation
1214
+ ] }),
1215
+ /* @__PURE__ */ jsx("div", { className: style$a["divider"] }),
1216
+ commandBarButtons,
1217
+ bugButton
1218
+ ] }) });
1219
+ };
1220
+ const FileBugButton = ({ onClick }) => {
1221
+ return /* @__PURE__ */ jsx(Tooltip, { content: "File Bug Report", relationship: "description", withArrow: true, children: /* @__PURE__ */ jsx(
1222
+ ToolbarButton,
1223
+ {
1224
+ appearance: "subtle",
1225
+ "aria-label": "File Bug Report",
1226
+ icon: /* @__PURE__ */ jsx(Bug16Regular, {}),
1227
+ onClick
1228
+ }
1229
+ ) });
1230
+ };
1231
+
1232
+ const DefaultFooter = () => {
1233
+ return /* @__PURE__ */ jsx(Footer, { children: /* @__PURE__ */ jsx(FooterVersionItem, {}) });
1234
+ };
1235
+
1236
+ const TypeSpecEditor = ({
1237
+ actions,
1238
+ options,
1239
+ ...other
1240
+ }) => {
1241
+ const resolvedOptions = {
1242
+ "semanticHighlighting.enabled": true,
1243
+ automaticLayout: true,
1244
+ tabSize: 2,
1245
+ minimap: {
1246
+ enabled: false
1247
+ },
1248
+ ...options
1249
+ };
1250
+ return /* @__PURE__ */ jsx(Editor, { actions, options: resolvedOptions, ...other });
1251
+ };
1252
+ const OutputEditor = ({ filename, value, editorOptions }) => {
1253
+ const model = useMonacoModel(filename);
1254
+ if (filename === "") {
1255
+ return null;
1256
+ }
1257
+ const options = {
1258
+ ...editorOptions,
1259
+ readOnly: true,
1260
+ automaticLayout: true,
1261
+ minimap: {
1262
+ enabled: false
1263
+ }
1264
+ };
1265
+ model.setValue(value);
1266
+ return /* @__PURE__ */ jsx(Editor, { model, options });
1267
+ };
1268
+
1269
+ const settings = "_settings_1yvpj_1";
1270
+ const section = "_section_1yvpj_7";
1271
+ const field = "_field_1yvpj_23";
1272
+ const empty = "_empty_1yvpj_33";
1273
+ const style$9 = {
1274
+ settings: settings,
1275
+ section: section,
1276
+ "section-title": "_section-title_1yvpj_19",
1277
+ field: field,
1278
+ empty: empty
1279
+ };
1280
+
1281
+ const form = "_form_w9o1o_1";
1282
+ const item = "_item_w9o1o_7";
1283
+ const description = "_description_w9o1o_13";
1284
+ const style$8 = {
1164
1285
  form: form,
1165
1286
  item: item,
1166
- "switch": "_switch_sqeas_13"
1287
+ description: description,
1288
+ "switch": "_switch_w9o1o_17"
1167
1289
  };
1168
1290
 
1169
1291
  const EmitterOptionsForm = ({
@@ -1185,11 +1307,11 @@ const EmitterOptionsForm = ({
1185
1307
  );
1186
1308
  const emitterOptionsSchema = library.definition?.emitter?.options?.properties;
1187
1309
  if (emitterOptionsSchema === void 0) {
1188
- return /* @__PURE__ */ jsx(Fragment, { children: '"No options"' });
1310
+ return /* @__PURE__ */ jsx(Text, { size: 200, children: "No options available" });
1189
1311
  }
1190
1312
  const entries = Object.entries(emitterOptionsSchema);
1191
- return /* @__PURE__ */ jsx("div", { className: style$7["form"], children: entries.map(([key, value]) => {
1192
- return /* @__PURE__ */ jsx("div", { className: style$7["form-item"], children: value.type === "array" ? /* @__PURE__ */ jsx(
1313
+ return /* @__PURE__ */ jsx("div", { className: style$8["form"], children: entries.map(([key, value]) => {
1314
+ return /* @__PURE__ */ jsx("div", { className: style$8["form-item"], children: value.type === "array" ? /* @__PURE__ */ jsx(
1193
1315
  JsonSchemaArrayPropertyInput,
1194
1316
  {
1195
1317
  emitterOptions: options[library.name] ?? {},
@@ -1240,7 +1362,7 @@ const JsonSchemaArrayPropertyInput = ({
1240
1362
  return JsonSchemaPropertyInput({ emitterOptions, name, prop: itemsSchema, onChange });
1241
1363
  }
1242
1364
  const itemsEnum = itemsSchema.enum;
1243
- return /* @__PURE__ */ jsxs("div", { className: style$7["item"], children: [
1365
+ return /* @__PURE__ */ jsxs("div", { className: style$8["item"], children: [
1244
1366
  /* @__PURE__ */ jsx(Label, { htmlFor: inputId, title: name, children: prettyName }),
1245
1367
  itemsEnum.map((x) => /* @__PURE__ */ jsx(
1246
1368
  Checkbox,
@@ -1272,20 +1394,24 @@ const JsonSchemaPropertyInput = ({
1272
1394
  );
1273
1395
  switch (prop.type) {
1274
1396
  case "boolean":
1275
- return /* @__PURE__ */ jsx(
1276
- Switch,
1277
- {
1278
- className: style$7["switch"],
1279
- label: prettyName,
1280
- labelPosition: "above",
1281
- checked: value,
1282
- onChange: handleChange
1283
- }
1284
- );
1397
+ return /* @__PURE__ */ jsxs("div", { className: style$8["item"], children: [
1398
+ /* @__PURE__ */ jsx(
1399
+ Switch,
1400
+ {
1401
+ className: style$8["switch"],
1402
+ label: prettyName,
1403
+ labelPosition: "above",
1404
+ checked: value,
1405
+ onChange: handleChange
1406
+ }
1407
+ ),
1408
+ prop.description && /* @__PURE__ */ jsx(Text, { size: 200, className: style$8["description"], children: prop.description })
1409
+ ] });
1285
1410
  case "string":
1286
1411
  default:
1287
- return /* @__PURE__ */ jsxs("div", { className: style$7["item"], children: [
1412
+ return /* @__PURE__ */ jsxs("div", { className: style$8["item"], children: [
1288
1413
  /* @__PURE__ */ jsx(Label, { htmlFor: inputId, title: name, children: prettyName }),
1414
+ prop.description && /* @__PURE__ */ jsx(Text, { size: 200, className: style$8["description"], children: prop.description }),
1289
1415
  prop.enum ? /* @__PURE__ */ jsx(RadioGroup, { layout: "horizontal", id: inputId, value, onChange: handleChange, children: prop.enum.map((x) => /* @__PURE__ */ jsx(Radio, { value: x, label: x }, x)) }) : /* @__PURE__ */ jsx(Input, { id: inputId, value, onChange: handleChange })
1290
1416
  ] });
1291
1417
  }
@@ -1301,7 +1427,7 @@ const LinterForm = ({
1301
1427
  return Object.keys(linter?.ruleSets ?? {}).map((x) => `${lib.name}/${x}`);
1302
1428
  });
1303
1429
  if (rulesets.length === 0) {
1304
- return /* @__PURE__ */ jsx(Fragment, { children: "No ruleset available" });
1430
+ return /* @__PURE__ */ jsx(Text, { style: { color: "var(--colorNeutralForeground3)", fontStyle: "italic" }, children: "No ruleset available" });
1305
1431
  }
1306
1432
  const handleChange = (ruleSet, checked) => {
1307
1433
  const ruleSets = linterRuleSet.extends ?? [];
@@ -1334,6 +1460,7 @@ const RuleSetCheckbox = ({ ruleSet, checked, onChange }) => {
1334
1460
 
1335
1461
  const CompilerSettings = ({
1336
1462
  selectedEmitter,
1463
+ onSelectedEmitterChange,
1337
1464
  host,
1338
1465
  options,
1339
1466
  onOptionsChanged
@@ -1358,172 +1485,243 @@ const CompilerSettings = ({
1358
1485
  },
1359
1486
  [onOptionsChanged, options]
1360
1487
  );
1361
- return /* @__PURE__ */ jsxs("div", { children: [
1362
- /* @__PURE__ */ jsxs(Fragment, { children: [
1363
- "Emitter: ",
1364
- selectedEmitter
1488
+ const emitters = useMemo(
1489
+ () => Object.values(host.libraries).filter((x) => x.isEmitter).map((x) => x.name),
1490
+ [host.libraries]
1491
+ );
1492
+ const handleEmitterChange = useCallback(
1493
+ (evt) => {
1494
+ onSelectedEmitterChange(evt.target.value);
1495
+ },
1496
+ [onSelectedEmitterChange]
1497
+ );
1498
+ return /* @__PURE__ */ jsxs("div", { className: style$9["settings"], children: [
1499
+ /* @__PURE__ */ jsxs("section", { className: style$9["section"], children: [
1500
+ /* @__PURE__ */ jsx(Subtitle2, { className: style$9["section-title"], children: "Emitter" }),
1501
+ /* @__PURE__ */ jsxs("div", { className: style$9["field"], children: [
1502
+ /* @__PURE__ */ jsx(Label, { children: "Select emitter" }),
1503
+ /* @__PURE__ */ jsxs(
1504
+ Select,
1505
+ {
1506
+ value: selectedEmitter,
1507
+ onChange: handleEmitterChange,
1508
+ "aria-label": "Select emitter",
1509
+ children: [
1510
+ /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "Select emitter..." }),
1511
+ emitters.map((name) => /* @__PURE__ */ jsx("option", { children: name }, name))
1512
+ ]
1513
+ }
1514
+ )
1515
+ ] })
1365
1516
  ] }),
1366
- /* @__PURE__ */ jsx(Divider, { style: { marginTop: 20 } }),
1367
- /* @__PURE__ */ jsx("h3", { children: "Options" }),
1368
- library && /* @__PURE__ */ jsx(
1369
- EmitterOptionsForm,
1370
- {
1371
- library,
1372
- options: options.options ?? {},
1373
- optionsChanged: emitterOptionsChanged
1374
- }
1375
- ),
1376
- /* @__PURE__ */ jsx(Divider, { style: { marginTop: 20 } }),
1377
- /* @__PURE__ */ jsx("h3", { children: "Linter" }),
1378
- /* @__PURE__ */ jsx(
1379
- LinterForm,
1380
- {
1381
- libraries: host.libraries,
1382
- linterRuleSet,
1383
- onLinterRuleSetChanged: linterRuleSetChanged
1384
- }
1385
- )
1386
- ] });
1387
- };
1388
-
1389
- const CompilerSettingsDialogButton = ({
1390
- selectedEmitter,
1391
- compilerOptions,
1392
- onCompilerOptionsChange
1393
- }) => {
1394
- const { host } = usePlaygroundContext();
1395
- return /* @__PURE__ */ jsxs(Dialog, { children: [
1396
- /* @__PURE__ */ jsx(DialogTrigger, { children: /* @__PURE__ */ jsx(ToolbarButton, { icon: /* @__PURE__ */ jsx(Settings24Regular, {}), "aria-label": "Open Settings" }) }),
1397
- /* @__PURE__ */ jsx(DialogSurface, { children: /* @__PURE__ */ jsxs(DialogBody, { children: [
1398
- /* @__PURE__ */ jsx(DialogTitle, { children: "Settings" }),
1399
- /* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsx(
1400
- CompilerSettings,
1517
+ /* @__PURE__ */ jsxs("section", { className: style$9["section"], children: [
1518
+ /* @__PURE__ */ jsx(Subtitle2, { className: style$9["section-title"], children: "Emitter options" }),
1519
+ library ? /* @__PURE__ */ jsx(
1520
+ EmitterOptionsForm,
1401
1521
  {
1402
- host,
1403
- selectedEmitter,
1404
- options: compilerOptions,
1405
- onOptionsChanged: onCompilerOptionsChange
1522
+ library,
1523
+ options: options.options ?? {},
1524
+ optionsChanged: emitterOptionsChanged
1406
1525
  }
1407
- ) })
1408
- ] }) })
1526
+ ) : /* @__PURE__ */ jsx(Text, { size: 200, className: style$9["empty"], children: "No emitter selected" })
1527
+ ] }),
1528
+ /* @__PURE__ */ jsxs("section", { className: style$9["section"], children: [
1529
+ /* @__PURE__ */ jsx(Subtitle2, { className: style$9["section-title"], children: "Linter rules" }),
1530
+ /* @__PURE__ */ jsx(
1531
+ LinterForm,
1532
+ {
1533
+ libraries: host.libraries,
1534
+ linterRuleSet,
1535
+ onLinterRuleSetChanged: linterRuleSetChanged
1536
+ }
1537
+ )
1538
+ ] })
1409
1539
  ] });
1410
1540
  };
1411
1541
 
1412
- const bar = "_bar_15c2c_1";
1413
- const divider = "_divider_15c2c_5";
1414
- const spacer = "_spacer_15c2c_9";
1415
- const style$6 = {
1416
- bar: bar,
1417
- divider: divider,
1418
- spacer: spacer
1542
+ const style$7 = {
1543
+ "config-panel": "_config-panel_cffut_1",
1544
+ "config-toggle": "_config-toggle_cffut_8",
1545
+ "config-content": "_config-content_cffut_17",
1546
+ "form-content": "_form-content_cffut_23"
1419
1547
  };
1420
1548
 
1421
- const EditorCommandBar = ({
1422
- documentationUrl,
1423
- saveCode,
1424
- formatCode,
1425
- fileBug,
1549
+ function compilerOptionsToTspConfig(selectedEmitter, compilerOptions) {
1550
+ const config = {};
1551
+ if (selectedEmitter) {
1552
+ config.emit = [selectedEmitter];
1553
+ }
1554
+ if (compilerOptions.options && Object.keys(compilerOptions.options).length > 0) {
1555
+ config.options = compilerOptions.options;
1556
+ }
1557
+ if (compilerOptions.linterRuleSet) {
1558
+ config.linter = compilerOptions.linterRuleSet;
1559
+ }
1560
+ return stringify(config, { indent: 2 }) || "";
1561
+ }
1562
+ function parseTspConfigYaml(yamlContent) {
1563
+ try {
1564
+ const config = parse(yamlContent);
1565
+ if (!config || typeof config !== "object") {
1566
+ return { compilerOptions: {} };
1567
+ }
1568
+ const compilerOptions = {};
1569
+ if (config.options) {
1570
+ compilerOptions.options = config.options;
1571
+ }
1572
+ if (config.linter) {
1573
+ compilerOptions.linterRuleSet = config.linter;
1574
+ }
1575
+ const selectedEmitter = config.emit?.[0];
1576
+ return { selectedEmitter, compilerOptions };
1577
+ } catch {
1578
+ return void 0;
1579
+ }
1580
+ }
1581
+
1582
+ const ConfigPanel = ({
1426
1583
  host,
1427
1584
  selectedEmitter,
1428
- onSelectedEmitterChange,
1429
1585
  compilerOptions,
1430
1586
  onCompilerOptionsChange,
1431
- samples,
1432
- selectedSampleName,
1433
- onSelectedSampleNameChange,
1434
- commandBarButtons
1587
+ onSelectedEmitterChange,
1588
+ editorOptions
1435
1589
  }) => {
1436
- const documentation = documentationUrl ? /* @__PURE__ */ jsx("label", { children: /* @__PURE__ */ jsx(Link, { href: documentationUrl, target: "_blank", children: "Docs" }) }) : void 0;
1437
- const bugButton = fileBug ? /* @__PURE__ */ jsx(FileBugButton, { onClick: fileBug }) : void 0;
1438
- const emitters = useMemo(
1439
- () => Object.values(host.libraries).filter((x) => x.isEmitter).map((x) => x.name),
1440
- [host.libraries]
1590
+ const [mode, setMode] = useState("form");
1591
+ const yamlModel = useMonacoModel("inmemory://test/tspconfig.yaml", "yaml");
1592
+ const changeFromYamlRef = useRef(false);
1593
+ useEffect(() => {
1594
+ if (mode !== "yaml") return;
1595
+ if (changeFromYamlRef.current) {
1596
+ changeFromYamlRef.current = false;
1597
+ return;
1598
+ }
1599
+ const yaml = compilerOptionsToTspConfig(selectedEmitter, compilerOptions);
1600
+ const current = yamlModel.getValue();
1601
+ if (current !== yaml) {
1602
+ yamlModel.setValue(yaml);
1603
+ }
1604
+ }, [selectedEmitter, compilerOptions, mode, yamlModel]);
1605
+ const parseAndSync = useMemo(
1606
+ () => debounce((content) => {
1607
+ const parsed = parseTspConfigYaml(content);
1608
+ if (!parsed) return;
1609
+ changeFromYamlRef.current = true;
1610
+ if (parsed.selectedEmitter && parsed.selectedEmitter !== selectedEmitter) {
1611
+ onSelectedEmitterChange(parsed.selectedEmitter);
1612
+ }
1613
+ onCompilerOptionsChange(parsed.compilerOptions);
1614
+ }, 200),
1615
+ [selectedEmitter, onCompilerOptionsChange, onSelectedEmitterChange]
1441
1616
  );
1442
- return /* @__PURE__ */ jsx("div", { className: style$6["bar"], children: /* @__PURE__ */ jsxs(Toolbar, { children: [
1443
- /* @__PURE__ */ jsx(Tooltip, { content: "Save", relationship: "description", withArrow: true, children: /* @__PURE__ */ jsx(ToolbarButton, { "aria-label": "Save", icon: /* @__PURE__ */ jsx(Save16Regular, {}), onClick: saveCode }) }),
1444
- /* @__PURE__ */ jsx(Tooltip, { content: "Format", relationship: "description", withArrow: true, children: /* @__PURE__ */ jsx(ToolbarButton, { "aria-label": "Format", icon: /* @__PURE__ */ jsx(Broom16Filled, {}), onClick: formatCode }) }),
1445
- samples && /* @__PURE__ */ jsxs(Fragment, { children: [
1446
- /* @__PURE__ */ jsx(
1447
- SamplesDrawerTrigger,
1448
- {
1449
- samples,
1450
- onSelectedSampleNameChange
1451
- }
1452
- ),
1453
- /* @__PURE__ */ jsx("div", { className: style$6["spacer"] })
1454
- ] }),
1455
- /* @__PURE__ */ jsx(
1456
- EmitterDropdown,
1457
- {
1458
- emitters,
1459
- onSelectedEmitterChange,
1460
- selectedEmitter
1617
+ useEffect(() => {
1618
+ const disposable = yamlModel.onDidChangeContent(() => {
1619
+ parseAndSync(yamlModel.getValue());
1620
+ });
1621
+ return () => {
1622
+ parseAndSync.clear();
1623
+ disposable.dispose();
1624
+ };
1625
+ }, [yamlModel, parseAndSync]);
1626
+ const handleModeChange = useCallback(
1627
+ (_, data) => {
1628
+ const newMode = data.value;
1629
+ if (newMode === "yaml") {
1630
+ const yaml = compilerOptionsToTspConfig(selectedEmitter, compilerOptions);
1631
+ yamlModel.setValue(yaml);
1461
1632
  }
1462
- ),
1463
- documentation && /* @__PURE__ */ jsxs(Fragment, { children: [
1464
- /* @__PURE__ */ jsx("div", { className: style$6["spacer"] }),
1465
- documentation
1466
- ] }),
1467
- /* @__PURE__ */ jsx("div", { className: style$6["divider"] }),
1468
- commandBarButtons,
1469
- bugButton,
1470
- /* @__PURE__ */ jsx(
1471
- CompilerSettingsDialogButton,
1633
+ setMode(newMode);
1634
+ },
1635
+ [selectedEmitter, compilerOptions, yamlModel]
1636
+ );
1637
+ return /* @__PURE__ */ jsxs("div", { className: style$7["config-panel"], children: [
1638
+ /* @__PURE__ */ jsx("div", { className: style$7["config-toggle"], children: /* @__PURE__ */ jsxs(TabList, { size: "small", selectedValue: mode, onTabSelect: handleModeChange, children: [
1639
+ /* @__PURE__ */ jsx(Tab, { value: "form", children: "Visual" }),
1640
+ /* @__PURE__ */ jsx(Tab, { value: "yaml", children: "Yaml" })
1641
+ ] }) }),
1642
+ /* @__PURE__ */ jsx("div", { className: style$7["config-content"], children: mode === "form" ? /* @__PURE__ */ jsx("div", { className: style$7["form-content"], children: /* @__PURE__ */ jsx(
1643
+ CompilerSettings,
1472
1644
  {
1473
- compilerOptions,
1474
- onCompilerOptionsChange,
1475
- selectedEmitter
1645
+ host,
1646
+ selectedEmitter,
1647
+ onSelectedEmitterChange,
1648
+ options: compilerOptions,
1649
+ onOptionsChanged: onCompilerOptionsChange
1476
1650
  }
1477
- )
1478
- ] }) });
1479
- };
1480
- const FileBugButton = ({ onClick }) => {
1481
- return /* @__PURE__ */ jsx(Tooltip, { content: "File Bug Report", relationship: "description", withArrow: true, children: /* @__PURE__ */ jsx(
1482
- ToolbarButton,
1483
- {
1484
- appearance: "subtle",
1485
- "aria-label": "File Bug Report",
1486
- icon: /* @__PURE__ */ jsx(Bug16Regular, {}),
1487
- onClick
1488
- }
1489
- ) });
1651
+ ) }) : /* @__PURE__ */ jsx(Editor, { model: yamlModel, options: { ...editorOptions, minimap: { enabled: false } } }) })
1652
+ ] });
1490
1653
  };
1491
1654
 
1492
- const DefaultFooter = () => {
1493
- return /* @__PURE__ */ jsx(Footer, { children: /* @__PURE__ */ jsx(FooterVersionItem, {}) });
1655
+ const style$6 = {
1656
+ "editor-panel": "_editor-panel_k9ax7_1",
1657
+ "panel-tabs-container": "_panel-tabs-container_k9ax7_7",
1658
+ "panel-content": "_panel-content_k9ax7_11"
1494
1659
  };
1495
1660
 
1496
- const TypeSpecEditor = ({
1661
+ const TypeSpecIcon = () => (
1662
+ // icons/raw/tsp-logo-inverted.svg
1663
+ /* @__PURE__ */ jsx(
1664
+ "svg",
1665
+ {
1666
+ width: "1em",
1667
+ height: "1em",
1668
+ viewBox: "200 200 30 30",
1669
+ fill: "currentColor",
1670
+ xmlns: "http://www.w3.org/2000/svg",
1671
+ children: /* @__PURE__ */ jsx(
1672
+ "path",
1673
+ {
1674
+ d: "M 223.327 148.108 L 223.327 144.801 L 222.786 144.801 L 222.786 144.213 L 224.44 144.213 L 224.44 144.801 L 223.899 144.801 L 223.899 148.108 Z M 225.391 148.15 Q 225.156 148.15 224.999 148.072 Q 224.843 147.994 224.753 147.846 Q 224.663 147.697 224.624 147.488 Q 224.586 147.279 224.586 147.016 L 225.148 146.963 Q 225.148 147.09 225.157 147.208 Q 225.166 147.326 225.191 147.42 Q 225.217 147.514 225.266 147.57 Q 225.315 147.626 225.391 147.626 Q 225.519 147.626 225.572 147.508 Q 225.625 147.39 225.625 147.223 Q 225.625 147.056 225.537 146.876 Q 225.45 146.696 225.328 146.534 Q 225.121 146.258 224.966 146.022 Q 224.811 145.787 224.725 145.559 Q 224.639 145.331 224.639 145.082 Q 224.639 144.886 224.689 144.72 Q 224.74 144.554 224.836 144.431 Q 224.933 144.308 225.071 144.239 Q 225.209 144.17 225.386 144.17 Q 225.606 144.17 225.758 144.244 Q 225.911 144.319 226.005 144.456 Q 226.099 144.594 226.143 144.784 Q 226.186 144.973 226.186 145.204 L 225.625 145.257 Q 225.625 145.159 225.615 145.059 Q 225.606 144.96 225.582 144.878 Q 225.558 144.796 225.513 144.745 Q 225.468 144.695 225.397 144.695 Q 225.285 144.695 225.243 144.789 Q 225.201 144.883 225.201 145.055 Q 225.201 145.278 225.32 145.485 Q 225.439 145.691 225.641 145.967 Q 225.882 146.293 226.034 146.566 Q 226.186 146.839 226.186 147.17 Q 226.186 147.379 226.141 147.558 Q 226.096 147.737 226 147.87 Q 225.903 148.002 225.753 148.076 Q 225.603 148.15 225.391 148.15 Z M 226.494 148.108 L 226.494 144.213 L 227.066 144.213 Q 227.392 144.213 227.611 144.356 Q 227.829 144.499 227.938 144.761 Q 228.047 145.023 228.047 145.379 Q 228.047 145.734 227.933 145.991 Q 227.819 146.248 227.6 146.392 Q 227.381 146.537 227.066 146.55 L 227.066 148.108 Z M 227.066 145.967 Q 227.217 145.967 227.305 145.907 Q 227.392 145.848 227.43 145.718 Q 227.469 145.588 227.469 145.384 Q 227.469 145.177 227.43 145.047 Q 227.392 144.917 227.303 144.856 Q 227.214 144.796 227.066 144.796 Z",
1675
+ transform: "matrix(4.553588, 0, 0, 3.175088, -811.313782, -249.035522)"
1676
+ }
1677
+ )
1678
+ }
1679
+ )
1680
+ );
1681
+ const EditorPanel = ({
1682
+ host,
1683
+ model,
1497
1684
  actions,
1498
- options,
1499
- ...other
1685
+ editorOptions,
1686
+ onMount,
1687
+ selectedEmitter,
1688
+ compilerOptions,
1689
+ onCompilerOptionsChange,
1690
+ onSelectedEmitterChange,
1691
+ commandBar
1500
1692
  }) => {
1501
- const resolvedOptions = {
1502
- "semanticHighlighting.enabled": true,
1503
- automaticLayout: true,
1504
- tabSize: 2,
1505
- minimap: {
1506
- enabled: false
1507
- },
1508
- ...options
1509
- };
1510
- return /* @__PURE__ */ jsx(Editor, { actions, options: resolvedOptions, ...other });
1511
- };
1512
- const OutputEditor = ({ filename, value, editorOptions }) => {
1513
- const model = useMonacoModel(filename);
1514
- if (filename === "") {
1515
- return null;
1516
- }
1517
- const options = {
1518
- ...editorOptions,
1519
- readOnly: true,
1520
- automaticLayout: true,
1521
- minimap: {
1522
- enabled: false
1523
- }
1524
- };
1525
- model.setValue(value);
1526
- return /* @__PURE__ */ jsx(Editor, { model, options });
1693
+ const [selectedTab, setSelectedTab] = useState("tsp");
1694
+ const onTabSelect = useCallback((_, data) => {
1695
+ setSelectedTab(data.value);
1696
+ }, []);
1697
+ return /* @__PURE__ */ jsxs("div", { className: style$6["editor-panel"], children: [
1698
+ /* @__PURE__ */ jsx("div", { className: style$6["panel-tabs-container"], children: /* @__PURE__ */ jsxs(TabList, { vertical: true, size: "large", selectedValue: selectedTab, onTabSelect, children: [
1699
+ /* @__PURE__ */ jsx(Tab, { value: "tsp", children: /* @__PURE__ */ jsx("span", { title: "TypeSpec", children: /* @__PURE__ */ jsx(TypeSpecIcon, {}) }) }),
1700
+ /* @__PURE__ */ jsx(Tab, { value: "cfg", children: /* @__PURE__ */ jsx("span", { title: "Config", children: /* @__PURE__ */ jsx(SettingsRegular, {}) }) })
1701
+ ] }) }),
1702
+ /* @__PURE__ */ jsxs("div", { className: style$6["panel-content"], children: [
1703
+ commandBar,
1704
+ selectedTab === "tsp" ? /* @__PURE__ */ jsx(
1705
+ TypeSpecEditor,
1706
+ {
1707
+ model,
1708
+ actions,
1709
+ options: editorOptions,
1710
+ onMount
1711
+ }
1712
+ ) : /* @__PURE__ */ jsx(
1713
+ ConfigPanel,
1714
+ {
1715
+ host,
1716
+ selectedEmitter,
1717
+ compilerOptions,
1718
+ onCompilerOptionsChange,
1719
+ onSelectedEmitterChange,
1720
+ editorOptions
1721
+ }
1722
+ )
1723
+ ] })
1724
+ ] });
1527
1725
  };
1528
1726
 
1529
1727
  const style$5 = {
@@ -2165,35 +2363,36 @@ const Playground = (props) => {
2165
2363
  return /* @__PURE__ */ jsx(PlaygroundContextProvider, { value: playgroundContext, children: /* @__PURE__ */ jsxs("div", { className: style$2["layout"], children: [
2166
2364
  /* @__PURE__ */ jsxs(SplitPane, { sizes: verticalPaneSizes, onChange: onVerticalPaneSizeChange, split: "horizontal", children: [
2167
2365
  /* @__PURE__ */ jsx(Pane, { children: /* @__PURE__ */ jsxs(SplitPane, { initialSizes: ["50%", "50%"], children: [
2168
- /* @__PURE__ */ jsxs(Pane, { className: style$2["edit-pane"], children: [
2169
- /* @__PURE__ */ jsx(
2170
- EditorCommandBar,
2171
- {
2172
- host,
2173
- selectedEmitter,
2174
- onSelectedEmitterChange,
2175
- compilerOptions,
2176
- onCompilerOptionsChange,
2177
- samples: props.samples,
2178
- selectedSampleName,
2179
- onSelectedSampleNameChange,
2180
- saveCode,
2181
- formatCode,
2182
- fileBug: props.onFileBug ? fileBug : void 0,
2183
- commandBarButtons: props.commandBarButtons,
2184
- documentationUrl: props.links?.documentationUrl
2185
- }
2186
- ),
2187
- /* @__PURE__ */ jsx(
2188
- TypeSpecEditor,
2189
- {
2190
- model: typespecModel,
2191
- actions: typespecEditorActions,
2192
- options: props.editorOptions,
2193
- onMount: onTypeSpecEditorMount
2194
- }
2195
- )
2196
- ] }),
2366
+ /* @__PURE__ */ jsx(Pane, { className: style$2["edit-pane"], children: /* @__PURE__ */ jsx(
2367
+ EditorPanel,
2368
+ {
2369
+ host,
2370
+ model: typespecModel,
2371
+ actions: typespecEditorActions,
2372
+ editorOptions: props.editorOptions,
2373
+ onMount: onTypeSpecEditorMount,
2374
+ selectedEmitter,
2375
+ compilerOptions,
2376
+ onCompilerOptionsChange,
2377
+ onSelectedEmitterChange,
2378
+ commandBar: /* @__PURE__ */ jsx(
2379
+ EditorCommandBar,
2380
+ {
2381
+ host,
2382
+ selectedEmitter,
2383
+ onSelectedEmitterChange,
2384
+ samples: props.samples,
2385
+ selectedSampleName,
2386
+ onSelectedSampleNameChange,
2387
+ saveCode,
2388
+ formatCode,
2389
+ fileBug: props.onFileBug ? fileBug : void 0,
2390
+ commandBarButtons: props.commandBarButtons,
2391
+ documentationUrl: props.links?.documentationUrl
2392
+ }
2393
+ )
2394
+ }
2395
+ ) }),
2197
2396
  /* @__PURE__ */ jsx(Pane, { children: /* @__PURE__ */ jsx(
2198
2397
  OutputView,
2199
2398
  {
@@ -47,24 +47,32 @@ function resolveVirtualPath(path, ...paths) {
47
47
  function createBrowserHostInternal(options) {
48
48
  const virtualFs = /* @__PURE__ */ new Map();
49
49
  const jsImports = /* @__PURE__ */ new Map();
50
- const libraries = options.libraries;
51
- for (const [libName, { _TypeSpecLibrary_ }] of Object.entries(libraries)) {
52
- for (const [key, value] of Object.entries(_TypeSpecLibrary_.typespecSourceFiles)) {
50
+ const libraries = {
51
+ ...options.libraries
52
+ };
53
+ function registerLibraryFiles(libName, lib) {
54
+ for (const [key, value] of Object.entries(lib._TypeSpecLibrary_.typespecSourceFiles)) {
53
55
  virtualFs.set(`/test/node_modules/${libName}/${key}`, value);
54
56
  }
55
- for (const [key, value] of Object.entries(_TypeSpecLibrary_.jsSourceFiles)) {
57
+ for (const [key, value] of Object.entries(lib._TypeSpecLibrary_.jsSourceFiles)) {
56
58
  addJsImport(`/test/node_modules/${libName}/${key}`, value);
57
59
  }
58
60
  }
59
- virtualFs.set(
60
- `/test/package.json`,
61
- JSON.stringify({
62
- name: "playground-pkg",
63
- dependencies: Object.fromEntries(
64
- Object.values(libraries).map((x) => [x.name, x.packageJson.version])
65
- )
66
- })
67
- );
61
+ function updatePackageJson() {
62
+ virtualFs.set(
63
+ `/test/package.json`,
64
+ JSON.stringify({
65
+ name: "playground-pkg",
66
+ dependencies: Object.fromEntries(
67
+ Object.values(libraries).map((x) => [x.name, x.packageJson.version])
68
+ )
69
+ })
70
+ );
71
+ }
72
+ for (const [libName, lib] of Object.entries(libraries)) {
73
+ registerLibraryFiles(libName, lib);
74
+ }
75
+ updatePackageJson();
68
76
  function addJsImport(path, value) {
69
77
  virtualFs.set(path, "");
70
78
  jsImports.set(path, value);
@@ -174,24 +182,33 @@ function createBrowserHostInternal(options) {
174
182
  }
175
183
  };
176
184
  }
185
+ async function loadLibraries(libsToLoad, importOptions = {}) {
186
+ const entries = await Promise.all(
187
+ libsToLoad.map(async (libName) => {
188
+ const { _TypeSpecLibrary_, $lib, $linter } = await importLibrary(
189
+ libName,
190
+ importOptions
191
+ );
192
+ const lib = {
193
+ name: libName,
194
+ isEmitter: $lib?.emitter,
195
+ definition: $lib,
196
+ packageJson: JSON.parse(_TypeSpecLibrary_.typespecSourceFiles["package.json"]),
197
+ linter: $linter,
198
+ _TypeSpecLibrary_
199
+ };
200
+ return [libName, lib];
201
+ })
202
+ );
203
+ return Object.fromEntries(entries);
204
+ }
177
205
  async function createBrowserHost(libsToLoad, importOptions = {}) {
178
- const libraries = {};
179
- for (const libName of libsToLoad) {
180
- const { _TypeSpecLibrary_, $lib, $linter } = await importLibrary(
181
- libName,
182
- importOptions
183
- );
184
- libraries[libName] = {
185
- name: libName,
186
- isEmitter: $lib?.emitter,
187
- definition: $lib,
188
- packageJson: JSON.parse(_TypeSpecLibrary_.typespecSourceFiles["package.json"]),
189
- linter: $linter,
190
- _TypeSpecLibrary_
191
- };
192
- }
206
+ const [libraries, compiler] = await Promise.all([
207
+ loadLibraries(libsToLoad, importOptions),
208
+ importTypeSpecCompiler(importOptions)
209
+ ]);
193
210
  return createBrowserHostInternal({
194
- compiler: await importTypeSpecCompiler(importOptions),
211
+ compiler,
195
212
  libraries
196
213
  });
197
214
  }
@@ -1,6 +1,14 @@
1
1
  import { LibraryImportOptions } from './core.js';
2
- import { BrowserHost } from './types.js';
2
+ import { BrowserHost, PlaygroundTspLibrary } from './types.js';
3
3
  export declare function resolveVirtualPath(path: string, ...paths: string[]): string;
4
+ /**
5
+ * Load libraries in parallel from the given list.
6
+ * @param libsToLoad List of library names. Must be available in the webpage importmap.
7
+ * @param importOptions Import configuration.
8
+ */
9
+ export declare function loadLibraries(libsToLoad: readonly string[], importOptions?: LibraryImportOptions): Promise<Record<string, PlaygroundTspLibrary & {
10
+ _TypeSpecLibrary_: any;
11
+ }>>;
4
12
  /**
5
13
  * Create the browser host from the list of libraries.
6
14
  * @param libsToLoad List of libraries to load. Those must be set in the webpage importmap.
@@ -1 +1 @@
1
- {"version":3,"file":"browser-host.d.ts","sourceRoot":"","sources":["../../src/browser-host.ts"],"names":[],"mappings":"AACA,OAAO,EAAyC,KAAK,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAC7F,OAAO,KAAK,EAAE,WAAW,EAAwB,MAAM,YAAY,CAAC;AAEpE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,UAElE;AAsKD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,aAAa,GAAE,oBAAyB,GACvC,OAAO,CAAC,WAAW,CAAC,CAoBtB"}
1
+ {"version":3,"file":"browser-host.d.ts","sourceRoot":"","sources":["../../src/browser-host.ts"],"names":[],"mappings":"AACA,OAAO,EAAyC,KAAK,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAC7F,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEpE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,UAElE;AAmLD;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,aAAa,GAAE,oBAAyB,GACvC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,GAAG;IAAE,iBAAiB,EAAE,GAAG,CAAA;CAAE,CAAC,CAAC,CAmB5E;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,aAAa,GAAE,oBAAyB,GACvC,OAAO,CAAC,WAAW,CAAC,CAStB"}
@@ -1,4 +1,3 @@
1
- import { CompilerOptions } from '@typespec/compiler';
2
1
  import { FunctionComponent, ReactNode } from 'react';
3
2
  import { BrowserHost, PlaygroundSample } from '../types.js';
4
3
  export interface EditorCommandBarProps {
@@ -10,8 +9,6 @@ export interface EditorCommandBarProps {
10
9
  host: BrowserHost;
11
10
  selectedEmitter: string;
12
11
  onSelectedEmitterChange: (emitter: string) => void;
13
- compilerOptions: CompilerOptions;
14
- onCompilerOptionsChange: (options: CompilerOptions) => void;
15
12
  samples?: Record<string, PlaygroundSample>;
16
13
  selectedSampleName: string;
17
14
  onSelectedSampleNameChange: (sampleName: string) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"editor-command-bar.d.ts","sourceRoot":"","sources":["../../../src/editor-command-bar/editor-command-bar.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAW,KAAK,iBAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAIxE,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGjE,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACrC,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACrC,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,IAAI,EAAE,WAAW,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,uBAAuB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,eAAe,EAAE,eAAe,CAAC;IACjC,uBAAuB,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IAE5D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC3C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,0BAA0B,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1D;AACD,eAAO,MAAM,gBAAgB,EAAE,iBAAiB,CAAC,qBAAqB,CA0ErE,CAAC"}
1
+ {"version":3,"file":"editor-command-bar.d.ts","sourceRoot":"","sources":["../../../src/editor-command-bar/editor-command-bar.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAW,KAAK,iBAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGxE,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGjE,MAAM,WAAW,qBAAqB;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACrC,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACrC,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,IAAI,EAAE,WAAW,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,uBAAuB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAEnD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC3C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,0BAA0B,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1D;AACD,eAAO,MAAM,gBAAgB,EAAE,iBAAiB,CAAC,qBAAqB,CAmErE,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { CompilerOptions } from '@typespec/compiler';
2
+ import { FunctionComponent } from 'react';
3
+ import { BrowserHost } from '../../types.js';
4
+ import { PlaygroundEditorsOptions } from '../playground.js';
5
+ export interface ConfigPanelProps {
6
+ host: BrowserHost;
7
+ selectedEmitter: string;
8
+ compilerOptions: CompilerOptions;
9
+ onCompilerOptionsChange: (options: CompilerOptions) => void;
10
+ onSelectedEmitterChange: (emitter: string) => void;
11
+ editorOptions?: PlaygroundEditorsOptions;
12
+ }
13
+ export declare const ConfigPanel: FunctionComponent<ConfigPanelProps>;
14
+ //# sourceMappingURL=config-panel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-panel.d.ts","sourceRoot":"","sources":["../../../../src/react/editor-panel/config-panel.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAqD,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAClG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAKjE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,WAAW,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,eAAe,CAAC;IACjC,uBAAuB,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IAC5D,uBAAuB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,aAAa,CAAC,EAAE,wBAAwB,CAAC;CAC1C;AAID,eAAO,MAAM,WAAW,EAAE,iBAAiB,CAAC,gBAAgB,CA8F3D,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { CompilerOptions } from '@typespec/compiler';
2
+ import { editor } from 'monaco-editor';
3
+ import { FunctionComponent, ReactNode } from 'react';
4
+ import { BrowserHost } from '../../types.js';
5
+ import { OnMountData } from '../editor.js';
6
+ import { PlaygroundEditorsOptions } from '../playground.js';
7
+ export type EditorPanelTab = "tsp" | "cfg";
8
+ export interface EditorPanelProps {
9
+ host: BrowserHost;
10
+ model: editor.IModel;
11
+ actions?: editor.IActionDescriptor[];
12
+ editorOptions?: PlaygroundEditorsOptions;
13
+ onMount?: (data: OnMountData) => void;
14
+ selectedEmitter: string;
15
+ compilerOptions: CompilerOptions;
16
+ onCompilerOptionsChange: (options: CompilerOptions) => void;
17
+ onSelectedEmitterChange: (emitter: string) => void;
18
+ /** Toolbar content rendered above the editor area */
19
+ commandBar?: ReactNode;
20
+ }
21
+ export declare const EditorPanel: FunctionComponent<EditorPanelProps>;
22
+ //# sourceMappingURL=editor-panel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-panel.d.ts","sourceRoot":"","sources":["../../../../src/react/editor-panel/editor-panel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAyB,KAAK,iBAAiB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACtF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAKjE,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,KAAK,CAAC;AAkB3C,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,iBAAiB,EAAE,CAAC;IACrC,aAAa,CAAC,EAAE,wBAAwB,CAAC;IACzC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IAEtC,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,eAAe,CAAC;IACjC,uBAAuB,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IAC5D,uBAAuB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAEnD,qDAAqD;IACrD,UAAU,CAAC,EAAE,SAAS,CAAC;CACxB;AAED,eAAO,MAAM,WAAW,EAAE,iBAAiB,CAAC,gBAAgB,CAwD3D,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { ConfigPanel, type ConfigPanelProps } from './config-panel.js';
2
+ export { EditorPanel, type EditorPanelProps, type EditorPanelTab } from './editor-panel.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/react/editor-panel/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { CompilerOptions, LinterRuleSet } from '@typespec/compiler';
2
+ export interface TspConfig {
3
+ emit?: string[];
4
+ options?: Record<string, Record<string, unknown>>;
5
+ linter?: LinterRuleSet;
6
+ imports?: string[];
7
+ trace?: string | string[];
8
+ "warn-as-error"?: boolean;
9
+ "output-dir"?: string;
10
+ }
11
+ /**
12
+ * Serialize the current playground state (emitter + compiler options) to tspconfig.yaml content.
13
+ */
14
+ export declare function compilerOptionsToTspConfig(selectedEmitter: string, compilerOptions: CompilerOptions): string;
15
+ export interface ParsedTspConfig {
16
+ selectedEmitter?: string;
17
+ compilerOptions: CompilerOptions;
18
+ }
19
+ /**
20
+ * Parse tspconfig.yaml content back to playground state.
21
+ * Returns undefined if the YAML is invalid.
22
+ */
23
+ export declare function parseTspConfigYaml(yamlContent: string): ParsedTspConfig | undefined;
24
+ //# sourceMappingURL=tspconfig-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tspconfig-utils.d.ts","sourceRoot":"","sources":["../../../../src/react/editor-panel/tspconfig-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGzE,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAClD,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,eAAe,GAC/B,MAAM,CAgBR;AAED,MAAM,WAAW,eAAe;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,eAAe,CAAC;CAClC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAuBnF"}
@@ -1 +1 @@
1
- {"version":3,"file":"playground.d.ts","sourceRoot":"","sources":["../../../src/react/playground.tsx"],"names":[],"mappings":"AAGA,OAAO,sCAAsC,CAAC;AAG9C,OAAO,EAML,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAKf,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAQjE,OAAO,KAAK,EAAoB,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEpF,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAGrF,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,WAAW,CAAC;IAElB,iDAAiD;IACjD,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,kCAAkC;IAClC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAEtC,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAE3C,oCAAoC;IACpC,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,yDAAyD;IACzD,sBAAsB,CAAC,EAAE,eAAe,CAAC;IACzC,6CAA6C;IAC7C,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAE3D;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IAEvB,uDAAuD;IACvD,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAE9B,uBAAuB;IACvB,KAAK,CAAC,EAAE,eAAe,CAAC;IAExB,kDAAkD;IAClD,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAE1B,4FAA4F;IAC5F,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAEpD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAE7C,aAAa,CAAC,EAAE,wBAAwB,CAAC;IAEzC;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IACzD,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAEhB,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,4BAA4B;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,eAAO,MAAM,UAAU,EAAE,iBAAiB,CAAC,eAAe,CAqPzD,CAAC"}
1
+ {"version":3,"file":"playground.d.ts","sourceRoot":"","sources":["../../../src/react/playground.tsx"],"names":[],"mappings":"AAGA,OAAO,sCAAsC,CAAC;AAG9C,OAAO,EAML,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAKf,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AASjE,OAAO,KAAK,EAAoB,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACpF,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAGrF,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,WAAW,CAAC;IAElB,iDAAiD;IACjD,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,kCAAkC;IAClC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAEtC,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAE3C,oCAAoC;IACpC,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,yDAAyD;IACzD,sBAAsB,CAAC,EAAE,eAAe,CAAC;IACzC,6CAA6C;IAC7C,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IAE3D;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IAEvB,uDAAuD;IACvD,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAE9B,uBAAuB;IACvB,KAAK,CAAC,EAAE,eAAe,CAAC;IAExB,kDAAkD;IAClD,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAE1B,4FAA4F;IAC5F,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAEpD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAE7C,aAAa,CAAC,EAAE,wBAAwB,CAAC;IAEzC;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IACzD,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAEhB,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,4BAA4B;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,eAAO,MAAM,UAAU,EAAE,iBAAiB,CAAC,eAAe,CA0PzD,CAAC"}
@@ -4,6 +4,7 @@ import { BrowserHost } from '../../types.js';
4
4
  export interface CompilerSettingsProps {
5
5
  readonly host: BrowserHost;
6
6
  readonly selectedEmitter: string;
7
+ readonly onSelectedEmitterChange: (emitter: string) => void;
7
8
  readonly options: CompilerOptions;
8
9
  readonly onOptionsChanged: (options: CompilerOptions) => void;
9
10
  }
@@ -1 +1 @@
1
- {"version":3,"file":"compiler-settings.d.ts","sourceRoot":"","sources":["../../../../src/react/settings/compiler-settings.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAe,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAKlD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,gBAAgB,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;CAC/D;AAED,eAAO,MAAM,gBAAgB,EAAE,iBAAiB,CAAC,qBAAqB,CA+CrE,CAAC"}
1
+ {"version":3,"file":"compiler-settings.d.ts","sourceRoot":"","sources":["../../../../src/react/settings/compiler-settings.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAwB,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAMlD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,uBAAuB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5D,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,gBAAgB,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;CAC/D;AAED,eAAO,MAAM,gBAAgB,EAAE,iBAAiB,CAAC,qBAAqB,CAuFrE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"emitter-options-form.d.ts","sourceRoot":"","sources":["../../../../src/react/settings/emitter-options-form.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAkC,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC/E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;CAC5D;AAED,eAAO,MAAM,kBAAkB,EAAE,iBAAiB,CAAC,uBAAuB,CAiDzE,CAAC"}
1
+ {"version":3,"file":"emitter-options-form.d.ts","sourceRoot":"","sources":["../../../../src/react/settings/emitter-options-form.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAkC,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC/E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;CAC5D;AAED,eAAO,MAAM,kBAAkB,EAAE,iBAAiB,CAAC,uBAAuB,CAiDzE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"linter-form.d.ts","sourceRoot":"","sources":["../../../../src/react/settings/linter-form.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAW,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAe,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE3D,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAChD,aAAa,EAAE,aAAa,CAAC;IAC7B,sBAAsB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;CAC1D;AAED,eAAO,MAAM,UAAU,EAAE,iBAAiB,CAAC,eAAe,CAsCzD,CAAC"}
1
+ {"version":3,"file":"linter-form.d.ts","sourceRoot":"","sources":["../../../../src/react/settings/linter-form.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAW,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAe,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE3D,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAChD,aAAa,EAAE,aAAa,CAAC;IAC7B,sBAAsB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,CAAC;CAC1D;AAED,eAAO,MAAM,UAAU,EAAE,iBAAiB,CAAC,eAAe,CA0CzD,CAAC"}
package/dist/style.css CHANGED
@@ -251,31 +251,112 @@
251
251
  margin: 0;
252
252
  line-height: 1.4;
253
253
  }
254
- ._form_sqeas_1 {
254
+ ._bar_15c2c_1 {
255
+ border-bottom: 1px solid var(--colorNeutralStroke1);
256
+ }
257
+
258
+ ._divider_15c2c_5 {
259
+ flex: 1;
260
+ }
261
+
262
+ ._spacer_15c2c_9 {
263
+ width: 10px;
264
+ }
265
+ ._settings_1yvpj_1 {
255
266
  display: flex;
256
267
  flex-direction: column;
257
- gap: 20px;
268
+ gap: 4px;
258
269
  }
259
270
 
260
- ._item_sqeas_7 {
271
+ ._section_1yvpj_7 {
261
272
  display: flex;
262
273
  flex-direction: column;
263
- gap: 10px;
274
+ gap: 12px;
275
+ padding: 12px 0;
276
+ border-bottom: 1px solid var(--colorNeutralStroke2);
277
+ }
278
+
279
+ ._section_1yvpj_7:last-child {
280
+ border-bottom: none;
281
+ }
282
+
283
+ ._section-title_1yvpj_19 {
284
+ margin: 0;
264
285
  }
265
286
 
266
- ._switch_sqeas_13 label {
287
+ ._field_1yvpj_23 {
288
+ display: flex;
289
+ flex-direction: column;
290
+ gap: 4px;
291
+ }
292
+
293
+ ._section-subtitle_1yvpj_29 {
294
+ color: var(--colorNeutralForeground3);
295
+ }
296
+
297
+ ._empty_1yvpj_33 {
298
+ color: var(--colorNeutralForeground3);
299
+ font-style: italic;
300
+ }
301
+ ._form_w9o1o_1 {
302
+ display: flex;
303
+ flex-direction: column;
304
+ gap: 16px;
305
+ }
306
+
307
+ ._item_w9o1o_7 {
308
+ display: flex;
309
+ flex-direction: column;
310
+ gap: 4px;
311
+ }
312
+
313
+ ._description_w9o1o_13 {
314
+ color: var(--colorNeutralForeground3);
315
+ }
316
+
317
+ ._switch_w9o1o_17 label {
267
318
  padding-left: 0;
268
319
  }
269
- ._bar_15c2c_1 {
320
+ ._config-panel_cffut_1 {
321
+ display: flex;
322
+ flex-direction: column;
323
+ height: 100%;
324
+ overflow: hidden;
325
+ }
326
+
327
+ ._config-toggle_cffut_8 {
328
+ display: flex;
329
+ align-items: center;
330
+ padding: 4px 8px;
270
331
  border-bottom: 1px solid var(--colorNeutralStroke1);
332
+ gap: 8px;
333
+ flex-shrink: 0;
271
334
  }
272
335
 
273
- ._divider_15c2c_5 {
336
+ ._config-content_cffut_17 {
274
337
  flex: 1;
338
+ min-height: 0;
339
+ overflow: auto;
275
340
  }
276
341
 
277
- ._spacer_15c2c_9 {
278
- width: 10px;
342
+ ._form-content_cffut_23 {
343
+ padding: 12px;
344
+ }
345
+ ._editor-panel_k9ax7_1 {
346
+ display: flex;
347
+ flex-direction: row;
348
+ height: 100%;
349
+ }
350
+
351
+ ._panel-tabs-container_k9ax7_7 {
352
+ background-color: var(--colorNeutralBackground3);
353
+ }
354
+
355
+ ._panel-content_k9ax7_11 {
356
+ flex: 1;
357
+ min-width: 0;
358
+ display: flex;
359
+ flex-direction: column;
279
360
  }
280
361
  ._file-output_jzw6j_1 {
281
362
  position: relative;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typespec/playground",
3
- "version": "0.13.0-dev.2",
3
+ "version": "0.13.0-dev.4",
4
4
  "author": "Microsoft Corporation",
5
5
  "description": "TypeSpec playground UI components.",
6
6
  "homepage": "https://typespec.io",
@@ -62,11 +62,11 @@
62
62
  "@fluentui/react-components": "~9.73.1",
63
63
  "@fluentui/react-icons": "^2.0.292",
64
64
  "@typespec/bundler": "^0.5.0 || >= 0.5.1-dev.1",
65
- "@typespec/compiler": "^1.9.0 || >= 1.10.0-dev.7",
65
+ "@typespec/compiler": "^1.9.0 || >= 1.10.0-dev.8",
66
66
  "@typespec/html-program-viewer": "^0.79.0 || >= 0.80.0-dev.2",
67
67
  "@typespec/http": "^1.9.1 || >= 1.10.0-dev.3",
68
- "@typespec/openapi": "^1.9.0 || >= 1.10.0-dev.3",
69
- "@typespec/openapi3": "^1.9.0 || >= 1.10.0-dev.5",
68
+ "@typespec/openapi": "^1.9.0 || >= 1.10.0-dev.4",
69
+ "@typespec/openapi3": "^1.9.0 || >= 1.10.0-dev.6",
70
70
  "@typespec/protobuf": "^0.79.0 || >= 0.80.0-dev.2",
71
71
  "@typespec/rest": "^0.79.0 || >= 0.80.0-dev.2",
72
72
  "@typespec/versioning": "^0.79.0 || >= 0.80.0-dev.2",
@@ -78,6 +78,7 @@
78
78
  "react-dom": "~19.2.3",
79
79
  "react-error-boundary": "^6.0.0",
80
80
  "swagger-ui-dist": "^5.20.1",
81
+ "yaml": "~2.8.2",
81
82
  "vscode-languageserver": "~9.0.1",
82
83
  "vscode-languageserver-textdocument": "~1.0.12"
83
84
  },
@@ -1,8 +0,0 @@
1
- import { CompilerOptions } from '@typespec/compiler';
2
- export interface CompilerSettingsDialogButtonProps {
3
- selectedEmitter: string;
4
- compilerOptions: CompilerOptions;
5
- onCompilerOptionsChange: (options: CompilerOptions) => void;
6
- }
7
- export declare const CompilerSettingsDialogButton: ({ selectedEmitter, compilerOptions, onCompilerOptionsChange, }: CompilerSettingsDialogButtonProps) => import("react/jsx-runtime").JSX.Element;
8
- //# sourceMappingURL=compiler-settings-dialog-button.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"compiler-settings-dialog-button.d.ts","sourceRoot":"","sources":["../../../../src/react/settings/compiler-settings-dialog-button.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAI1D,MAAM,WAAW,iCAAiC;IAChD,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,eAAe,CAAC;IACjC,uBAAuB,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;CAC7D;AAED,eAAO,MAAM,4BAA4B,GAAI,gEAI1C,iCAAiC,4CAuBnC,CAAC"}