Skip to content
Merged
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
11 changes: 11 additions & 0 deletions docs/rules/enforce-consistent-line-wrapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Enforce tailwind classes to be broken up into multiple lines. It is possible to
### `printWidth`

The maximum line length. Lines are wrapped appropriately to stay within this limit. The value `0` disables line wrapping by `printWidth`.
Tabs count according to [`tabWidth`](#tabwidth) when evaluating this limit.

**Type**: `number`
**Default**: `80`
Expand Down Expand Up @@ -51,6 +52,16 @@ Enforce tailwind classes to be broken up into multiple lines. It is possible to

<br/>

### `tabWidth`

Determines how many columns a tab character contributes when checking `printWidth`.
This option only affects width calculations and does not change emitted indentation characters.

**Type**: `number`
**Default**: `1`

<br/>

### `lineBreakStyle`

The line break style.
Expand Down
113 changes: 111 additions & 2 deletions src/rules/enforce-consistent-line-wrapping.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,90 @@ describe(enforceConsistentLineWrapping.name, () => {
);
});

it("should use tabWidth when checking printWidth", () => {

const dirty = "a b c d";
const clean = "\n\ta b c\n\td\n";

lint(
enforceConsistentLineWrapping,
{
invalid: [
{
jsx: `() => <img class="${dirty}" />`,
jsxOutput: `() => <img class="${clean}" />`,
svelte: `<img class="${dirty}" />`,
svelteOutput: `<img class="${clean}" />`,

errors: 1,
options: [{ classesPerLine: 0, indent: "tab", printWidth: 10, tabWidth: 4 }]
}
]
}
);
});

it("should default tabWidth to 1 when it is not configured", () => {
lint(
enforceConsistentLineWrapping,
{
invalid: [
{
jsx: `() => <img class="a b c d" />`,
jsxOutput: `() => <img class="\n\ta b c d\n" />`,
svelte: `<img class="a b c d" />`,
svelteOutput: `<img class="\n\ta b c d\n" />`,

errors: 1,
options: [{ classesPerLine: 0, indent: "tab", printWidth: 10 }]
}
]
}
);
});

it("should not apply tabWidth when indentation uses spaces", () => {
lint(
enforceConsistentLineWrapping,
{
invalid: [
{
jsx: `() => <img class="a b c d" />`,
jsxOutput: `() => <img class="\n a b c d\n" />`,
svelte: `<img class="a b c d" />`,
svelteOutput: `<img class="\n a b c d\n" />`,

errors: 1,
options: [{ classesPerLine: 0, indent: 2, printWidth: 10, tabWidth: 8 }]
}
Comment thread
schoero marked this conversation as resolved.
]
}
);
});

it("should still ignore printWidth when it is set to 0 even with tabWidth", () => {

const dirty = "a b c d";
const clean = "\n\ta b c\n\td\n";

lint(
enforceConsistentLineWrapping,
{
invalid: [
{
jsx: `() => <img class="${dirty}" />`,
jsxOutput: `() => <img class="${clean}" />`,
svelte: `<img class="${dirty}" />`,
svelteOutput: `<img class="${clean}" />`,

errors: 1,
options: [{ classesPerLine: 3, indent: "tab", printWidth: 0, tabWidth: 4 }]
}
]
}
);
});

it("should warn if `lineBreakStyle` is likely misconfigured", async () => {
{

Expand Down Expand Up @@ -975,7 +1059,6 @@ describe(enforceConsistentLineWrapping.name, () => {

// #52
it("should wrap expressions even if `group` is set to `never`", () => {

const expression = "${true ? 'b' : 'c'}";

const correct = dedent`
Expand All @@ -997,7 +1080,6 @@ describe(enforceConsistentLineWrapping.name, () => {
]
}
);

});

it("should be possible to change group separation by emptyLines", () => {
Expand Down Expand Up @@ -1099,7 +1181,34 @@ describe(enforceConsistentLineWrapping.name, () => {
]
}
);
});

it("should still start on a new line when `group` is set to `never` except if `preferSingleLine` is enabled", () => {
lint(
enforceConsistentLineWrapping,
{
valid: [
{
angular: `<img class="\n a b hover:c\n" />`,
html: `<img class="\n a b hover:c\n" />`,
jsx: `() => <img class="\n a b hover:c\n" />`,
svelte: `<img class="\n a b hover:c\n" />`,
vue: `<template><img class="\n a b hover:c\n" /></template>`,

options: [{ group: "never", preferSingleLine: false, printWidth: 100 }]
},
{
angular: `<img class="a b hover:c" />`,
html: `<img class="a b hover:c" />`,
jsx: `() => <img class="a b hover:c" />`,
svelte: `<img class="a b hover:c" />`,
vue: `<template><img class="a b hover:c" /></template>`,

options: [{ group: "never", preferSingleLine: true, printWidth: 100 }]
}
]
}
);
});

it("should remove duplicate classes in string literals in defined tagged template literals", () => {
Expand Down
28 changes: 25 additions & 3 deletions src/rules/enforce-consistent-line-wrapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,14 @@ export const enforceConsistentLineWrapping = createRule({
description("Enable this option if prettier is used in your project.")
),
"strict"
),
tabWidth: optional(
pipe(
number(),
minValue(1),
description("The visual width of a tab character when evaluating printWidth.")
),
1
)
}),

Expand Down Expand Up @@ -239,8 +247,7 @@ function lintLiterals(ctx: Context<typeof enforceConsistentLineWrapping>, litera

const simulatedLine = multilineClasses.line
.clone()
.addClass(className)
.toString();
.addClass(className);

// wrap after the first sticky class
if(
Expand Down Expand Up @@ -582,7 +589,22 @@ class Line {
}

public get length() {
return this.toString().length;
const line = this.toString();
const { tabWidth } = this.ctx.options;

if(tabWidth <= 1 || !line.includes("\t")){
return line.length;
}

let width = 0;

for(let i = 0; i < line.length; i++){
width += line[i] === "\t"
? tabWidth
: 1;
}

return width;
}

public get classCount() {
Expand Down
Loading