Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,23 @@ describe("InitializedMarkdownEditor", () => {
});
});

describe("code blocks", () => {
it("renders existing code blocks in write mode when withCodeBlocks is false", async () => {
// Given
const markdown = "Before\n\n```\nconsole.log('hi');\n```\n\nAfter";

// When / Then — must not throw "Parsing of the following markdown
// structure failed: {type: code, name: N/A}".
await renderWithAct(
<MockedEditorComponent markdown={markdown} mode="write" />
);

const editor = screen.getByLabelText(EDITOR_LABEL);
expect(editor).toHaveTextContent("Before");
expect(editor).toHaveTextContent("After");
});
});

describe("html tags", () => {
it("properly preserves HTML tags with custom attributes", async () => {
// Given
Expand Down
16 changes: 16 additions & 0 deletions front_end/src/components/markdown_editor/editor.css
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,22 @@
div:has(.prism-code) + p:has(> br:only-child) {
display: none;
}

/*
* Keep fenced code blocks from stretching the editor horizontally.
* `overflow-x: auto` on the <pre> only clips when every ancestor up to the
* content-editable is width-bounded — Lexical wraps decorator blocks in
* intermediate spans/divs that default to intrinsic width, so we force
* min-width: 0 on the wrappers and cap the <pre> at 100% of its container.
*/
.mdx-content-editable pre {
max-width: 100%;
}
.mdx-content-editable [data-lexical-decorator],
.mdx-content-editable [data-lexical-decorator] > * {
min-width: 0;
max-width: 100%;
}
@media (min-width: 1024px) {
.markdown-editor.markdown-editor-read .tweets-wrapper {
display: block;
Expand Down
18 changes: 9 additions & 9 deletions front_end/src/components/markdown_editor/initialized_editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ const PrismCodeBlock: FC<{ code?: string; language?: string }> = ({
// Handle plain text without syntax highlighting
if (normalizedLang === "text") {
return (
<div className="my-4">
<pre className="overflow-x-auto rounded border border-gray-300 bg-gray-100 p-3 dark:border-gray-300-dark dark:bg-gray-100-dark">
<div className="my-4 w-full min-w-0 max-w-full">
<pre className="w-full max-w-full overflow-x-auto rounded border border-gray-300 bg-gray-100 p-3 dark:border-gray-300-dark dark:bg-gray-100-dark">
{codeTrimmed}
</pre>
</div>
Expand All @@ -92,7 +92,7 @@ const PrismCodeBlock: FC<{ code?: string; language?: string }> = ({
const prismLang = CANONICAL_TO_PRISM[normalizedLang] ?? "tsx";

return (
<div className="my-4">
<div className="my-4 w-full min-w-0 max-w-full">
<Highlight
key={theme}
theme={prismTheme}
Expand All @@ -101,7 +101,7 @@ const PrismCodeBlock: FC<{ code?: string; language?: string }> = ({
>
{({ className, tokens, getLineProps, getTokenProps }) => (
<pre
className={`${className} overflow-x-auto rounded border border-gray-300 bg-gray-100 p-3 dark:border-gray-300-dark dark:bg-gray-100-dark`}
className={`${className} w-full max-w-full overflow-x-auto rounded border border-gray-300 bg-gray-100 p-3 dark:border-gray-300-dark dark:bg-gray-100-dark`}
>
{tokens.map((line, i) => (
<div key={i} {...getLineProps({ line })}>
Expand Down Expand Up @@ -258,11 +258,11 @@ const InitializedMarkdownEditor: FC<
equationPlugin(),
];

if (!withCodeBlocks) {
return common;
}

if (mode === "read") {
// Always register codeBlockPlugin so pre-existing ``` fences in the source
// markdown parse — otherwise MDXEditor throws on unknown "code" nodes.
// `withCodeBlocks` only gates the insert-code-block toolbar affordance and
// the rich CodeMirror editing experience.
if (!withCodeBlocks || mode === "read") {
return [
...common,
codeBlockPlugin({
Expand Down
Loading