diff --git a/packages/website/src/components/ErrorsViewer.tsx b/packages/website/src/components/ErrorsViewer.tsx
index b9f6528672be..b37597f69483 100644
--- a/packages/website/src/components/ErrorsViewer.tsx
+++ b/packages/website/src/components/ErrorsViewer.tsx
@@ -86,7 +86,7 @@ function ErrorBlock({
)}
- {item.suggestions.length > 0 && (
+ {item.suggestions && item.suggestions.length > 0 && (
{item.suggestions.map((fixer, index) => (
();
- const [markers, setMarkers] = useState();
+ const [markers, setMarkers] = useState>({
+ code: [],
+ eslintrc: [],
+ tsconfig: [],
+ });
const [ruleNames, setRuleNames] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [tsVersions, setTSVersion] = useState([]);
@@ -165,8 +169,10 @@ function Playground(): React.JSX.Element {
active={state.showAST ?? false}
additionalTabsInfo={{
Errors:
- markers?.reduce((prev, cur) => prev + cur.items.length, 0) ||
- 0,
+ markers[activeTab].reduce(
+ (prev, cur) => prev + cur.items.length,
+ 0,
+ ) || 0,
}}
change={showAST => setState({ showAST })}
tabs={detailTabs}
@@ -216,7 +222,7 @@ function Playground(): React.JSX.Element {
/>
)
) : (
-
+
)}
diff --git a/packages/website/src/components/editor/LoadedEditor.tsx b/packages/website/src/components/editor/LoadedEditor.tsx
index 0cc5dbe16299..1b7937e5244a 100644
--- a/packages/website/src/components/editor/LoadedEditor.tsx
+++ b/packages/website/src/components/editor/LoadedEditor.tsx
@@ -83,8 +83,23 @@ export const LoadedEditor: React.FC
= ({
const markers = monaco.editor.getModelMarkers({
resource: model.uri,
});
- onMarkersChange(parseMarkers(markers, codeActions, editor));
- }, [codeActions, onMarkersChange, editor, monaco.editor]);
+
+ const errors = parseMarkers(markers, codeActions, editor);
+
+ onMarkersChange(prev => {
+ const tsconfigErrors =
+ activeTab === 'tsconfig' &&
+ !errors.length &&
+ Object.values(prev[activeTab]).filter(
+ error => error.group === 'TypeScript',
+ );
+
+ return {
+ ...prev,
+ [activeTab]: tsconfigErrors || errors,
+ };
+ });
+ }, [activeTab, codeActions, onMarkersChange, editor, monaco.editor]);
useEffect(() => {
webLinter.updateParserOptions(sourceType);
diff --git a/packages/website/src/components/editor/types.ts b/packages/website/src/components/editor/types.ts
index 3b8b41a67944..932f7cf5d9ad 100644
--- a/packages/website/src/components/editor/types.ts
+++ b/packages/website/src/components/editor/types.ts
@@ -5,7 +5,9 @@ export interface CommonEditorProps extends ConfigModel {
readonly activeTab: TabType;
readonly onASTChange: (value: UpdateModel | undefined) => void;
readonly onChange: (cfg: Partial) => void;
- readonly onMarkersChange: (value: ErrorGroup[]) => void;
+ readonly onMarkersChange: React.Dispatch<
+ React.SetStateAction>
+ >;
readonly onSelect: (position?: number) => void;
readonly selectedRange?: SelectedRange;
}
diff --git a/packages/website/src/components/editor/useSandboxServices.ts b/packages/website/src/components/editor/useSandboxServices.ts
index d3a6e7fc00e3..f28548405e15 100644
--- a/packages/website/src/components/editor/useSandboxServices.ts
+++ b/packages/website/src/components/editor/useSandboxServices.ts
@@ -116,6 +116,7 @@ export const useSandboxServices = (
system,
lintUtils,
sandboxInstance.tsvfs,
+ props.onMarkersChange,
);
onLoaded(
diff --git a/packages/website/src/components/linter/createLinter.ts b/packages/website/src/components/linter/createLinter.ts
index 78f001439d87..c396a4642e03 100644
--- a/packages/website/src/components/linter/createLinter.ts
+++ b/packages/website/src/components/linter/createLinter.ts
@@ -7,6 +7,10 @@ import type {
} from '@typescript-eslint/utils/ts-eslint';
import type * as ts from 'typescript';
+import type {
+ ErrorGroup,
+ TabType,
+} from '../../../../website/src/components/types';
import type {
LinterOnLint,
LinterOnParse,
@@ -42,6 +46,9 @@ export function createLinter(
system: PlaygroundSystem,
webLinterModule: WebLinterModule,
vfs: typeof tsvfs,
+ onMarkersChange: React.Dispatch<
+ React.SetStateAction>
+ >,
): CreateLinter {
const rules: CreateLinter['rules'] = new Map();
const configs = new Map(Object.entries(webLinterModule.configs));
@@ -153,6 +160,8 @@ export function createLinter(
};
const applyTSConfig = (fileName: string): void => {
+ let error: ErrorGroup | null = null;
+
try {
const file = system.readFile(fileName) ?? '{}';
const parsed = parseTSConfig(file).compilerOptions;
@@ -160,7 +169,38 @@ export function createLinter(
console.log('[Editor] Updating', fileName, compilerOptions);
parser.updateConfig(compilerOptions);
} catch (e) {
- console.error(e);
+ if (e instanceof Error) {
+ error = {
+ group: 'TypeScript',
+ items: e.message
+ .trim()
+ .split('\n')
+ .map((message: string) => {
+ return {
+ message,
+ severity: 8, // MarkerSeverity.Error
+ };
+ }),
+ uri: undefined,
+ };
+ }
+ } finally {
+ onMarkersChange(prev => {
+ const activeTabErrors = Object.fromEntries(
+ prev.tsconfig.map(error => [error.group, error]),
+ );
+
+ if (error) {
+ activeTabErrors.TypeScript = error;
+ } else {
+ delete activeTabErrors.TypeScript;
+ }
+
+ return {
+ ...prev,
+ tsconfig: Object.values(activeTabErrors),
+ };
+ });
}
};
diff --git a/packages/website/src/components/types.ts b/packages/website/src/components/types.ts
index 181e1e5de39b..7dc1e913b1f1 100644
--- a/packages/website/src/components/types.ts
+++ b/packages/website/src/components/types.ts
@@ -40,10 +40,10 @@ export type SelectedRange = [number, number];
export interface ErrorItem {
fixer?: { fix(): void; message: string };
- location: string;
+ location?: string;
message: string;
severity: number;
- suggestions: { fix(): void; message: string }[];
+ suggestions?: { fix(): void; message: string }[];
}
export interface ErrorGroup {