diff --git a/packages/website/src/components/config/ConfigEditor.module.css b/packages/website/src/components/config/ConfigEditor.module.css
index 1329e5af9a74..b2f25dfcbe0f 100644
--- a/packages/website/src/components/config/ConfigEditor.module.css
+++ b/packages/website/src/components/config/ConfigEditor.module.css
@@ -39,6 +39,10 @@
margin: 0.2rem 0;
}
+.searchResultDescription {
+ flex: 1 0 75%;
+}
+
.searchResult:nth-child(even),
.searchResultGroup:nth-child(even) {
background: var(--ifm-color-emphasis-100);
diff --git a/packages/website/src/components/config/ConfigEditor.tsx b/packages/website/src/components/config/ConfigEditor.tsx
index 43bfcadd9bcd..4f0f9d939955 100644
--- a/packages/website/src/components/config/ConfigEditor.tsx
+++ b/packages/website/src/components/config/ConfigEditor.tsx
@@ -7,11 +7,14 @@ import Text from '../inputs/Text';
import Checkbox from '../inputs/Checkbox';
import useFocus from '../hooks/useFocus';
import Modal from '@site/src/components/modals/Modal';
+import Dropdown from '@site/src/components/inputs/Dropdown';
export interface ConfigOptionsField {
key: string;
+ type: 'boolean' | 'string';
label?: string;
defaults?: unknown[];
+ enum?: string[];
}
export interface ConfigOptionsType {
@@ -33,6 +36,11 @@ function reducerObject(
state: ConfigEditorValues,
action:
| { type: 'init'; config?: ConfigEditorValues }
+ | {
+ type: 'set';
+ name: string;
+ value: unknown;
+ }
| {
type: 'toggle';
checked: boolean;
@@ -44,6 +52,15 @@ function reducerObject(
case 'init': {
return action.config ?? {};
}
+ case 'set': {
+ const newState = { ...state };
+ if (action.value === '') {
+ delete newState[action.name];
+ } else {
+ newState[action.name] = action.value;
+ }
+ return newState;
+ }
case 'toggle': {
const newState = { ...state };
if (action.checked) {
@@ -110,28 +127,44 @@ function ConfigEditor(props: ConfigEditorProps): JSX.Element {
{group.fields.map(item => (
))}
diff --git a/packages/website/src/components/config/ConfigEslint.tsx b/packages/website/src/components/config/ConfigEslint.tsx
index a25046b71103..f14d00ec5b78 100644
--- a/packages/website/src/components/config/ConfigEslint.tsx
+++ b/packages/website/src/components/config/ConfigEslint.tsx
@@ -45,6 +45,7 @@ function ConfigEslint(props: ConfigEslintProps): JSX.Element {
.map(item => ({
key: item.name,
label: item.description,
+ type: 'boolean',
defaults: ['error', 2, 'warn', 1, ['error'], ['warn'], [2], [1]],
})),
},
@@ -55,6 +56,7 @@ function ConfigEslint(props: ConfigEslintProps): JSX.Element {
.map(item => ({
key: item.name,
label: item.description,
+ type: 'boolean',
defaults: ['error', 2, 'warn', 1, ['error'], ['warn'], [2], [1]],
})),
},
diff --git a/packages/website/src/components/config/ConfigTypeScript.tsx b/packages/website/src/components/config/ConfigTypeScript.tsx
index 8d64045ac4b8..91a4781d14fe 100644
--- a/packages/website/src/components/config/ConfigTypeScript.tsx
+++ b/packages/website/src/components/config/ConfigTypeScript.tsx
@@ -11,10 +11,6 @@ interface ConfigTypeScriptProps {
readonly config?: string;
}
-function checkOptions(item: [string, unknown]): item is [string, boolean] {
- return typeof item[1] === 'boolean';
-}
-
function ConfigTypeScript(props: ConfigTypeScriptProps): JSX.Element {
const [tsConfigOptions, updateOptions] = useState([]);
const [configObject, updateConfigObject] = useState();
@@ -36,10 +32,20 @@ function ConfigTypeScript(props: ConfigTypeScriptProps): JSX.Element {
heading: category,
fields: [],
};
- group[category].fields.push({
- key: item.name,
- label: item.description!.message,
- });
+ if (item.type === 'boolean') {
+ group[category].fields.push({
+ key: item.name,
+ type: 'boolean',
+ label: item.description!.message,
+ });
+ } else if (item.type instanceof Map) {
+ group[category].fields.push({
+ key: item.name,
+ type: 'string',
+ label: item.description!.message,
+ enum: ['', ...Array.from(item.type.keys())],
+ });
+ }
return group;
},
{},
@@ -51,9 +57,7 @@ function ConfigTypeScript(props: ConfigTypeScriptProps): JSX.Element {
const onClose = useCallback(
(newConfig: Record) => {
- const cfg = Object.fromEntries(
- Object.entries(newConfig).filter(checkOptions),
- );
+ const cfg = { ...newConfig };
if (!shallowEqual(cfg, configObject?.compilerOptions)) {
props.onClose({
tsconfig: toJson({ ...(configObject ?? {}), compilerOptions: cfg }),
diff --git a/packages/website/src/components/config/utils.ts b/packages/website/src/components/config/utils.ts
index 77d06c66b0be..749487ea1aab 100644
--- a/packages/website/src/components/config/utils.ts
+++ b/packages/website/src/components/config/utils.ts
@@ -8,6 +8,9 @@ export interface OptionDeclarations {
type?: unknown;
category?: { message: string };
description?: { message: string };
+ element?: {
+ type: unknown;
+ };
}
export function parseESLintRC(code?: string): EslintRC {
@@ -84,7 +87,6 @@ export function toJsonConfig(cfg: unknown, prop: string): string {
export function getTypescriptOptions(): OptionDeclarations[] {
const allowedCategories = [
'Command-line Options',
- 'Modules',
'Projects',
'Compiler Diagnostics',
'Editor Support',
@@ -93,13 +95,24 @@ export function getTypescriptOptions(): OptionDeclarations[] {
'Source Map Options',
];
+ const filteredNames = [
+ 'moduleResolution',
+ 'moduleDetection',
+ 'plugins',
+ 'typeRoots',
+ 'jsx',
+ ];
+
// @ts-expect-error: definition is not fully correct
return (window.ts.optionDeclarations as OptionDeclarations[]).filter(
item =>
- item.type === 'boolean' &&
+ (item.type === 'boolean' ||
+ item.type === 'list' ||
+ item.type instanceof Map) &&
item.description &&
item.category &&
- !allowedCategories.includes(item.category.message),
+ !allowedCategories.includes(item.category.message) &&
+ !filteredNames.includes(item.name),
);
}
diff --git a/packages/website/src/components/editor/config.ts b/packages/website/src/components/editor/config.ts
index 679baa8a0f22..b1d013ff28f6 100644
--- a/packages/website/src/components/editor/config.ts
+++ b/packages/website/src/components/editor/config.ts
@@ -13,6 +13,12 @@ export function createCompilerOptions(
module: window.ts.ModuleKind.ESNext as number,
...tsConfig,
jsx: jsx ? window.ts.JsxEmit.Preserve : window.ts.JsxEmit.None,
+ moduleResolution: undefined,
+ plugins: undefined,
+ typeRoots: undefined,
+ paths: undefined,
+ moduleDetection: undefined,
+ baseUrl: undefined,
};
}
@@ -58,10 +64,27 @@ export function getEslintSchema(
export function getTsConfigSchema(): JSONSchema4 {
const properties = getTypescriptOptions().reduce((options, item) => {
- options[item.name] = {
- type: item.type,
- description: item.description!.message,
- };
+ if (item.type === 'boolean') {
+ options[item.name] = {
+ type: 'boolean',
+ description: item.description!.message,
+ };
+ } else if (item.type === 'list' && item.element?.type instanceof Map) {
+ options[item.name] = {
+ type: 'array',
+ items: {
+ type: 'string',
+ enum: Array.from(item.element.type.keys()),
+ },
+ description: item.description!.message,
+ };
+ } else if (item.type instanceof Map) {
+ options[item.name] = {
+ type: 'string',
+ description: item.description!.message,
+ enum: Array.from(item.type.keys()),
+ };
+ }
return options;
}, {});