@typespec/playground 0.13.1-dev.0 → 0.14.0-dev.1

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.
@@ -1,10 +1,10 @@
1
- import require$$0, { createContext, useContext, memo, useCallback, useRef, useEffect, useMemo, useState, useId as useId$1 } from 'react';
1
+ import require$$0, { createContext, useContext, memo, useCallback, useRef, useEffect, useMemo, useState, useId } 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, Toolbar, Link, useId, Label, Checkbox, RadioGroup, Radio, Input, Switch, Subtitle2, 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 as useId$1, 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, Save16Regular, Broom16Filled, Bug16Regular, SettingsRegular, FolderListRegular, DataLineRegular, ErrorCircle16Filled, Warning16Filled, ChevronDown16Regular } from '@fluentui/react-icons';
7
+ import { ChevronDownRegular, ChevronRightRegular, DocumentBulletList24Regular, Dismiss24Regular, Save16Regular, Broom16Filled, Bug16Regular, SettingsRegular, FolderRegular, DocumentRegular, FolderListRegular, DataLineRegular, ErrorCircle16Filled, Warning16Filled, ChevronDown16Regular } from '@fluentui/react-icons';
8
8
  import debounce from 'debounce';
9
9
  import { CompletionItemTag } from 'vscode-languageserver';
10
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';
@@ -27,7 +27,7 @@ function usePlaygroundContext() {
27
27
 
28
28
  const list = "_list_wrnwm_1";
29
29
  const item$1 = "_item_wrnwm_4";
30
- const style$e = {
30
+ const style$h = {
31
31
  list: list,
32
32
  item: item$1,
33
33
  "item--error": "_item--error_wrnwm_15",
@@ -47,9 +47,9 @@ const DiagnosticList = ({
47
47
  [onDiagnosticSelected]
48
48
  );
49
49
  if (diagnostics.length === 0) {
50
- return /* @__PURE__ */ jsx("div", { className: style$e["list"], children: "No errors" });
50
+ return /* @__PURE__ */ jsx("div", { className: style$h["list"], children: "No errors" });
51
51
  }
52
- return /* @__PURE__ */ jsx("div", { className: style$e["list"], children: diagnostics.map((x, i) => {
52
+ return /* @__PURE__ */ jsx("div", { className: style$h["list"], children: diagnostics.map((x, i) => {
53
53
  return /* @__PURE__ */ jsx(DiagnosticItem, { diagnostic: x, onItemSelected: handleItemSelected }, i);
54
54
  }) });
55
55
  };
@@ -57,19 +57,19 @@ const DiagnosticItem = ({ diagnostic, onItemSelected }) => {
57
57
  const handleClick = useCallback(() => {
58
58
  onItemSelected(diagnostic);
59
59
  }, [diagnostic, onItemSelected]);
60
- return /* @__PURE__ */ jsxs("div", { tabIndex: 0, className: style$e["item"], onClick: handleClick, children: [
60
+ return /* @__PURE__ */ jsxs("div", { tabIndex: 0, className: style$h["item"], onClick: handleClick, children: [
61
61
  /* @__PURE__ */ jsx(
62
62
  "div",
63
63
  {
64
64
  className: mergeClasses(
65
- (style$e[diagnostic.severity === "error" ? "item--error" : "item--warning"])
65
+ (style$h[diagnostic.severity === "error" ? "item--error" : "item--warning"])
66
66
  ),
67
67
  children: diagnostic.severity
68
68
  }
69
69
  ),
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 }) })
70
+ /* @__PURE__ */ jsx("div", { className: style$h["item-code"], children: diagnostic.code }),
71
+ /* @__PURE__ */ jsx("div", { className: style$h["item-message"], children: diagnostic.message }),
72
+ /* @__PURE__ */ jsx("div", { className: style$h["item-loc"], children: /* @__PURE__ */ jsx(DiagnosticTargetLink, { target: diagnostic.target }) })
73
73
  ] });
74
74
  };
75
75
  const DiagnosticTargetLink = memo(({ target }) => {
@@ -134,18 +134,18 @@ function useMonacoModel(uri, language) {
134
134
  }
135
135
 
136
136
  const footer = "_footer_e6dic_1";
137
- const style$d = {
137
+ const style$g = {
138
138
  footer: footer,
139
139
  "footer-item": "_footer-item_e6dic_9"
140
140
  };
141
141
 
142
142
  const FooterItem = ({ children, link, className }) => {
143
- const resolvedClassName = mergeClasses(style$d["footer-item"], className);
143
+ const resolvedClassName = mergeClasses(style$g["footer-item"], className);
144
144
  return link ? /* @__PURE__ */ jsx("a", { className: resolvedClassName, href: link, target: "_blank", rel: "noopener noreferrer", children }) : /* @__PURE__ */ jsx("div", { className: resolvedClassName, children });
145
145
  };
146
146
 
147
147
  const button = "_button_1c15n_4";
148
- const style$c = {
148
+ const style$f = {
149
149
  "version-item": "_version-item_1c15n_1",
150
150
  button: button
151
151
  };
@@ -154,8 +154,8 @@ const FooterVersionItem = memo(({ versionSelector }) => {
154
154
  const { host } = usePlaygroundContext();
155
155
  const latest = versionSelector?.latest;
156
156
  const selected = versionSelector?.selected ?? host.compiler.MANIFEST.version;
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: [
157
+ return /* @__PURE__ */ jsx(FooterItem, { className: style$f["version-item"], children: /* @__PURE__ */ jsxs(Popover, { children: [
158
+ /* @__PURE__ */ jsx(PopoverTrigger, { disableButtonEnhancement: true, children: /* @__PURE__ */ jsxs("div", { className: style$f["button"], children: [
159
159
  /* @__PURE__ */ jsx("span", { children: "Version " }),
160
160
  /* @__PURE__ */ jsx("span", { children: selected }),
161
161
  /* @__PURE__ */ jsx("span", { children: latest ? latest === selected ? " (latest)" : " (old)" : "" })
@@ -201,7 +201,7 @@ const VersionSelector = memo(({ versions, selected, latest, onChange }) => {
201
201
  });
202
202
 
203
203
  const Footer = ({ className, children }) => {
204
- return /* @__PURE__ */ jsx("div", { className: mergeClasses(style$d.footer, className), children });
204
+ return /* @__PURE__ */ jsx("div", { className: mergeClasses(style$g.footer, className), children });
205
205
  };
206
206
 
207
207
  function useControllableValue(controlledValue, defaultUncontrolledValue, onChange) {
@@ -960,6 +960,258 @@ function assertsSize(size, sum, defaultValue = Infinity) {
960
960
  return defaultValue;
961
961
  }
962
962
 
963
+ function useTreeControls({ onSetExpanded }) {
964
+ const expanded = useRef(/* @__PURE__ */ new Set()).current;
965
+ const [rerender, setRerender] = useState(0);
966
+ const toggleExpand = useCallback(
967
+ (key) => {
968
+ if (expanded.has(key)) {
969
+ expanded.delete(key);
970
+ } else {
971
+ expanded.add(key);
972
+ }
973
+ onSetExpanded?.(expanded);
974
+ setRerender((x) => x + 1);
975
+ },
976
+ [expanded]
977
+ );
978
+ const expand = useCallback(
979
+ (key) => {
980
+ if (expanded.has(key)) {
981
+ return;
982
+ }
983
+ expanded.add(key);
984
+ onSetExpanded?.(expanded);
985
+ setRerender((x) => x + 1);
986
+ },
987
+ [expanded]
988
+ );
989
+ const collapse = useCallback(
990
+ (key) => {
991
+ if (!expanded.has(key)) {
992
+ return;
993
+ }
994
+ expanded.delete(key);
995
+ onSetExpanded?.(expanded);
996
+ setRerender((x) => x + 1);
997
+ },
998
+ [expanded]
999
+ );
1000
+ return useMemo(
1001
+ () => ({ expanded: new Set(expanded), toggleExpand, expand, collapse }),
1002
+ [expanded, toggleExpand, expand, collapse, expanded, rerender]
1003
+ );
1004
+ }
1005
+
1006
+ const tree = "_tree_16t0l_1";
1007
+ const focus = "_focus_16t0l_18";
1008
+ const active = "_active_16t0l_22";
1009
+ const caret = "_caret_16t0l_26";
1010
+ const icon = "_icon_16t0l_33";
1011
+ const style$e = {
1012
+ tree: tree,
1013
+ "tree-row": "_tree-row_16t0l_4",
1014
+ focus: focus,
1015
+ active: active,
1016
+ caret: caret,
1017
+ icon: icon};
1018
+
1019
+ const INDENT_SIZE = 8;
1020
+ function TreeViewRow({ id, row, active, focussed, activate, icon: Icon }) {
1021
+ const paddingLeft = row.depth * INDENT_SIZE;
1022
+ const onClick = useCallback(() => activate(row), [activate, row]);
1023
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
1024
+ "div",
1025
+ {
1026
+ id,
1027
+ role: "treeitem",
1028
+ style: { paddingLeft },
1029
+ className: mergeClasses(
1030
+ style$e["tree-row"],
1031
+ active && style$e["active"],
1032
+ focussed && style$e["focus"]
1033
+ ),
1034
+ "aria-selected": active,
1035
+ "aria-expanded": row.expanded,
1036
+ "aria-posinset": row.localIndex,
1037
+ "aria-level": row.depth,
1038
+ onClick,
1039
+ children: [
1040
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: style$e["caret"], children: /* @__PURE__ */ jsxRuntimeExports.jsx(Caret, { row }) }),
1041
+ Icon && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: style$e["icon"], children: /* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { node: row.item }) }),
1042
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "label", title: row.item.name, children: row.item.name })
1043
+ ]
1044
+ }
1045
+ );
1046
+ }
1047
+ const Caret = ({ row }) => {
1048
+ const toggleExpand = useCallback(
1049
+ (evt) => {
1050
+ evt.stopPropagation();
1051
+ row.toggleExpand();
1052
+ },
1053
+ [row]
1054
+ );
1055
+ if (row.hasChildren) {
1056
+ return row.expanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDownRegular, { onClick: toggleExpand }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRightRegular, { onClick: toggleExpand });
1057
+ } else {
1058
+ return null;
1059
+ }
1060
+ };
1061
+
1062
+ function Tree({
1063
+ tree,
1064
+ selected,
1065
+ onSelect,
1066
+ onSetExpanded,
1067
+ nodeIcon,
1068
+ selectionMode = "none"
1069
+ }) {
1070
+ const id = useId();
1071
+ const { expanded, toggleExpand, expand, collapse } = useTreeControls({
1072
+ onSetExpanded
1073
+ });
1074
+ const [focusedIndex, setFocusedIndex] = useState(-1);
1075
+ const [selectedKey, setSelectedKey] = useControllableValue(selected, void 0, onSelect);
1076
+ const rows = useMemo(
1077
+ () => getTreeRowsForNode(expanded, toggleExpand, tree),
1078
+ [expanded, toggleExpand, tree]
1079
+ );
1080
+ const parentMap = useMemo(() => computeParent(tree), [tree]);
1081
+ useEffect(() => {
1082
+ expand(selectedKey);
1083
+ let current = parentMap.get(selectedKey);
1084
+ while (current) {
1085
+ expand(current);
1086
+ current = parentMap.get(current);
1087
+ }
1088
+ }, [expand, selectedKey, parentMap]);
1089
+ const activateRow = useCallback(
1090
+ (row) => {
1091
+ setFocusedIndex(row.index);
1092
+ if (row.hasChildren) {
1093
+ toggleExpand(row.id);
1094
+ if (selectionMode === "single") {
1095
+ setSelectedKey(row.id);
1096
+ }
1097
+ } else if (selectionMode === "none" || selectedKey === row.id) {
1098
+ toggleExpand(row.id);
1099
+ } else {
1100
+ expand(row.id);
1101
+ if (selectionMode === "single") {
1102
+ setSelectedKey(row.id);
1103
+ }
1104
+ }
1105
+ },
1106
+ [selectionMode, selectedKey, toggleExpand, expand, setSelectedKey]
1107
+ );
1108
+ const handleKeyDown = useCallback(
1109
+ (event) => {
1110
+ const curTreeRow = rows[focusedIndex];
1111
+ switch (event.code) {
1112
+ case "ArrowDown":
1113
+ setFocusedIndex((focusedIndex + 1) % rows.length);
1114
+ event.preventDefault();
1115
+ break;
1116
+ case "ArrowUp":
1117
+ setFocusedIndex((focusedIndex - 1) % rows.length);
1118
+ event.preventDefault();
1119
+ break;
1120
+ case "ArrowRight":
1121
+ expand(curTreeRow.id);
1122
+ event.preventDefault();
1123
+ break;
1124
+ case "ArrowLeft":
1125
+ collapse(curTreeRow.id);
1126
+ event.preventDefault();
1127
+ break;
1128
+ case "Space":
1129
+ case "Enter":
1130
+ activateRow(curTreeRow);
1131
+ event.preventDefault();
1132
+ return;
1133
+ }
1134
+ },
1135
+ [setFocusedIndex, focusedIndex, rows, activateRow, expand, collapse]
1136
+ );
1137
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
1138
+ "div",
1139
+ {
1140
+ id,
1141
+ className: style$e["tree"],
1142
+ tabIndex: 0,
1143
+ role: "tree",
1144
+ onKeyDown: handleKeyDown,
1145
+ onFocus: () => {
1146
+ const row = rows.findIndex((row2) => row2.id === selectedKey);
1147
+ setFocusedIndex(row === -1 ? 0 : row);
1148
+ },
1149
+ onBlur: () => setFocusedIndex(-1),
1150
+ "aria-activedescendant": `${id}-${focusedIndex}`,
1151
+ children: rows.map((row) => {
1152
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
1153
+ TreeViewRow,
1154
+ {
1155
+ id: `${id}-${row.index}`,
1156
+ icon: nodeIcon,
1157
+ focussed: focusedIndex === row.index,
1158
+ row,
1159
+ active: selectionMode === "single" && row.id === selectedKey,
1160
+ activate: activateRow
1161
+ },
1162
+ row.id
1163
+ );
1164
+ })
1165
+ }
1166
+ );
1167
+ }
1168
+ function getTreeRowsForNode(expandedItems, toggleExpand, node, depth = 0) {
1169
+ const rows = [];
1170
+ if (!node.children) {
1171
+ return [];
1172
+ }
1173
+ for (const [index, child] of node.children.entries()) {
1174
+ const hasChildren = child.hasMore || Boolean(child.children && child.children.length > 0);
1175
+ const id = child.id;
1176
+ const expanded = expandedItems.has(id);
1177
+ rows.push({
1178
+ id,
1179
+ index: -1,
1180
+ item: child,
1181
+ expanded,
1182
+ depth,
1183
+ hasChildren,
1184
+ localIndex: index,
1185
+ toggleExpand: () => {
1186
+ toggleExpand(id);
1187
+ }
1188
+ });
1189
+ if (hasChildren && expanded) {
1190
+ for (const row of getTreeRowsForNode(expandedItems, toggleExpand, child, depth + 1)) {
1191
+ rows.push(row);
1192
+ }
1193
+ }
1194
+ for (let i = 0; i < rows.length; i++) {
1195
+ rows[i].index = i;
1196
+ }
1197
+ }
1198
+ return rows;
1199
+ }
1200
+ function computeParent(node) {
1201
+ const map = /* @__PURE__ */ new Map();
1202
+ const queue = [node];
1203
+ let current;
1204
+ while (current = queue.pop()) {
1205
+ if (current.children) {
1206
+ for (const child of current.children) {
1207
+ map.set(child.id, current.id);
1208
+ queue.push(child);
1209
+ }
1210
+ }
1211
+ }
1212
+ return map;
1213
+ }
1214
+
963
1215
  const EmitterDropdown = ({
964
1216
  emitters,
965
1217
  onSelectedEmitterChange,
@@ -989,7 +1241,7 @@ const EmitterDropdown = ({
989
1241
  );
990
1242
  };
991
1243
 
992
- const style$b = {
1244
+ const style$d = {
993
1245
  "samples-grid": "_samples-grid_1dkte_1",
994
1246
  "sample-card": "_sample-card_1dkte_8",
995
1247
  "sample-card-content": "_sample-card-content_1dkte_26",
@@ -1076,9 +1328,9 @@ const SampleIcon = ({ name }) => {
1076
1328
  );
1077
1329
  }
1078
1330
  };
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 })
1331
+ return /* @__PURE__ */ jsxs("div", { className: style$d["sample-icon"], style: { backgroundColor: colors.bg }, "aria-hidden": "true", children: [
1332
+ /* @__PURE__ */ jsx("svg", { width: "48", height: "48", viewBox: "0 0 48 48", className: style$d["sample-icon-pattern"], children: renderPattern() }),
1333
+ /* @__PURE__ */ jsx("span", { className: style$d["sample-icon-initials"], style: { color: colors.fg }, children: initials })
1082
1334
  ] });
1083
1335
  };
1084
1336
 
@@ -1086,7 +1338,7 @@ const SampleCard = ({ name, sample, onSelect }) => {
1086
1338
  return /* @__PURE__ */ jsx(
1087
1339
  Card,
1088
1340
  {
1089
- className: style$b["sample-card"],
1341
+ className: style$d["sample-card"],
1090
1342
  onClick: () => onSelect(name),
1091
1343
  role: "button",
1092
1344
  tabIndex: 0,
@@ -1096,11 +1348,11 @@ const SampleCard = ({ name, sample, onSelect }) => {
1096
1348
  onSelect(name);
1097
1349
  }
1098
1350
  },
1099
- children: /* @__PURE__ */ jsxs("div", { className: style$b["sample-card-content"], children: [
1351
+ children: /* @__PURE__ */ jsxs("div", { className: style$d["sample-card-content"], children: [
1100
1352
  /* @__PURE__ */ jsx(SampleIcon, { name }),
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 })
1353
+ /* @__PURE__ */ jsxs("div", { className: style$d["sample-card-text"], children: [
1354
+ /* @__PURE__ */ jsx(Text, { as: "h3", weight: "semibold", className: style$d["sample-title"], children: name }),
1355
+ sample.description && /* @__PURE__ */ jsx(Text, { as: "p", className: style$d["sample-description"], children: sample.description })
1104
1356
  ] })
1105
1357
  ] })
1106
1358
  }
@@ -1152,7 +1404,7 @@ const SamplesDrawerTrigger = ({
1152
1404
  children: "Sample Gallery"
1153
1405
  }
1154
1406
  ) }),
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)) }) })
1407
+ /* @__PURE__ */ jsx(DrawerBody, { children: /* @__PURE__ */ jsx("div", { className: style$d["samples-grid"], children: Object.entries(samples).map(([name, sample]) => /* @__PURE__ */ jsx(SampleCard, { name, sample, onSelect: handleSampleSelect }, name)) }) })
1156
1408
  ]
1157
1409
  }
1158
1410
  )
@@ -1162,7 +1414,7 @@ const SamplesDrawerTrigger = ({
1162
1414
  const bar = "_bar_15c2c_1";
1163
1415
  const divider = "_divider_15c2c_5";
1164
1416
  const spacer = "_spacer_15c2c_9";
1165
- const style$a = {
1417
+ const style$c = {
1166
1418
  bar: bar,
1167
1419
  divider: divider,
1168
1420
  spacer: spacer
@@ -1187,7 +1439,7 @@ const EditorCommandBar = ({
1187
1439
  () => Object.values(host.libraries).filter((x) => x.isEmitter).map((x) => x.name),
1188
1440
  [host.libraries]
1189
1441
  );
1190
- return /* @__PURE__ */ jsx("div", { className: style$a["bar"], children: /* @__PURE__ */ jsxs(Toolbar, { children: [
1442
+ return /* @__PURE__ */ jsx("div", { className: style$c["bar"], children: /* @__PURE__ */ jsxs(Toolbar, { children: [
1191
1443
  /* @__PURE__ */ jsx(Tooltip, { content: "Save", relationship: "description", withArrow: true, children: /* @__PURE__ */ jsx(ToolbarButton, { "aria-label": "Save", icon: /* @__PURE__ */ jsx(Save16Regular, {}), onClick: saveCode }) }),
1192
1444
  /* @__PURE__ */ jsx(Tooltip, { content: "Format", relationship: "description", withArrow: true, children: /* @__PURE__ */ jsx(ToolbarButton, { "aria-label": "Format", icon: /* @__PURE__ */ jsx(Broom16Filled, {}), onClick: formatCode }) }),
1193
1445
  samples && /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -1198,7 +1450,7 @@ const EditorCommandBar = ({
1198
1450
  onSelectedSampleNameChange
1199
1451
  }
1200
1452
  ),
1201
- /* @__PURE__ */ jsx("div", { className: style$a["spacer"] })
1453
+ /* @__PURE__ */ jsx("div", { className: style$c["spacer"] })
1202
1454
  ] }),
1203
1455
  /* @__PURE__ */ jsx(
1204
1456
  EmitterDropdown,
@@ -1209,10 +1461,10 @@ const EditorCommandBar = ({
1209
1461
  }
1210
1462
  ),
1211
1463
  documentation && /* @__PURE__ */ jsxs(Fragment, { children: [
1212
- /* @__PURE__ */ jsx("div", { className: style$a["spacer"] }),
1464
+ /* @__PURE__ */ jsx("div", { className: style$c["spacer"] }),
1213
1465
  documentation
1214
1466
  ] }),
1215
- /* @__PURE__ */ jsx("div", { className: style$a["divider"] }),
1467
+ /* @__PURE__ */ jsx("div", { className: style$c["divider"] }),
1216
1468
  commandBarButtons,
1217
1469
  bugButton
1218
1470
  ] }) });
@@ -1270,7 +1522,7 @@ const settings = "_settings_1yvpj_1";
1270
1522
  const section = "_section_1yvpj_7";
1271
1523
  const field = "_field_1yvpj_23";
1272
1524
  const empty = "_empty_1yvpj_33";
1273
- const style$9 = {
1525
+ const style$b = {
1274
1526
  settings: settings,
1275
1527
  section: section,
1276
1528
  "section-title": "_section-title_1yvpj_19",
@@ -1281,7 +1533,7 @@ const style$9 = {
1281
1533
  const form = "_form_w9o1o_1";
1282
1534
  const item = "_item_w9o1o_7";
1283
1535
  const description = "_description_w9o1o_13";
1284
- const style$8 = {
1536
+ const style$a = {
1285
1537
  form: form,
1286
1538
  item: item,
1287
1539
  description: description,
@@ -1310,9 +1562,9 @@ const EmitterOptionsForm = ({
1310
1562
  return /* @__PURE__ */ jsx(Text, { size: 200, children: "No options available" });
1311
1563
  }
1312
1564
  const entries = Object.entries(emitterOptionsSchema);
1313
- return /* @__PURE__ */ jsx("div", { className: style$8["form"], children: entries.map(([key, value]) => {
1565
+ return /* @__PURE__ */ jsx("div", { className: style$a["form"], children: entries.map(([key, value]) => {
1314
1566
  const resolved = value.oneOf ? resolveOneOfProperty(value) : value;
1315
- return /* @__PURE__ */ jsx("div", { className: style$8["form-item"], children: resolved.type === "array" ? /* @__PURE__ */ jsx(
1567
+ return /* @__PURE__ */ jsx("div", { className: style$a["form-item"], children: resolved.type === "array" ? /* @__PURE__ */ jsx(
1316
1568
  JsonSchemaArrayPropertyInput,
1317
1569
  {
1318
1570
  emitterOptions: options[library.name] ?? {},
@@ -1354,7 +1606,7 @@ const JsonSchemaArrayPropertyInput = ({
1354
1606
  () => name[0].toUpperCase() + name.slice(1).replace(/-/g, " "),
1355
1607
  [name]
1356
1608
  );
1357
- const inputId = useId("input");
1609
+ const inputId = useId$1("input");
1358
1610
  const [selectedValues, setSelectedValues] = useState(new Set(value));
1359
1611
  const handleChange = useCallback(
1360
1612
  (_, data, value2) => {
@@ -1374,7 +1626,7 @@ const JsonSchemaArrayPropertyInput = ({
1374
1626
  return JsonSchemaPropertyInput({ emitterOptions, name, prop: itemsSchema, onChange });
1375
1627
  }
1376
1628
  const itemsEnum = itemsSchema.enum;
1377
- return /* @__PURE__ */ jsxs("div", { className: style$8["item"], children: [
1629
+ return /* @__PURE__ */ jsxs("div", { className: style$a["item"], children: [
1378
1630
  /* @__PURE__ */ jsx(Label, { htmlFor: inputId, title: name, children: prettyName }),
1379
1631
  itemsEnum.map((x) => /* @__PURE__ */ jsx(
1380
1632
  Checkbox,
@@ -1398,7 +1650,7 @@ const JsonSchemaPropertyInput = ({
1398
1650
  () => name[0].toUpperCase() + name.slice(1).replace(/-/g, " "),
1399
1651
  [name]
1400
1652
  );
1401
- const inputId = useId("input");
1653
+ const inputId = useId$1("input");
1402
1654
  const value = emitterOptions[name] ?? prop.default;
1403
1655
  const handleChange = useCallback(
1404
1656
  (_, data) => onChange({ name, value: "value" in data ? data.value : data.checked }),
@@ -1406,24 +1658,24 @@ const JsonSchemaPropertyInput = ({
1406
1658
  );
1407
1659
  switch (prop.type) {
1408
1660
  case "boolean":
1409
- return /* @__PURE__ */ jsxs("div", { className: style$8["item"], children: [
1661
+ return /* @__PURE__ */ jsxs("div", { className: style$a["item"], children: [
1410
1662
  /* @__PURE__ */ jsx(
1411
1663
  Switch,
1412
1664
  {
1413
- className: style$8["switch"],
1665
+ className: style$a["switch"],
1414
1666
  label: prettyName,
1415
1667
  labelPosition: "above",
1416
1668
  checked: value,
1417
1669
  onChange: handleChange
1418
1670
  }
1419
1671
  ),
1420
- prop.description && /* @__PURE__ */ jsx(Text, { size: 200, className: style$8["description"], children: prop.description })
1672
+ prop.description && /* @__PURE__ */ jsx(Text, { size: 200, className: style$a["description"], children: prop.description })
1421
1673
  ] });
1422
1674
  case "string":
1423
1675
  default:
1424
- return /* @__PURE__ */ jsxs("div", { className: style$8["item"], children: [
1676
+ return /* @__PURE__ */ jsxs("div", { className: style$a["item"], children: [
1425
1677
  /* @__PURE__ */ jsx(Label, { htmlFor: inputId, title: name, children: prettyName }),
1426
- prop.description && /* @__PURE__ */ jsx(Text, { size: 200, className: style$8["description"], children: prop.description }),
1678
+ prop.description && /* @__PURE__ */ jsx(Text, { size: 200, className: style$a["description"], children: prop.description }),
1427
1679
  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 })
1428
1680
  ] });
1429
1681
  }
@@ -1507,10 +1759,10 @@ const CompilerSettings = ({
1507
1759
  },
1508
1760
  [onSelectedEmitterChange]
1509
1761
  );
1510
- return /* @__PURE__ */ jsxs("div", { className: style$9["settings"], children: [
1511
- /* @__PURE__ */ jsxs("section", { className: style$9["section"], children: [
1512
- /* @__PURE__ */ jsx(Subtitle2, { className: style$9["section-title"], children: "Emitter" }),
1513
- /* @__PURE__ */ jsxs("div", { className: style$9["field"], children: [
1762
+ return /* @__PURE__ */ jsxs("div", { className: style$b["settings"], children: [
1763
+ /* @__PURE__ */ jsxs("section", { className: style$b["section"], children: [
1764
+ /* @__PURE__ */ jsx(Subtitle2, { className: style$b["section-title"], children: "Emitter" }),
1765
+ /* @__PURE__ */ jsxs("div", { className: style$b["field"], children: [
1514
1766
  /* @__PURE__ */ jsx(Label, { children: "Select emitter" }),
1515
1767
  /* @__PURE__ */ jsxs(
1516
1768
  Select,
@@ -1526,8 +1778,8 @@ const CompilerSettings = ({
1526
1778
  )
1527
1779
  ] })
1528
1780
  ] }),
1529
- /* @__PURE__ */ jsxs("section", { className: style$9["section"], children: [
1530
- /* @__PURE__ */ jsx(Subtitle2, { className: style$9["section-title"], children: "Emitter options" }),
1781
+ /* @__PURE__ */ jsxs("section", { className: style$b["section"], children: [
1782
+ /* @__PURE__ */ jsx(Subtitle2, { className: style$b["section-title"], children: "Emitter options" }),
1531
1783
  library ? /* @__PURE__ */ jsx(
1532
1784
  EmitterOptionsForm,
1533
1785
  {
@@ -1535,10 +1787,10 @@ const CompilerSettings = ({
1535
1787
  options: options.options ?? {},
1536
1788
  optionsChanged: emitterOptionsChanged
1537
1789
  }
1538
- ) : /* @__PURE__ */ jsx(Text, { size: 200, className: style$9["empty"], children: "No emitter selected" })
1790
+ ) : /* @__PURE__ */ jsx(Text, { size: 200, className: style$b["empty"], children: "No emitter selected" })
1539
1791
  ] }),
1540
- /* @__PURE__ */ jsxs("section", { className: style$9["section"], children: [
1541
- /* @__PURE__ */ jsx(Subtitle2, { className: style$9["section-title"], children: "Linter rules" }),
1792
+ /* @__PURE__ */ jsxs("section", { className: style$b["section"], children: [
1793
+ /* @__PURE__ */ jsx(Subtitle2, { className: style$b["section-title"], children: "Linter rules" }),
1542
1794
  /* @__PURE__ */ jsx(
1543
1795
  LinterForm,
1544
1796
  {
@@ -1551,7 +1803,7 @@ const CompilerSettings = ({
1551
1803
  ] });
1552
1804
  };
1553
1805
 
1554
- const style$7 = {
1806
+ const style$9 = {
1555
1807
  "config-panel": "_config-panel_cffut_1",
1556
1808
  "config-toggle": "_config-toggle_cffut_8",
1557
1809
  "config-content": "_config-content_cffut_17",
@@ -1646,12 +1898,12 @@ const ConfigPanel = ({
1646
1898
  },
1647
1899
  [selectedEmitter, compilerOptions, yamlModel]
1648
1900
  );
1649
- return /* @__PURE__ */ jsxs("div", { className: style$7["config-panel"], children: [
1650
- /* @__PURE__ */ jsx("div", { className: style$7["config-toggle"], children: /* @__PURE__ */ jsxs(TabList, { size: "small", selectedValue: mode, onTabSelect: handleModeChange, children: [
1901
+ return /* @__PURE__ */ jsxs("div", { className: style$9["config-panel"], children: [
1902
+ /* @__PURE__ */ jsx("div", { className: style$9["config-toggle"], children: /* @__PURE__ */ jsxs(TabList, { size: "small", selectedValue: mode, onTabSelect: handleModeChange, children: [
1651
1903
  /* @__PURE__ */ jsx(Tab, { value: "form", children: "Visual" }),
1652
1904
  /* @__PURE__ */ jsx(Tab, { value: "yaml", children: "Yaml" })
1653
1905
  ] }) }),
1654
- /* @__PURE__ */ jsx("div", { className: style$7["config-content"], children: mode === "form" ? /* @__PURE__ */ jsx("div", { className: style$7["form-content"], children: /* @__PURE__ */ jsx(
1906
+ /* @__PURE__ */ jsx("div", { className: style$9["config-content"], children: mode === "form" ? /* @__PURE__ */ jsx("div", { className: style$9["form-content"], children: /* @__PURE__ */ jsx(
1655
1907
  CompilerSettings,
1656
1908
  {
1657
1909
  host,
@@ -1664,7 +1916,7 @@ const ConfigPanel = ({
1664
1916
  ] });
1665
1917
  };
1666
1918
 
1667
- const style$6 = {
1919
+ const style$8 = {
1668
1920
  "editor-panel": "_editor-panel_k9ax7_1",
1669
1921
  "panel-tabs-container": "_panel-tabs-container_k9ax7_7",
1670
1922
  "panel-content": "_panel-content_k9ax7_11"
@@ -1706,12 +1958,12 @@ const EditorPanel = ({
1706
1958
  const onTabSelect = useCallback((_, data) => {
1707
1959
  setSelectedTab(data.value);
1708
1960
  }, []);
1709
- return /* @__PURE__ */ jsxs("div", { className: style$6["editor-panel"], children: [
1710
- /* @__PURE__ */ jsx("div", { className: style$6["panel-tabs-container"], children: /* @__PURE__ */ jsxs(TabList, { vertical: true, size: "large", selectedValue: selectedTab, onTabSelect, children: [
1961
+ return /* @__PURE__ */ jsxs("div", { className: style$8["editor-panel"], children: [
1962
+ /* @__PURE__ */ jsx("div", { className: style$8["panel-tabs-container"], children: /* @__PURE__ */ jsxs(TabList, { vertical: true, size: "large", selectedValue: selectedTab, onTabSelect, children: [
1711
1963
  /* @__PURE__ */ jsx(Tab, { value: "tsp", children: /* @__PURE__ */ jsx("span", { title: "TypeSpec", children: /* @__PURE__ */ jsx(TypeSpecIcon, {}) }) }),
1712
1964
  /* @__PURE__ */ jsx(Tab, { value: "cfg", children: /* @__PURE__ */ jsx("span", { title: "Config", children: /* @__PURE__ */ jsx(SettingsRegular, {}) }) })
1713
1965
  ] }) }),
1714
- /* @__PURE__ */ jsxs("div", { className: style$6["panel-content"], children: [
1966
+ /* @__PURE__ */ jsxs("div", { className: style$8["panel-content"], children: [
1715
1967
  commandBar,
1716
1968
  selectedTab === "tsp" ? /* @__PURE__ */ jsx(
1717
1969
  TypeSpecEditor,
@@ -1736,7 +1988,29 @@ const EditorPanel = ({
1736
1988
  ] });
1737
1989
  };
1738
1990
 
1739
- const style$5 = {
1991
+ const breadcrumb = "_breadcrumb_15sw5_1";
1992
+ const segment = "_segment_15sw5_15";
1993
+ const separator = "_separator_15sw5_20";
1994
+ const current = "_current_15sw5_25";
1995
+ const style$7 = {
1996
+ breadcrumb: breadcrumb,
1997
+ segment: segment,
1998
+ separator: separator,
1999
+ current: current
2000
+ };
2001
+
2002
+ const FileBreadcrumb = ({ path }) => {
2003
+ if (!path || !path.includes("/")) {
2004
+ return null;
2005
+ }
2006
+ const segments = path.split("/");
2007
+ return /* @__PURE__ */ jsx("div", { className: style$7["breadcrumb"], children: segments.map((segment, index) => /* @__PURE__ */ jsxs("span", { className: style$7["segment"], children: [
2008
+ index > 0 && /* @__PURE__ */ jsx("span", { className: style$7["separator"], children: "/" }),
2009
+ /* @__PURE__ */ jsx("span", { className: index === segments.length - 1 ? style$7["current"] : void 0, children: segment })
2010
+ ] }, index)) });
2011
+ };
2012
+
2013
+ const style$6 = {
1740
2014
  "file-output": "_file-output_jzw6j_1",
1741
2015
  "viewer-selector": "_viewer-selector_jzw6j_5"
1742
2016
  };
@@ -1762,8 +2036,8 @@ const FileOutput = ({ filename, content, viewers }) => {
1762
2036
  } else if (keys.length === 1) {
1763
2037
  return resolvedViewers[keys[0]].render({ filename, content });
1764
2038
  }
1765
- return /* @__PURE__ */ jsxs("div", { className: style$5["file-output"], children: [
1766
- /* @__PURE__ */ jsx("div", { className: style$5["viewer-selector"], children: /* @__PURE__ */ jsx(Select, { value: selected, onChange: handleSelected, "aria-label": "Select viewer", children: Object.values(resolvedViewers).map(({ key, label }) => /* @__PURE__ */ jsx("option", { value: key, children: label }, key)) }) }),
2039
+ return /* @__PURE__ */ jsxs("div", { className: style$6["file-output"], children: [
2040
+ /* @__PURE__ */ jsx("div", { className: style$6["viewer-selector"], children: /* @__PURE__ */ jsx(Select, { value: selected, onChange: handleSelected, "aria-label": "Select viewer", children: Object.values(resolvedViewers).map(({ key, label }) => /* @__PURE__ */ jsx("option", { value: key, children: label }, key)) }) }),
1767
2041
  selectedRender && selectedRender({ filename, content })
1768
2042
  ] });
1769
2043
  };
@@ -1773,6 +2047,90 @@ const RawFileViewer = {
1773
2047
  render: ({ filename, content }) => /* @__PURE__ */ jsx(OutputEditor, { filename, value: content })
1774
2048
  };
1775
2049
 
2050
+ const style$5 = {
2051
+ "file-tree": "_file-tree_m3if7_1"
2052
+ };
2053
+
2054
+ const FileNodeIcon = ({ node }) => {
2055
+ if (node.isDirectory) {
2056
+ return /* @__PURE__ */ jsx(FolderRegular, {});
2057
+ }
2058
+ return /* @__PURE__ */ jsx(DocumentRegular, {});
2059
+ };
2060
+ function buildTree(files) {
2061
+ const root = { id: "__root__", name: "root", isDirectory: true, children: [] };
2062
+ const dirMap = /* @__PURE__ */ new Map();
2063
+ dirMap.set("", root);
2064
+ function ensureDir(dirPath) {
2065
+ if (dirMap.has(dirPath)) {
2066
+ return dirMap.get(dirPath);
2067
+ }
2068
+ const parts = dirPath.split("/");
2069
+ const parentPath = parts.slice(0, -1).join("/");
2070
+ const parent = ensureDir(parentPath);
2071
+ const node = {
2072
+ id: dirPath,
2073
+ name: parts[parts.length - 1],
2074
+ isDirectory: true,
2075
+ children: []
2076
+ };
2077
+ dirMap.set(dirPath, node);
2078
+ parent.children.push(node);
2079
+ return node;
2080
+ }
2081
+ for (const file of [...files].sort()) {
2082
+ const lastSlash = file.lastIndexOf("/");
2083
+ if (lastSlash === -1) {
2084
+ root.children.push({
2085
+ id: file,
2086
+ name: file,
2087
+ isDirectory: false
2088
+ });
2089
+ } else {
2090
+ const dirPath = file.substring(0, lastSlash);
2091
+ const fileName = file.substring(lastSlash + 1);
2092
+ const parent = ensureDir(dirPath);
2093
+ parent.children.push({
2094
+ id: file,
2095
+ name: fileName,
2096
+ isDirectory: false
2097
+ });
2098
+ }
2099
+ }
2100
+ function sortChildren(node) {
2101
+ if (node.children) {
2102
+ node.children.sort((a, b) => {
2103
+ if (a.isDirectory !== b.isDirectory) {
2104
+ return a.isDirectory ? -1 : 1;
2105
+ }
2106
+ return String(a.name).localeCompare(String(b.name));
2107
+ });
2108
+ for (const child of node.children) {
2109
+ sortChildren(child);
2110
+ }
2111
+ }
2112
+ }
2113
+ sortChildren(root);
2114
+ return root;
2115
+ }
2116
+ const FileTreeExplorer = ({
2117
+ files,
2118
+ selected,
2119
+ onSelect
2120
+ }) => {
2121
+ const tree = useMemo(() => buildTree(files), [files]);
2122
+ return /* @__PURE__ */ jsx("div", { className: style$5["file-tree"], children: /* @__PURE__ */ jsx(
2123
+ Tree,
2124
+ {
2125
+ tree,
2126
+ selectionMode: "single",
2127
+ selected,
2128
+ onSelect,
2129
+ nodeIcon: FileNodeIcon
2130
+ }
2131
+ ) });
2132
+ };
2133
+
1776
2134
  const tabs = "_tabs_1x6x2_1";
1777
2135
  const tab = "_tab_1x6x2_1";
1778
2136
  const style$4 = {
@@ -1806,13 +2164,14 @@ const OutputTabs = ({
1806
2164
  };
1807
2165
 
1808
2166
  const style$3 = {
1809
- "output-view": "_output-view_omce4_1",
1810
- "file-viewer": "_file-viewer_omce4_6",
1811
- "output-content": "_output-content_omce4_12",
1812
- "file-viewer-content": "_file-viewer-content_omce4_16",
1813
- "type-graph-viewer": "_type-graph-viewer_omce4_21",
1814
- "viewer-tabs-container": "_viewer-tabs-container_omce4_26",
1815
- "viewer-error": "_viewer-error_omce4_30"
2167
+ "output-view": "_output-view_eeqi3_1",
2168
+ "file-viewer": "_file-viewer_eeqi3_6",
2169
+ "output-content": "_output-content_eeqi3_12",
2170
+ "file-viewer-content": "_file-viewer-content_eeqi3_16",
2171
+ "file-viewer-content-with-breadcrumb": "_file-viewer-content-with-breadcrumb_eeqi3_21",
2172
+ "type-graph-viewer": "_type-graph-viewer_eeqi3_32",
2173
+ "viewer-tabs-container": "_viewer-tabs-container_eeqi3_37",
2174
+ "viewer-error": "_viewer-error_eeqi3_41"
1816
2175
  };
1817
2176
 
1818
2177
  const FileViewerComponent = ({
@@ -1822,6 +2181,10 @@ const FileViewerComponent = ({
1822
2181
  }) => {
1823
2182
  const [filename, setFilename] = useState("");
1824
2183
  const [content, setContent] = useState("");
2184
+ const showFileTree = useMemo(
2185
+ () => outputFiles.some((f) => f.includes("/")) || outputFiles.length >= 3,
2186
+ [outputFiles]
2187
+ );
1825
2188
  const loadOutputFile = useCallback(
1826
2189
  async (path) => {
1827
2190
  const contents = await program.host.readFile("./tsp-output/" + path);
@@ -1839,18 +2202,36 @@ const FileViewerComponent = ({
1839
2202
  setFilename("");
1840
2203
  }
1841
2204
  }, [program, outputFiles, loadOutputFile, filename]);
1842
- const handleTabSelection = useCallback(
2205
+ const handleFileSelection = useCallback(
1843
2206
  (newFilename) => {
1844
- setFilename(newFilename);
1845
- void loadOutputFile(newFilename);
2207
+ if (outputFiles.includes(newFilename)) {
2208
+ setFilename(newFilename);
2209
+ void loadOutputFile(newFilename);
2210
+ }
1846
2211
  },
1847
- [loadOutputFile]
2212
+ [loadOutputFile, outputFiles]
1848
2213
  );
1849
2214
  if (outputFiles.length === 0) {
1850
2215
  return /* @__PURE__ */ jsx(Fragment, { children: "No files emitted." });
1851
2216
  }
2217
+ if (showFileTree) {
2218
+ return /* @__PURE__ */ jsx("div", { className: style$3["file-viewer"], children: /* @__PURE__ */ jsxs(SplitPane, { initialSizes: ["220px", void 0], children: [
2219
+ /* @__PURE__ */ jsx(Pane, { minSize: 120, maxSize: 400, children: /* @__PURE__ */ jsx(
2220
+ FileTreeExplorer,
2221
+ {
2222
+ files: outputFiles,
2223
+ selected: filename,
2224
+ onSelect: handleFileSelection
2225
+ }
2226
+ ) }),
2227
+ /* @__PURE__ */ jsx(Pane, { children: /* @__PURE__ */ jsxs("div", { className: style$3["file-viewer-content-with-breadcrumb"], children: [
2228
+ /* @__PURE__ */ jsx(FileBreadcrumb, { path: filename }),
2229
+ /* @__PURE__ */ jsx("div", { className: style$3["file-viewer-content"], children: /* @__PURE__ */ jsx(FileOutput, { filename, content, viewers: fileViewers }) })
2230
+ ] }) })
2231
+ ] }) });
2232
+ }
1852
2233
  return /* @__PURE__ */ jsxs("div", { className: style$3["file-viewer"], children: [
1853
- /* @__PURE__ */ jsx(OutputTabs, { filenames: outputFiles, selected: filename, onSelect: handleTabSelection }),
2234
+ /* @__PURE__ */ jsx(OutputTabs, { filenames: outputFiles, selected: filename, onSelect: handleFileSelection }),
1854
2235
  /* @__PURE__ */ jsx("div", { className: style$3["file-viewer-content"], children: /* @__PURE__ */ jsx(FileOutput, { filename, content, viewers: fileViewers }) })
1855
2236
  ] });
1856
2237
  };
@@ -2506,7 +2887,7 @@ function useStandalonePlaygroundContext(config) {
2506
2887
  }
2507
2888
  const StandalonePlayground = (config) => {
2508
2889
  const context = useStandalonePlaygroundContext(config);
2509
- const toasterId = useId$1();
2890
+ const toasterId = useId();
2510
2891
  const { dispatchToast } = useToastController(toasterId);
2511
2892
  const [lastSavedData, setLastSavedData] = useState(null);
2512
2893
  const saveToStorage = useCallback(
@@ -0,0 +1,6 @@
1
+ import { FunctionComponent } from 'react';
2
+ export interface FileBreadcrumbProps {
3
+ readonly path: string;
4
+ }
5
+ export declare const FileBreadcrumb: FunctionComponent<FileBreadcrumbProps>;
6
+ //# sourceMappingURL=file-breadcrumb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-breadcrumb.d.ts","sourceRoot":"","sources":["../../../../src/react/breadcrumb/file-breadcrumb.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAG/C,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,cAAc,EAAE,iBAAiB,CAAC,mBAAmB,CAmBjE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { FileBreadcrumb, type FileBreadcrumbProps } from './file-breadcrumb.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/react/breadcrumb/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { FunctionComponent } from 'react';
2
+ export interface FileTreeExplorerProps {
3
+ readonly files: string[];
4
+ readonly selected: string;
5
+ readonly onSelect: (file: string) => void;
6
+ }
7
+ export declare const FileTreeExplorer: FunctionComponent<FileTreeExplorerProps>;
8
+ //# sourceMappingURL=file-tree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-tree.d.ts","sourceRoot":"","sources":["../../../../src/react/file-tree/file-tree.tsx"],"names":[],"mappings":"AACA,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAKjE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AA8ED,eAAO,MAAM,gBAAgB,EAAE,iBAAiB,CAAC,qBAAqB,CAkBrE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { FileTreeExplorer, type FileTreeExplorerProps } from './file-tree.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/react/file-tree/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"file-viewer.d.ts","sourceRoot":"","sources":["../../../../src/react/output-view/file-viewer.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAqB,aAAa,EAAE,MAAM,aAAa,CAAC;AAqDtF,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,gBAAgB,EAAE,GAAG,aAAa,CAU/E"}
1
+ {"version":3,"file":"file-viewer.d.ts","sourceRoot":"","sources":["../../../../src/react/output-view/file-viewer.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,gBAAgB,EAAqB,aAAa,EAAE,MAAM,aAAa,CAAC;AAqFtF,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,gBAAgB,EAAE,GAAG,aAAa,CAU/E"}
package/dist/style.css CHANGED
@@ -358,6 +358,33 @@
358
358
  display: flex;
359
359
  flex-direction: column;
360
360
  }
361
+ ._breadcrumb_15sw5_1 {
362
+ display: flex;
363
+ align-items: center;
364
+ padding: 4px 12px;
365
+ font-size: 12px;
366
+ height: 26px;
367
+ border-bottom: 1px solid var(--colorNeutralStroke1);
368
+ background: var(--colorNeutralBackground1);
369
+ overflow: hidden;
370
+ white-space: nowrap;
371
+ text-overflow: ellipsis;
372
+ flex-shrink: 0;
373
+ }
374
+
375
+ ._segment_15sw5_15 {
376
+ display: inline-flex;
377
+ align-items: center;
378
+ }
379
+
380
+ ._separator_15sw5_20 {
381
+ margin: 0 4px;
382
+ color: var(--colorNeutralForeground4);
383
+ }
384
+
385
+ ._current_15sw5_25 {
386
+ font-weight: 600;
387
+ }
361
388
  ._file-output_jzw6j_1 {
362
389
  position: relative;
363
390
  height: 100%;
@@ -368,6 +395,12 @@
368
395
  z-index: 1;
369
396
  right: 0;
370
397
  }
398
+ ._file-tree_m3if7_1 {
399
+ height: 100%;
400
+ overflow: auto;
401
+ background: var(--colorNeutralBackground3);
402
+ padding-top: 4px;
403
+ }
371
404
  ._tabs_1x6x2_1 {
372
405
  border-bottom: 1px solid var(--colorNeutralStroke1);
373
406
  box-shadow: var(--shadow2);
@@ -388,36 +421,47 @@
388
421
  ._tab--selected_1x6x2_18 {
389
422
  background-color: var(--colorNeutralBackground5) !important;
390
423
  }
391
- ._output-view_omce4_1 {
424
+ ._output-view_eeqi3_1 {
392
425
  display: flex;
393
426
  flex-direction: row;
394
427
  height: 100%;
395
428
  }
396
- ._file-viewer_omce4_6 {
429
+ ._file-viewer_eeqi3_6 {
397
430
  display: flex;
398
431
  flex-direction: column;
399
432
  height: 100%;
400
433
  }
401
434
 
402
- ._output-content_omce4_12 {
435
+ ._output-content_eeqi3_12 {
403
436
  flex: 1;
404
437
  min-width: 0;
405
438
  }
406
- ._file-viewer-content_omce4_16 {
439
+ ._file-viewer-content_eeqi3_16 {
440
+ flex: 1;
441
+ min-height: 0;
442
+ }
443
+
444
+ ._file-viewer-content-with-breadcrumb_eeqi3_21 {
445
+ display: flex;
446
+ flex-direction: column;
447
+ height: 100%;
448
+ }
449
+
450
+ ._file-viewer-content-with-breadcrumb_eeqi3_21 ._file-viewer-content_eeqi3_16 {
407
451
  flex: 1;
408
452
  min-height: 0;
409
453
  }
410
454
 
411
- ._type-graph-viewer_omce4_21 {
455
+ ._type-graph-viewer_eeqi3_32 {
412
456
  height: 100%;
413
457
  overflow-y: auto;
414
458
  }
415
459
 
416
- ._viewer-tabs-container_omce4_26 {
460
+ ._viewer-tabs-container_eeqi3_37 {
417
461
  background-color: var(--colorNeutralBackground3);
418
462
  }
419
463
 
420
- ._viewer-error_omce4_30 {
464
+ ._viewer-error_eeqi3_41 {
421
465
  padding: 20px;
422
466
  }
423
467
  ._layout_l03ni_1 {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typespec/playground",
3
- "version": "0.13.1-dev.0",
3
+ "version": "0.14.0-dev.1",
4
4
  "author": "Microsoft Corporation",
5
5
  "description": "TypeSpec playground UI components.",
6
6
  "homepage": "https://typespec.io",