Skip to content

formatter: JSX expression child unnecessarily expanded across 3 lines when it fits within printWidth #21916

@jsmecham

Description

@jsmecham

Input

const App = () => {
  return (
    <O>
      <I>
        <x />
        {f(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx).y} (
        {label})
      </I>
    </O>
  );
};

Config

{}

Oxfmt output

const App = () => {
  return (
    <O>
      <I>
        <x />
        {
          f(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx).y
        } (
        {label})
      </I>
    </O>
  );
};

Prettier output

const App = () => {
  return (
    <O>
      <I>
        <x />
        {f(xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx).y} (
        {label})
      </I>
    </O>
  );
};

Additional notes

The line {f(xxx...xxx).y} ( is exactly 79 characters at 8-space indent — fits within printWidth: 80. Prettier leaves it on a single line. oxfmt expands the JSX expression {f(xxx...).y} across three lines ({, content, } on separate lines), apparently treating the trailing ( literal text as part of the same group's measurement and deciding the combined sequence doesn't fit.

The <x /> self-closing element is necessary to set up the printer state that exposes the bug — it produces the hard line break preceding the trigger expression that resets the printer's "measured group fits" tracking, so the inner expression group ends up re-measuring itself and walking past the fill entry boundary into subsequent content.

Tested against oxfmt 0.47.0 and prettier 3.8.3.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions