Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
feat: add groupByResponsive setting
  • Loading branch information
francoismassart committed Jun 9, 2021
commit 7a099122887bb8cc36dccadb262cd861633d2428
15 changes: 15 additions & 0 deletions docs/rules/classnames-order.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Examples of **correct** code for this rule:
"tailwindcss/classnames-order": [<enabled>, {
"callees": Array<string>,
"config": <string>|<object>,
"groupByResponsive": <boolean>,
"groups": Array<object>,
"prependCustom": <boolean>,
"removeDuplicates": <boolean>
Expand Down Expand Up @@ -52,6 +53,20 @@ It is also possible to directly inject a configuration as plain `object` like `{

Finally, the plugin will [merge the provided configuration](https://tailwindcss.com/docs/configuration#referencing-in-java-script) with [Tailwind CSS's default configuration](https://github.com/tailwindlabs/tailwindcss/blob/master/stubs/defaultConfig.stub.js).

### `groupByResponsive` (default: `false`)

Linting this code:

`<div class="rounded sm:rounded-lg lg:rounded-2xl p-4 sm:p-6 lg:p-8">...</div>`

By default, the ordering process will group the classnames by properties, then by variants:

`<div class="p-4 sm:p-6 lg:p-8 rounded sm:rounded-lg lg:rounded-2xl">...</div>`

Set `groupByResponsive` to `true` and the ordering and you will get:

`<div class="p-4 rounded sm:p-6 sm:rounded-lg lg:p-8 lg:rounded-2xl">...</div>`

### `groups` (default defined in [groups.js](../../lib/config/groups.js))

If you really need to, you can write your own configuration.
Expand Down
37 changes: 34 additions & 3 deletions lib/rules/classnames-order.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ module.exports = {
const callees = getOption(context, 'callees');
const twConfig = getOption(context, 'config');
const groupsConfig = getOption(context, 'groups');
const groupByResponsive = getOption(context, 'groupByResponsive');
const prependCustom = getOption(context, 'prependCustom');
const removeDuplicates = getOption(context, 'removeDuplicates');

Expand Down Expand Up @@ -106,6 +107,23 @@ module.exports = {
}
return str;
};
/**
* Generate an Array of Array, grouping class by responsive variants
* @param {Array} classNames
* @returns {Array} an Array (one entry per responsive variant), each entry is an array of classnames
*/
const getResponsiveGroups = (classNames) => {
const responsiveVariants = Object.keys(mergedConfig.theme.screens);
const classnamesByResponsive = [[]];
responsiveVariants.forEach((prefix) => {
classnamesByResponsive.push([]);
});
classNames.forEach((cls) => {
const idx = parseInt(getSpecificity(attrUtil.cleanClassname(cls), responsiveVariants, true), 10);
classnamesByResponsive[idx].push(cls);
});
return classnamesByResponsive;
};

/**
* Parse each classname and populate the `sorted` and `extra` arrays
Expand Down Expand Up @@ -259,11 +277,24 @@ module.exports = {
}

// Sorting
const { sorted, extras } = getSortedGroups(classNames);
const mergedSorted = [];
const mergedExtras = [];
if (groupByResponsive) {
const respGroups = getResponsiveGroups(classNames);
respGroups.forEach((clsGroup) => {
const { sorted, extras } = getSortedGroups(clsGroup);
mergedSorted.push(...sorted);
mergedExtras.push(...extras);
});
} else {
const { sorted, extras } = getSortedGroups(classNames);
mergedSorted.push(...sorted);
mergedExtras.push(...extras);
}

// Generates the validated/sorted attribute value
const flatted = sorted.flat();
const union = prependCustom ? [...extras, ...flatted] : [...flatted, ...extras];
const flatted = mergedSorted.flat();
const union = prependCustom ? [...mergedExtras, ...flatted] : [...flatted, ...mergedExtras];
if (before !== null) {
union.unshift(before);
}
Expand Down
2 changes: 2 additions & 0 deletions lib/util/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ function getOption(context, name) {
return ['classnames', 'clsx', 'ctl'];
case 'config':
return 'tailwind.config.js';
case 'groupByResponsive':
return false;
case 'groups':
return defaultGroups;
case 'prependCustom':
Expand Down
8 changes: 8 additions & 0 deletions tests/lib/rules/classnames-order.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ ruleTester.run("classnames-order", rule, {
{
code: `<div class='box-content lg:box-border'>Simple quotes</div>`,
},
{
code: `<div class="p-4 rounded sm:p-6 sm:rounded-lg lg:p-8 lg:rounded-2xl">groupByResponsive</div>`,
options: [
{
groupByResponsive: true,
},
],
},
{
code: `<div class="p-5 lg:p-4 md:py-2 sm:px-3 xl:px-6">'p', then 'py' then 'px'</div>`,
},
Expand Down