Skip to content

Commit

Permalink
feat: 🎸 --sort-html-attributes option
Browse files Browse the repository at this point in the history
  • Loading branch information
shufo committed Aug 7, 2022
1 parent e3ed51a commit 058a6c8
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 3 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ $ blade-formatter -c -d resources/**/*.blade.php
| `--wrap-line-length`, `--wrap` | The length of line wrap size | 120 |
| `--wrap-attributes`, `--wrap-atts` | The way to wrap attributes. `[auto\|force\|force-aligned\|force-expand-multiline\|aligned-multiple\|preserve\|preserve-aligned]` | `auto` |
| `--sort-tailwindcss-classes`, `--sort-classes` | Sort Tailwindcss classes automatically. This option respects `tailwind.config.js` and sort classes according to settings. | false |
| `--sort-html-attributes`, `--sort-attributes` | Sort HTML attributes. `[none\|alphabetical\|code-guide\|idiomatic\|vuejs]` | `'none'` |
| `--end-with-newline`, `-e` | End output with newline | true |
| `--stdin` | format code provided on `<STDIN>` | false |
| `--help`, `-h` | Show help | |
Expand All @@ -196,7 +197,8 @@ e.g.
"wrapLineLength": 120,
"endWithNewLine": true,
"useTabs": false,
"sortTailwindcssClasses": true
"sortTailwindcssClasses": true,
"sortHtmlAttributes": "none",
}
```

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div aria-disabled="true" class="myclass" id="myid" name="myname" src="other">
foo
</div>
3 changes: 3 additions & 0 deletions __tests__/fixtures/formatted.sort_html_attribute.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="myclass" id="myid" name="myname" src="other" aria-disabled="true">
foo
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"sortHtmlAttributes": "alphabetical"
}
3 changes: 3 additions & 0 deletions __tests__/fixtures/sort_html_attribute.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div name="myname" aria-disabled="true" id="myid" class="myclass" src="other">
foo
</div>
17 changes: 17 additions & 0 deletions __tests__/formatter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4234,4 +4234,21 @@ describe('formatter', () => {

await expect(new BladeFormatter().format(content)).rejects.toThrow('SyntaxError');
});

test('it should order html attributes if --sort-html-attributes option passed', async () => {
const content = [
`<div name="myname" aria-disabled="true" id="myid" class="myclass" src="other">`,
`foo`,
`</div>`,
].join('\n');

const expected = [
`<div class="myclass" id="myid" name="myname" aria-disabled="true" src="other">`,
` foo`,
`</div>`,
``,
].join('\n');

await util.doubleFormatCheck(content, expected, { sortHtmlAttributes: 'idiomatic' });
});
});
8 changes: 8 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ export default async function cli() {
description: 'Sort tailwindcss classes',
default: false,
})
.option('sort-html-attributes', {
alias: 'sort-attributes',
type: 'string',
choices: ['none', 'alphabetical', 'code-guide', 'idiomatic', 'vuejs'],
description: 'Sort HTML attributes.',
default: 'none',
defaultDescription: 'none',
})
.option('progress', {
alias: 'p',
type: 'boolean',
Expand Down
13 changes: 13 additions & 0 deletions src/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import detectIndent from 'detect-indent';
import Aigle from 'aigle';
import xregexp from 'xregexp';
import { sortClasses } from '@shufo/tailwindcss-class-sorter';
import { sortAttributes } from 'html-attribute-sorter';
import { FormatterOption, CLIOption } from './main';
import * as vsctm from './vsctm';
import * as util from './util';
Expand All @@ -30,6 +31,7 @@ import {
cssAtRuleTokens,
} from './indent';
import { nestedParenthesisRegex } from './regex';
import { SortHtmlAttributes } from './runtimeConfig';

export default class Formatter {
argumentCheck: any;
Expand Down Expand Up @@ -178,6 +180,7 @@ export default class Formatter {
.then((target) => this.formatXData(target))
.then((target) => this.preserveComponentAttribute(target))
.then((target) => this.preserveShorthandBinding(target))
.then((target) => this.sortHtmlAttributes(target))
.then((target) => this.preserveHtmlAttributes(target))
.then((target) => this.preserveHtmlTags(target))
.then((target) => this.formatAsHtml(target))
Expand Down Expand Up @@ -748,6 +751,16 @@ export default class Formatter {
);
}

async sortHtmlAttributes(content: string) {
const strategy: SortHtmlAttributes = this.options.sortHtmlAttributes ?? 'none';

if (strategy !== 'none') {
return sortAttributes(content, { order: strategy });
}

return content;
}

async preserveShorthandBinding(content: string) {
return _.replace(
content,
Expand Down
9 changes: 8 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ import _ from 'lodash';
import findConfig from 'find-config';
import Formatter from './formatter';
import * as util from './util';
import { findRuntimeConfig, readRuntimeConfig, RuntimeConfig, WrapAttributes } from './runtimeConfig';
import {
findRuntimeConfig,
readRuntimeConfig,
RuntimeConfig,
SortHtmlAttributes,
WrapAttributes,
} from './runtimeConfig';
import FormatError from './errors/formatError';

export interface CLIOption {
Expand All @@ -29,6 +35,7 @@ export interface FormatterOption {
endWithNewline?: boolean;
useTabs?: boolean;
sortTailwindcssClasses?: true;
sortHtmlAttributes?: SortHtmlAttributes;
}

class BladeFormatter {
Expand Down
10 changes: 10 additions & 0 deletions src/runtimeConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,16 @@ export type WrapAttributes =
| 'preserve'
| 'preserve-aligned';

export type SortHtmlAttributes = 'none' | 'alphabetical' | 'code-guide' | 'idiomatic' | 'vuejs';

export interface RuntimeConfig {
indentSize?: number;
wrapLineLength?: number;
wrapAttributes?: WrapAttributes;
endWithNewline?: boolean;
useTabs?: boolean;
sortTailwindcssClasses?: true;
sortHtmlAttributes?: SortHtmlAttributes;
}

const defaultConfigNames = ['.bladeformatterrc.json', '.bladeformatterrc'];
Expand Down Expand Up @@ -66,6 +70,12 @@ export async function readRuntimeConfig(filePath: string | null): Promise<Runtim
},
endWithNewline: { type: 'boolean', nullable: true },
useTabs: { type: 'boolean', nullable: true },
sortTailwindcssClasses: { type: 'boolean', nullable: true },
sortHtmlAttributes: {
type: 'string',
enum: ['none', 'alphabetical', 'code-guide', 'idiomatic', 'vuejs'],
nullable: true,
},
},
additionalProperties: true,
};
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"forceConsistentCasingInFileNames": true,
"types": ["node", "@types/jest"],
"strict": true,
"skipLibCheck": true
"skipLibCheck": true,
"resolveJsonModule": true
},
"ts-node": {
"compilerOptions": {
Expand Down

0 comments on commit 058a6c8

Please sign in to comment.