feat(client): add isDialogue prop to ChallengeTranscript component (#64831)

Co-authored-by: Huyen Nguyen <25715018+huyenltnguyen@users.noreply.github.com>
This commit is contained in:
月正海角
2025-12-23 03:18:42 +08:00
committed by GitHub
parent a34fad01ca
commit d5e855906a
4 changed files with 68 additions and 17 deletions
@@ -58,4 +58,43 @@ describe('<ChallengeTranscript />', () => {
expect(setSpy).not.toHaveBeenCalled();
setSpy.mockRestore();
});
it('should render the transcript as a table when isDialogue is true', () => {
store.set('fcc-transcript-expanded', true);
render(
<ChallengeTranscript
{...baseProps}
transcript={'Hello\nWorld'}
shouldPersistExpanded={true}
isDialogue={true}
/>
);
const table = screen.getByRole('table');
expect(table).toBeVisible();
expect(screen.getByRole('cell', { name: 'Hello' })).toBeVisible();
expect(screen.getByRole('cell', { name: 'World' })).toBeVisible();
});
it('should render the transcript with PrismFormatted when isDialogue is false', () => {
store.set('fcc-transcript-expanded', true);
render(
<ChallengeTranscript
{...baseProps}
transcript='<pre><code class="language-js">console.log("hi")</code></pre>'
shouldPersistExpanded={true}
isDialogue={false}
/>
);
const preElement = screen.getByRole('region');
expect(preElement).toBeVisible();
expect(preElement.tagName).toBe('PRE');
// eslint-disable-next-line testing-library/no-node-access
const codeElement = preElement.querySelector('code');
expect(codeElement).toBeInTheDocument();
expect(preElement).toHaveTextContent('console.log("hi")');
});
});
@@ -3,16 +3,19 @@ import { useTranslation } from 'react-i18next';
import { Spacer } from '@freecodecamp/ui';
import store from 'store';
import PrismFormatted from './prism-formatted';
import './challenge-transcript.css';
interface ChallengeTranscriptProps {
transcript: string;
shouldPersistExpanded?: boolean;
isDialogue?: boolean;
}
function ChallengeTranscript({
transcript,
shouldPersistExpanded
shouldPersistExpanded,
isDialogue
}: ChallengeTranscriptProps): JSX.Element {
const { t } = useTranslation();
@@ -42,20 +45,24 @@ function ChallengeTranscript({
{t('learn.transcript')}
</summary>
<Spacer size='m' />
<table className='transcript-table'>
<tbody>
{transcript
.split('\n')
.filter(line => line.trim() !== '')
.map((line, idx) => {
return (
<tr key={idx}>
<td dangerouslySetInnerHTML={{ __html: line }} />
</tr>
);
})}
</tbody>
</table>
{isDialogue ? (
<table className='transcript-table'>
<tbody>
{transcript
.split('\n')
.filter(line => line.trim() !== '')
.map((line, idx) => {
return (
<tr key={idx}>
<td dangerouslySetInnerHTML={{ __html: line }} />
</tr>
);
})}
</tbody>
</table>
) : (
<PrismFormatted className='line-numbers' text={transcript} />
)}
</details>
<Spacer size='m' />
</>
@@ -437,7 +437,7 @@ export function Scene({
</button>
)}
</div>
<ChallengeTranscript transcript={transcriptText} />
<ChallengeTranscript transcript={transcriptText} isDialogue={true} />
<Spacer size='m' />
</Col>
);
@@ -279,7 +279,12 @@ const ShowFillInTheBlank = ({
{scene && <Scene scene={scene} sceneSubject={sceneSubject} />}
<Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}>
{transcript && <ChallengeTranscript transcript={transcript} />}
{transcript && (
<ChallengeTranscript
transcript={transcript}
isDialogue={true}
/>
)}
{instructions && (
<>