Repository navigation
feat(enforce-consistent-line-wrapping): wrap a JSX attribute string in place (#216) - #224
Merged
Merged
Conversation
…n place (#216) The rule never fixed a string literal: a JS string can't hold a raw newline, and turning it into a template is a judgment call. A JSX attribute's own string is different — `className="…"` may span lines as written, its newlines are plain whitespace in a class attribute — so nothing is converted, and it's the layout eslint-plugin-better-tailwindcss writes. A migrated codebase's multiline className strings linted clean but new ones were only reported. - New option `wrapStrings: 'never' | 'jsx'` (default 'never'). With 'jsx', both fixers (wrapLines and classesPerLine) take a Literal whose parent is a JSXAttribute — never `className={"…"}`, a call argument, a variable, a ternary or an object value — and write the template block between the quotes, the closing quote at the attribute line's indentation. - CRLF: a JSX string keeps the file's `\r\n` (a template's value is LF), so it is measured and wrapped in LF and written back with the file's ending. - oxfmt's sortTailwindcss collapses the block unless `preserveWhitespace: true`: pinned in oxfmt-interop.test.ts and said on the rule page and /interop. Tests: rule cases (overWidth, all, classesPerLine, single quotes, nested JSX and tabs, CRLF, configured attributes, every JS-string shape still warn-only); the #14 cycle steps for the JSX block; multiline-preservation now runs every fixer over both the template and the JSX-string shape. Mutations of the predicate and the CRLF handling each fail a test. The bench corpus and synthetic are identical (the default is unchanged). Claude-Session: https://claude.ai/code/session_019vTh6S5A41M1HLkmk3FaM1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #216.
Summary
The rule never fixed a string literal: a JS string can't hold a raw newline, and turning it into a template is a judgment call. A JSX attribute's own string is different.
className="…"may span lines as written, because its newlines are plain whitespace in a class attribute, so nothing has to be converted. It is also the layouteslint-plugin-better-tailwindcsswrites: a migrated codebase's multilineclassNamestrings already lint clean, but new ones were only reported, not fixed.wrapStrings: 'never' | 'jsx'(default'never'). With'jsx', both fixers (wrapLinesandclassesPerLine) also handle aLiteralwhose parent is aJSXAttribute, and write the template block between the quotes. The closing quote lands at the attribute line's indentation.className={"…"}, call arguments, variables, ternaries and object values.\r\n. It is measured and wrapped in LF, then written back with the file's line ending.sortTailwindcsscollapses the block unlesspreserveWhitespace: true. This is pinned inoxfmt-interop.test.tsand noted on the rule page and on/interop(EN/ES).Test plan
overWidth,all,classesPerLine, single quotes, nested JSX and tabs, CRLF, configured attributes, and every JS-string shape still warn-only.whitespace-line-wrap-cycle: steps for the JSX block (the no-unnecessary-whitespace and enforce-consistent-line-wrapping contradict each other #14 cycle).multiline-preservationnow runs every fixer over both the template shape and the JSX-string shape (34 cases).oxfmt-interop: with real oxfmt, the block collapses by default and survives withpreserveWhitespace: true.wrapStringssection, corrected string-literal passages, new ✗/✓ examples run bydoc-examples, the defaults row and the migration-table note.lint:types,format:check, typecheck, build andpnpm test(3749 + 312); benchnpm test. The corpus and synthetic runs are identical to the baseline (the default is unchanged).interop.mjspasses.🤖 Generated with Claude Code
https://claude.ai/code/session_019vTh6S5A41M1HLkmk3FaM1