You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 3235ec9
Browse filesBrowse the repository at this point in the historyBrowse files
feat(core): Markdown fenced code wraps long lines, as RichText does (#7564)
## User impact
A reader of `Markdown` on a narrow screen sees a whole code line instead of scrolling a code block sideways, and a long line is as tall in `Markdown` as in RichText, so a product that switches a document between reading (`Markdown`) and editing (`RichTextEditor`) no longer moves every block below a long code line. Only appearance changes: the code's text, line numbers, syntax colours and Copy output are unchanged.
## Authority
`spec:AST-061` FR5 / DEC-9 (owner-approved, stacked spec pull request #7559): "Fenced code wraps long lines on every surface; a code line never scrolls or clips sideways." Merge after #7559.
## What changes
- `Markdown` passes `isWrapped` to its default `CodeBlock`. A caller's own `components.code` renderer is untouched.
- RichText's code block wraps with core `CodeBlock`'s wrapped rule (`white-space: pre-wrap`, `word-break: break-all`, `overflow-wrap: break-word`) instead of `overflow-wrap: anywhere`, so a line of the same width breaks at the same places on both surfaces; with different rules a long line could take a different number of lines in read and edit mode.
- `Markdown.doc.mjs` anatomy says code wraps.
- `component:Markdown` (current record) Intent and Compatibility record the wrap as a visual, non-breaking default-path change (a fence that no longer overflows also no longer takes the conditional scroll-region tab stop), and its `system_specs` cite `spec:AST-061/DEC-9`. This touches a record, so it needs spec-owner approval at its head.
- Changeset: `@astryxdesign/core` patch, `[feat]` (visual-only under `spec:AST-017/DEC-17`), naming the old and new look and the `components.code` escape.
- The parity sandbox Chromium spec asserts the record: no fence scrolls sideways on `Markdown`, and above phone width a wrapped long line is the same height on both surfaces (at 1440px `code-long` wraps to two lines on each). At phone width the editor's field inset leaves its frame 18px narrower, so a long line there may take one more line in the editor, which FR9's edit-mode inset allows.
## Evidence
Real Chrome (stable, headless) against Storybook builds:
| Arm | Width | Markdown code block | RichText code block | Markdown scrolls sideways |
| --- | --- | --- | --- | --- |
| before (current `main`) | 390 | 82px | 142px | yes |
| before | 1440 | 82px | 102px | yes |
| after | 390 | 122px | 142px | no |
| after | 1440 | 102px | 102px | no |
Light and dark give the same numbers. At 390px the remaining 20px is one extra wrapped line in the editor's narrower frame (340px vs 358px of room).
- Red first: the updated parity case fails on `main` at 390px and 1440px ("code-fence scrolls", "code-long scrolls"); with this change the whole parity sandbox spec passes, 39 of 39.
- `npx vitest run packages/core/src/Markdown packages/core/src/CodeBlock`: 48 files, 1070 tests pass.
- `check:changesets`, Prettier, ESLint clean.
## Writing rubric results
Run over the changed text of `docs/specs/AST-061-document-surface-parity/spec.md` (Current-state impact) and `packages/core/src/Markdown/Markdown.spec.md` (Intent, Compatibility and migration, FR29 row).
- R1 narration: none. Each changed sentence states what Markdown and RichText do now (the wrap, the editor-frame gap, the two default-path changes) in the present tense.
- R2 research in the record: none; the measurements stay in this description and the evidence artifact.
- R3 evidence naming a change: none; no verification cell names a pull request.
- R4 rejected alternatives over one line or outside a decision: none added.
- R5 pull request or issue references remaining: none.
- R6 ruled open questions still listing options: none; neither record gains an open question.
## Scope
- [x] One change: fenced code wraps on both surfaces.
- [x] No new public API; a visual default changes, with an escape.
- [x] Public text and artifacts contain no internal Meta context.
[feat]`Markdown` fenced code blocks wrap long lines instead of scrolling them sideways. A reader on a narrow screen sees the whole line without a horizontal scroll, and where `Markdown` and RichText give a code block the same width, a long line takes the same number of lines in both. Only the appearance changes: the code's text, line numbers, syntax colours and what Copy returns are unchanged, and a code block whose lines no longer overflow also no longer takes the scroll region's Tab stop, as a code block that fits never has. To keep the old sideways-scrolling look, render code yourself through the `components.code` prop with a `CodeBlock` that leaves `isWrapped` off.
dollar-delimited text, `components`, and `inlinePlugins` remain unchanged unless
78
80
the caller supplies `plugins`, supplies `components.math`, or passes the matching
79
81
explicit parser option.
@@ -87,7 +89,13 @@ the released one.
87
89
a `<language> diff` label; the header, copy, disclosure, and viewport name
88
90
stay, and a supplied `code` renderer's contract is unchanged. The way back to
89
91
plain text is a `text` fence or a custom `code` renderer. Every other fence
90
-
is unchanged.
92
+
is unchanged apart from the wrap below.
93
+
- Default-path wrap change (`spec:AST-061` FR5, DEC-9), visual and not breaking:
94
+
the default Code block wraps long lines instead of scrolling them sideways, so
95
+
a fence whose lines no longer overflow also no longer takes the conditional
96
+
scroll-region tab stop. Text, line numbers, syntax colours, copy output, and a
97
+
supplied `code` renderer's contract are unchanged. The way back to sideways
98
+
scrolling is a custom `code` renderer.
91
99
- Default-path layout change (FR26–FR28): a default table's columns may become
92
100
wider than the released fixed buckets, never narrower; header labels wrap
93
101
instead of truncating; a table that squashed its columns may now scroll.
@@ -240,7 +248,7 @@ unions. Enabled calls return the explicit `InlineNodeWithMath` and
240
248
| FR26 | On the default table path each column has a content-derived width floor: the larger of its own longest unbreakable token and a readable minimum derived from that column's content, bounded so a table of short columns still fits its container. The floor applies to the cell's text, not to its padded box, so it means the same amount of content at every density. A header label contributes its own readable minimum to that comparison. A table whose floors exceed the container grows and scrolls rather than dividing the container equally. |
241
249
| FR27 | Default table header cells never truncate: no ellipsis and no width clamp. A header reads in full, on one line up to a bounded width and wrapping past it. Inline code inside a default table cell keeps its token whole rather than breaking mid-token; a supplied `inlineCode` renderer owns its own wrapping. |
242
250
| FR28 | Markdown's Table block owns spacing, sizing, and alignment. The nested Table's own Scroll region remains the sole owner of the table's horizontal overflow, its accessible name, and its conditional keyboard focusability; Markdown adds no second scroll container, name, or tab stop of its own. |
243
-
| FR29 | On the default Code block path the fence's full first word selects CodeBlock's diff layer (`component:CodeBlock` FR9): `diff` renders the layer over plaintext, `diff-<language>` the layer over `<language>` (the language read by the same leading-word rule as any other fence); every other fence is unchanged. A supplied `code` renderer's contract is unchanged: it keeps receiving the leading word characters as `language` — `diff` for both `diff` and `diff-<language>` fences — and nothing new.|
251
+
| FR29 | On the default Code block path the fence's full first word selects CodeBlock's diff layer (`component:CodeBlock` FR9): `diff` renders the layer over plaintext, `diff-<language>` the layer over `<language>` (the language read by the same leading-word rule as any other fence); every other fence takes no diff layer. A supplied `code` renderer's contract is unchanged: it keeps receiving the leading word characters as `language` — `diff` for both `diff` and `diff-<language>` fences — and nothing new. |
244
252
245
253
FR23 includes CommonMark-compatible lazy paragraph continuation inside blockquotes
246
254
and ordered, unordered, or task-list items. Omitting a repeated quote marker or
0 commit comments