feat(tools): allow tsx tabs (#61936)

Co-authored-by: Huyen Nguyen <25715018+huyenltnguyen@users.noreply.github.com>
This commit is contained in:
Anna
2025-09-12 14:16:37 -04:00
committed by GitHub
parent 28411a2cec
commit ee05b0d5da
8 changed files with 26 additions and 5 deletions
@@ -188,6 +188,7 @@ const modeMap = {
js: 'javascript', js: 'javascript',
jsx: 'javascript', jsx: 'javascript',
ts: 'typescript', ts: 'typescript',
tsx: 'typescript',
py: 'python', py: 'python',
python: 'python' python: 'python'
}; };
@@ -17,6 +17,7 @@ export type VisibleEditors = {
stylescss?: boolean; stylescss?: boolean;
scriptjs?: boolean; scriptjs?: boolean;
indexts?: boolean; indexts?: boolean;
indextsx?: boolean;
mainpy?: boolean; mainpy?: boolean;
}; };
type MultifileEditorProps = Pick< type MultifileEditorProps = Pick<
@@ -70,6 +71,7 @@ const MultifileEditor = (props: MultifileEditorProps) => {
scriptjs, scriptjs,
indexts, indexts,
indexjsx, indexjsx,
indextsx,
mainpy mainpy
}, },
usesMultifileEditor, usesMultifileEditor,
@@ -94,6 +96,7 @@ const MultifileEditor = (props: MultifileEditorProps) => {
// The order of the keys should match the order set by sortChallengeFiles // The order of the keys should match the order set by sortChallengeFiles
if (indexjsx) editorKeys.push('indexjsx'); if (indexjsx) editorKeys.push('indexjsx');
if (indextsx) editorKeys.push('indextsx');
if (indexhtml) editorKeys.push('indexhtml'); if (indexhtml) editorKeys.push('indexhtml');
if (stylescss) editorKeys.push('stylescss'); if (stylescss) editorKeys.push('stylescss');
if (scriptjs) editorKeys.push('scriptjs'); if (scriptjs) editorKeys.push('scriptjs');
+14
View File
@@ -70,5 +70,19 @@ export const challengeFiles: ChallengeFile[] = [
editableRegionBoundaries: [], editableRegionBoundaries: [],
usesMultifileEditor: true, usesMultifileEditor: true,
path: 'index.jsx', path: 'index.jsx',
},
{
contents: 'some tsx',
error: null,
ext: 'tsx',
head: '',
history: ['index.tsx'],
fileKey: 'indextsx',
name: 'index',
seed: 'some tsx',
tail: '',
editableRegionBoundaries: [],
usesMultifileEditor: true,
path: 'index.tsx',
} }
] ]
+2 -1
View File
@@ -14,11 +14,12 @@ describe('sort-files', () => {
expect(sorted.length).toEqual(expected.length); expect(sorted.length).toEqual(expected.length);
}); });
it('should sort the objects into jsx, html, css, js, ts order', () => { it('should sort the objects into jsx, tsx, html, css, js, ts order', () => {
const sorted = sortChallengeFiles(challengeFiles); const sorted = sortChallengeFiles(challengeFiles);
const sortedKeys = sorted.map(({ fileKey }) => fileKey); const sortedKeys = sorted.map(({ fileKey }) => fileKey);
const expected = [ const expected = [
'indexjsx', 'indexjsx',
'indextsx',
'indexhtml', 'indexhtml',
'stylescss', 'stylescss',
'scriptjs', 'scriptjs',
+2
View File
@@ -4,6 +4,8 @@ export function sortChallengeFiles<File extends { fileKey: string }>(
return challengeFiles.toSorted((a, b) => { return challengeFiles.toSorted((a, b) => {
if (a.fileKey === 'indexjsx') return -1; if (a.fileKey === 'indexjsx') return -1;
if (b.fileKey === 'indexjsx') return 1; if (b.fileKey === 'indexjsx') return 1;
if (a.fileKey === 'indextsx') return -1;
if (b.fileKey === 'indextsx') return 1;
if (a.fileKey === 'indexhtml') return -1; if (a.fileKey === 'indexhtml') return -1;
if (b.fileKey === 'indexhtml') return 1; if (b.fileKey === 'indexhtml') return 1;
if (a.fileKey === 'stylescss') return -1; if (a.fileKey === 'stylescss') return -1;
+1 -1
View File
@@ -1,7 +1,7 @@
// originally based off of https://github.com/gulpjs/vinyl // originally based off of https://github.com/gulpjs/vinyl
import invariant from 'invariant'; import invariant from 'invariant';
const exts = ['js', 'html', 'css', 'jsx', 'ts', 'py'] as const; const exts = ['js', 'html', 'css', 'jsx', 'ts', 'tsx', 'py'] as const;
export type Ext = (typeof exts)[number]; export type Ext = (typeof exts)[number];
export interface IncompleteChallengeFile { export interface IncompleteChallengeFile {
@@ -195,7 +195,7 @@ describe('add-seed plugin', () => {
expect.assertions(1); expect.assertions(1);
expect(() => plugin(cCodeAST, file)).toThrow( expect(() => plugin(cCodeAST, file)).toThrow(
"On line 30 'c' is not a supported language.\n" + "On line 30 'c' is not a supported language.\n" +
' Please use one of js, css, html, jsx or py' ' Please use one of js, css, html, jsx, ts, tsx or py'
); );
}); });
@@ -8,7 +8,7 @@ const keyToSection = {
head: 'before-user-code', head: 'before-user-code',
tail: 'after-user-code' tail: 'after-user-code'
}; };
const supportedLanguages = ['js', 'css', 'html', 'jsx', 'py', 'ts']; const supportedLanguages = ['js', 'css', 'html', 'jsx', 'py', 'ts', 'tsx'];
const longToShortLanguages = { const longToShortLanguages = {
javascript: 'js', javascript: 'js',
typescript: 'ts', typescript: 'ts',
@@ -54,7 +54,7 @@ function codeToData(node, seeds, seedKey, validate) {
throw Error(`On line ${ throw Error(`On line ${
position.start(node).line position.start(node).line
} '${shortLang}' is not a supported language. } '${shortLang}' is not a supported language.
Please use one of js, css, html, jsx or py Please use one of js, css, html, jsx, ts, tsx or py
`); `);
const fileId = `index${shortLang}`; const fileId = `index${shortLang}`;