heybourn / headwind

An opinionated Tailwind CSS class sorter built for Visual Studio Code
https://marketplace.visualstudio.com/items?itemName=heybourn.headwind
MIT License
1.39k stars 44 forks source link

Better configuration #5

Open andreich1980 opened 4 years ago

andreich1980 commented 4 years ago

It would be cool if I could set up preferred sort order not with full class names like m-0, m-12, -m-2 etc but just m and -m. This way I wouldn't have to add all my custom tweaks of tailwindcss.config.js

before

"headwind.defaultSortOrder": [
    "container",
    "m-0",
    "m-1",
    "m-2",
   ...
    "mx-0",
    "mx-1",
    "mx-2",
   ...
    "ml-0",
    "ml-1",
    "ml-2",
   ...
    "mrl-0",
    "mr-1",
    "mr-2",
   ...
    "my-0",
    "my-1",
    "my-2",
   ...
    "mt-0",
    "mt-1",
    "mt-2",
   ...
    "mb-0",
    "mb-1",
    "mb-2",
   ...
    "-m-1",
    "-m-2",
    ...
    "p-0",
    "p-1",
    "p-2",
    ...
]

after

"headwind.defaultSortOrder": [
    "container",
    "m",
    "mx",
    "ml",
    "mr",
    "my",
    "mt",
    "mb",
    "-m",
    ...
    "p",
   ...
]

Though I don't know how to manage classes like flex, flex-col in this case. Maybe there should be 2 config sections: one to manage tags with numbers (like m-N, p-N, border-N, etc. And another section for full class names.

Great extension btw!

innocenzi commented 4 years ago

I think the best way would be to actually sort thanks to the configuration.

It could, for instance, add a VSCode configuration item headwind.groupBy that would take an array of Tailwind CSS configuration keys (eg. [ "spacing", "colors" ]) and use that to order. That way, custom classes would also be taken into account.

For a more precise sorting, a configuration item headwind.sort could be used, with an array of class names.

Another last thing, it could be interesting to add a class separator. Willem Van Bockstal uses | and I find that pretty interesting.

{
  "headwind.groupBy": [
    "container",
    "spacing",
    "fontFamily",
    "colors",
  ],
  "headwind.sort": [
    "my-class", // can be classes that have nothing to do with Tailwind
  ],
  "headwind.separator": "|"
}
andreich1980 commented 4 years ago

1) When use "spacing" how do I choose what goes first m-N or p-N? 2) How would you use the |? To separate what classes/group of classes? mx-2 my-3 | px-4 py-2 | flex ?

innocenzi commented 4 years ago
  1. With that configuration it would be arbitrary. We could add a regex array to the configuration in order to make that behavior configurable (see below).
  2. Yes, exactly.

I replaced the example config:

{
  "headwind.groupBy": {
    "container": [],
    "spacing": ["\\-", "m", "p"], // would order negative classes first, then margin, then padding for the spacing namespace
    "fontFamily": [],
    "colors": ["text", "bg", "border"] // would place text color utilities before background, and border last
  },
  "headwind.customFirst": true, // places custom (non-tailwind) classes first if true, last if false
  "headwind.sort": [
    // can be classes that have nothing to do with Tailwind
    "my-class",
    "another-class"
  ],
  "headwind.separator": {
    "character": "|",
    "threshold": 20 // add the separator only if more than 20 classes?
  }
}
andreich1980 commented 4 years ago

I like this approach! Great idea 💡 And if separator character is an empty string - don't use it. And the "headwind.customFirst": true option is what I was thinking about but haven't mentioned it yet!

innocenzi commented 4 years ago

If there is no PR in the next couple of days, I might want to implement this myself, if @heybourn likes this pattern. Or maybe I can do something in a separated package, since someone on Twitter has mentioned that a CLI tool for this would be appreciated. 😊

heybourn commented 4 years ago

I'd love if you made a PR. I agree, I think slimming the code down to prefixes would be a better approach

innocenzi commented 4 years ago

So, I'm going to make a separate package for this. Its API will take the classlist and parameters as arguments, and will return the sorted classlist. That way, it can be reusable accross multiple extensions and still be consistent, and it can also be used as a CLI tool.

innocenzi commented 4 years ago

Well, looks like this won't be possible without Tailwind giving a map of configuration ›› class names.

Currently, there is no way to know which class will be generated from which plugin (core or not). It means we can't actually sort the class names thanks to this kind of configuration.

What's required is a map like that:

{
  "height": [
    ".h-0",
    ".h-1",
    ".h-2",
    ".h-3",
    ".h-4",
    ".h-5",
    ".h-6",
    ".h-8",
    ".h-10",
    ".h-12",
    ".h-16",
    ".h-20",
    ".h-24",
    ".h-32",
    ".h-40",
    ".h-48",
    ".h-56",
    ".h-64",
    ".h-auto",
    ".h-px",
    ".h-full",
    ".h-screen",
  ],
  "lineHeight": [
    ".leading-none",
    ".leading-tight",
    ".leading-snug",
    ".leading-normal",
    ".leading-relaxed",
    ".leading-loose",
  ]
}

I guess I'm giving up that idea for now, until it gets implemented in Tailwind 😦

andreich1980 commented 4 years ago

Should we ping @tailwindcss to ask for Adam's opinion?

innocenzi commented 4 years ago

@andreich1980 He said on the Discord server that he was open to PRs. Feel free to come in order to ask before doing any work, though.

hacknug commented 4 years ago

Managed to get core to give me something like this. Would this be enough? What else are we missing?

long-ass JSON-formatted file ```json { "classes": [ [ [ null ], [ ".container" ], [ ".container" ], [ ".container" ], [ ".container" ] ], [ [ ".sr-only", ".not-sr-only" ], [ ".appearance-none" ], [ ".bg-fixed", ".bg-local", ".bg-scroll" ], [ ".bg-transparent", ".bg-black", ".bg-white", ".bg-gray-100", ".bg-gray-200", ".bg-gray-300", ".bg-gray-400", ".bg-gray-500", ".bg-gray-600", ".bg-gray-700", ".bg-gray-800", ".bg-gray-900", ".bg-red-100", ".bg-red-200", ".bg-red-300", ".bg-red-400", ".bg-red-500", ".bg-red-600", ".bg-red-700", ".bg-red-800", ".bg-red-900", ".bg-orange-100", ".bg-orange-200", ".bg-orange-300", ".bg-orange-400", ".bg-orange-500", ".bg-orange-600", ".bg-orange-700", ".bg-orange-800", ".bg-orange-900", ".bg-yellow-100", ".bg-yellow-200", ".bg-yellow-300", ".bg-yellow-400", ".bg-yellow-500", ".bg-yellow-600", ".bg-yellow-700", ".bg-yellow-800", ".bg-yellow-900", ".bg-green-100", ".bg-green-200", ".bg-green-300", ".bg-green-400", ".bg-green-500", ".bg-green-600", ".bg-green-700", ".bg-green-800", ".bg-green-900", ".bg-teal-100", ".bg-teal-200", ".bg-teal-300", ".bg-teal-400", ".bg-teal-500", ".bg-teal-600", ".bg-teal-700", ".bg-teal-800", ".bg-teal-900", ".bg-blue-100", ".bg-blue-200", ".bg-blue-300", ".bg-blue-400", ".bg-blue-500", ".bg-blue-600", ".bg-blue-700", ".bg-blue-800", ".bg-blue-900", ".bg-indigo-100", ".bg-indigo-200", ".bg-indigo-300", ".bg-indigo-400", ".bg-indigo-500", ".bg-indigo-600", ".bg-indigo-700", ".bg-indigo-800", ".bg-indigo-900", ".bg-purple-100", ".bg-purple-200", ".bg-purple-300", ".bg-purple-400", ".bg-purple-500", ".bg-purple-600", ".bg-purple-700", ".bg-purple-800", ".bg-purple-900", ".bg-pink-100", ".bg-pink-200", ".bg-pink-300", ".bg-pink-400", ".bg-pink-500", ".bg-pink-600", ".bg-pink-700", ".bg-pink-800", ".bg-pink-900" ], [ ".bg-bottom", ".bg-center", ".bg-left", ".bg-left-bottom", ".bg-left-top", ".bg-right", ".bg-right-bottom", ".bg-right-top", ".bg-top" ], [ ".bg-repeat", ".bg-no-repeat", ".bg-repeat-x", ".bg-repeat-y", ".bg-repeat-round", ".bg-repeat-space" ], [ ".bg-auto", ".bg-cover", ".bg-contain" ], [ ".border-collapse", ".border-separate" ], [ ".border-transparent", ".border-black", ".border-white", ".border-gray-100", ".border-gray-200", ".border-gray-300", ".border-gray-400", ".border-gray-500", ".border-gray-600", ".border-gray-700", ".border-gray-800", ".border-gray-900", ".border-red-100", ".border-red-200", ".border-red-300", ".border-red-400", ".border-red-500", ".border-red-600", ".border-red-700", ".border-red-800", ".border-red-900", ".border-orange-100", ".border-orange-200", ".border-orange-300", ".border-orange-400", ".border-orange-500", ".border-orange-600", ".border-orange-700", ".border-orange-800", ".border-orange-900", ".border-yellow-100", ".border-yellow-200", ".border-yellow-300", ".border-yellow-400", ".border-yellow-500", ".border-yellow-600", ".border-yellow-700", ".border-yellow-800", ".border-yellow-900", ".border-green-100", ".border-green-200", ".border-green-300", ".border-green-400", ".border-green-500", ".border-green-600", ".border-green-700", ".border-green-800", ".border-green-900", ".border-teal-100", ".border-teal-200", ".border-teal-300", ".border-teal-400", ".border-teal-500", ".border-teal-600", ".border-teal-700", ".border-teal-800", ".border-teal-900", ".border-blue-100", ".border-blue-200", ".border-blue-300", ".border-blue-400", ".border-blue-500", ".border-blue-600", ".border-blue-700", ".border-blue-800", ".border-blue-900", ".border-indigo-100", ".border-indigo-200", ".border-indigo-300", ".border-indigo-400", ".border-indigo-500", ".border-indigo-600", ".border-indigo-700", ".border-indigo-800", ".border-indigo-900", ".border-purple-100", ".border-purple-200", ".border-purple-300", ".border-purple-400", ".border-purple-500", ".border-purple-600", ".border-purple-700", ".border-purple-800", ".border-purple-900", ".border-pink-100", ".border-pink-200", ".border-pink-300", ".border-pink-400", ".border-pink-500", ".border-pink-600", ".border-pink-700", ".border-pink-800", ".border-pink-900" ], [ ".rounded-none", ".rounded-sm", ".rounded", ".rounded-lg", ".rounded-full", ".rounded-t-none", ".rounded-r-none", ".rounded-b-none", ".rounded-l-none", ".rounded-t-sm", ".rounded-r-sm", ".rounded-b-sm", ".rounded-l-sm", ".rounded-t", ".rounded-r", ".rounded-b", ".rounded-l", ".rounded-t-lg", ".rounded-r-lg", ".rounded-b-lg", ".rounded-l-lg", ".rounded-t-full", ".rounded-r-full", ".rounded-b-full", ".rounded-l-full", ".rounded-tl-none", ".rounded-tr-none", ".rounded-br-none", ".rounded-bl-none", ".rounded-tl-sm", ".rounded-tr-sm", ".rounded-br-sm", ".rounded-bl-sm", ".rounded-tl", ".rounded-tr", ".rounded-br", ".rounded-bl", ".rounded-tl-lg", ".rounded-tr-lg", ".rounded-br-lg", ".rounded-bl-lg", ".rounded-tl-full", ".rounded-tr-full", ".rounded-br-full", ".rounded-bl-full" ], [ ".border-solid", ".border-dashed", ".border-dotted", ".border-double", ".border-none" ], [ ".border-0", ".border-2", ".border-4", ".border-8", ".border", ".border-t-0", ".border-r-0", ".border-b-0", ".border-l-0", ".border-t-2", ".border-r-2", ".border-b-2", ".border-l-2", ".border-t-4", ".border-r-4", ".border-b-4", ".border-l-4", ".border-t-8", ".border-r-8", ".border-b-8", ".border-l-8", ".border-t", ".border-r", ".border-b", ".border-l" ], [ ".cursor-auto", ".cursor-default", ".cursor-pointer", ".cursor-wait", ".cursor-text", ".cursor-move", ".cursor-not-allowed" ], [ ".block", ".inline-block", ".inline", ".flex", ".inline-flex", ".table", ".table-row", ".table-cell", ".hidden" ], [ ".flex-row", ".flex-row-reverse", ".flex-col", ".flex-col-reverse" ], [ ".flex-wrap", ".flex-wrap-reverse", ".flex-no-wrap" ], [ ".items-start", ".items-end", ".items-center", ".items-baseline", ".items-stretch" ], [ ".self-auto", ".self-start", ".self-end", ".self-center", ".self-stretch" ], [ ".justify-start", ".justify-end", ".justify-center", ".justify-between", ".justify-around" ], [ ".content-center", ".content-start", ".content-end", ".content-between", ".content-around" ], [ ".flex-1", ".flex-auto", ".flex-initial", ".flex-none" ], [ ".flex-grow-0", ".flex-grow" ], [ ".flex-shrink-0", ".flex-shrink" ], [ ".order-1", ".order-2", ".order-3", ".order-4", ".order-5", ".order-6", ".order-7", ".order-8", ".order-9", ".order-10", ".order-11", ".order-12", ".order-first", ".order-last", ".order-none" ], [ ".float-right", ".float-left", ".float-none", ".clearfix:after" ], [ ".font-sans", ".font-serif", ".font-mono" ], [ ".font-hairline", ".font-thin", ".font-light", ".font-normal", ".font-medium", ".font-semibold", ".font-bold", ".font-extrabold", ".font-black" ], [ ".h-0", ".h-1", ".h-2", ".h-3", ".h-4", ".h-5", ".h-6", ".h-8", ".h-10", ".h-12", ".h-16", ".h-20", ".h-24", ".h-32", ".h-40", ".h-48", ".h-56", ".h-64", ".h-auto", ".h-px", ".h-full", ".h-screen" ], [ ".leading-none", ".leading-tight", ".leading-snug", ".leading-normal", ".leading-relaxed", ".leading-loose" ], [ ".list-inside", ".list-outside" ], [ ".list-none", ".list-disc", ".list-decimal" ], [ ".m-0", ".m-1", ".m-2", ".m-3", ".m-4", ".m-5", ".m-6", ".m-8", ".m-10", ".m-12", ".m-16", ".m-20", ".m-24", ".m-32", ".m-40", ".m-48", ".m-56", ".m-64", ".m-auto", ".m-px", ".-m-1", ".-m-2", ".-m-3", ".-m-4", ".-m-5", ".-m-6", ".-m-8", ".-m-10", ".-m-12", ".-m-16", ".-m-20", ".-m-24", ".-m-32", ".-m-40", ".-m-48", ".-m-56", ".-m-64", ".-m-px", ".my-0", ".mx-0", ".my-1", ".mx-1", ".my-2", ".mx-2", ".my-3", ".mx-3", ".my-4", ".mx-4", ".my-5", ".mx-5", ".my-6", ".mx-6", ".my-8", ".mx-8", ".my-10", ".mx-10", ".my-12", ".mx-12", ".my-16", ".mx-16", ".my-20", ".mx-20", ".my-24", ".mx-24", ".my-32", ".mx-32", ".my-40", ".mx-40", ".my-48", ".mx-48", ".my-56", ".mx-56", ".my-64", ".mx-64", ".my-auto", ".mx-auto", ".my-px", ".mx-px", ".-my-1", ".-mx-1", ".-my-2", ".-mx-2", ".-my-3", ".-mx-3", ".-my-4", ".-mx-4", ".-my-5", ".-mx-5", ".-my-6", ".-mx-6", ".-my-8", ".-mx-8", ".-my-10", ".-mx-10", ".-my-12", ".-mx-12", ".-my-16", ".-mx-16", ".-my-20", ".-mx-20", ".-my-24", ".-mx-24", ".-my-32", ".-mx-32", ".-my-40", ".-mx-40", ".-my-48", ".-mx-48", ".-my-56", ".-mx-56", ".-my-64", ".-mx-64", ".-my-px", ".-mx-px", ".mt-0", ".mr-0", ".mb-0", ".ml-0", ".mt-1", ".mr-1", ".mb-1", ".ml-1", ".mt-2", ".mr-2", ".mb-2", ".ml-2", ".mt-3", ".mr-3", ".mb-3", ".ml-3", ".mt-4", ".mr-4", ".mb-4", ".ml-4", ".mt-5", ".mr-5", ".mb-5", ".ml-5", ".mt-6", ".mr-6", ".mb-6", ".ml-6", ".mt-8", ".mr-8", ".mb-8", ".ml-8", ".mt-10", ".mr-10", ".mb-10", ".ml-10", ".mt-12", ".mr-12", ".mb-12", ".ml-12", ".mt-16", ".mr-16", ".mb-16", ".ml-16", ".mt-20", ".mr-20", ".mb-20", ".ml-20", ".mt-24", ".mr-24", ".mb-24", ".ml-24", ".mt-32", ".mr-32", ".mb-32", ".ml-32", ".mt-40", ".mr-40", ".mb-40", ".ml-40", ".mt-48", ".mr-48", ".mb-48", ".ml-48", ".mt-56", ".mr-56", ".mb-56", ".ml-56", ".mt-64", ".mr-64", ".mb-64", ".ml-64", ".mt-auto", ".mr-auto", ".mb-auto", ".ml-auto", ".mt-px", ".mr-px", ".mb-px", ".ml-px", ".-mt-1", ".-mr-1", ".-mb-1", ".-ml-1", ".-mt-2", ".-mr-2", ".-mb-2", ".-ml-2", ".-mt-3", ".-mr-3", ".-mb-3", ".-ml-3", ".-mt-4", ".-mr-4", ".-mb-4", ".-ml-4", ".-mt-5", ".-mr-5", ".-mb-5", ".-ml-5", ".-mt-6", ".-mr-6", ".-mb-6", ".-ml-6", ".-mt-8", ".-mr-8", ".-mb-8", ".-ml-8", ".-mt-10", ".-mr-10", ".-mb-10", ".-ml-10", ".-mt-12", ".-mr-12", ".-mb-12", ".-ml-12", ".-mt-16", ".-mr-16", ".-mb-16", ".-ml-16", ".-mt-20", ".-mr-20", ".-mb-20", ".-ml-20", ".-mt-24", ".-mr-24", ".-mb-24", ".-ml-24", ".-mt-32", ".-mr-32", ".-mb-32", ".-ml-32", ".-mt-40", ".-mr-40", ".-mb-40", ".-ml-40", ".-mt-48", ".-mr-48", ".-mb-48", ".-ml-48", ".-mt-56", ".-mr-56", ".-mb-56", ".-ml-56", ".-mt-64", ".-mr-64", ".-mb-64", ".-ml-64", ".-mt-px", ".-mr-px", ".-mb-px", ".-ml-px" ], [ ".max-h-full", ".max-h-screen" ], [ ".max-w-xs", ".max-w-sm", ".max-w-md", ".max-w-lg", ".max-w-xl", ".max-w-2xl", ".max-w-3xl", ".max-w-4xl", ".max-w-5xl", ".max-w-6xl", ".max-w-full" ], [ ".min-h-0", ".min-h-full", ".min-h-screen" ], [ ".min-w-0", ".min-w-full" ], [ ".object-contain", ".object-cover", ".object-fill", ".object-none", ".object-scale-down" ], [ ".object-bottom", ".object-center", ".object-left", ".object-left-bottom", ".object-left-top", ".object-right", ".object-right-bottom", ".object-right-top", ".object-top" ], [ ".opacity-0", ".opacity-25", ".opacity-50", ".opacity-75", ".opacity-100" ], [ ".outline-none" ], [ ".overflow-auto", ".overflow-hidden", ".overflow-visible", ".overflow-scroll", ".overflow-x-auto", ".overflow-y-auto", ".overflow-x-hidden", ".overflow-y-hidden", ".overflow-x-visible", ".overflow-y-visible", ".overflow-x-scroll", ".overflow-y-scroll", ".scrolling-touch", ".scrolling-auto" ], [ ".p-0", ".p-1", ".p-2", ".p-3", ".p-4", ".p-5", ".p-6", ".p-8", ".p-10", ".p-12", ".p-16", ".p-20", ".p-24", ".p-32", ".p-40", ".p-48", ".p-56", ".p-64", ".p-px", ".py-0", ".px-0", ".py-1", ".px-1", ".py-2", ".px-2", ".py-3", ".px-3", ".py-4", ".px-4", ".py-5", ".px-5", ".py-6", ".px-6", ".py-8", ".px-8", ".py-10", ".px-10", ".py-12", ".px-12", ".py-16", ".px-16", ".py-20", ".px-20", ".py-24", ".px-24", ".py-32", ".px-32", ".py-40", ".px-40", ".py-48", ".px-48", ".py-56", ".px-56", ".py-64", ".px-64", ".py-px", ".px-px", ".pt-0", ".pr-0", ".pb-0", ".pl-0", ".pt-1", ".pr-1", ".pb-1", ".pl-1", ".pt-2", ".pr-2", ".pb-2", ".pl-2", ".pt-3", ".pr-3", ".pb-3", ".pl-3", ".pt-4", ".pr-4", ".pb-4", ".pl-4", ".pt-5", ".pr-5", ".pb-5", ".pl-5", ".pt-6", ".pr-6", ".pb-6", ".pl-6", ".pt-8", ".pr-8", ".pb-8", ".pl-8", ".pt-10", ".pr-10", ".pb-10", ".pl-10", ".pt-12", ".pr-12", ".pb-12", ".pl-12", ".pt-16", ".pr-16", ".pb-16", ".pl-16", ".pt-20", ".pr-20", ".pb-20", ".pl-20", ".pt-24", ".pr-24", ".pb-24", ".pl-24", ".pt-32", ".pr-32", ".pb-32", ".pl-32", ".pt-40", ".pr-40", ".pb-40", ".pl-40", ".pt-48", ".pr-48", ".pb-48", ".pl-48", ".pt-56", ".pr-56", ".pb-56", ".pl-56", ".pt-64", ".pr-64", ".pb-64", ".pl-64", ".pt-px", ".pr-px", ".pb-px", ".pl-px" ], [ ".placeholder-transparent::placeholder", ".placeholder-black::placeholder", ".placeholder-white::placeholder", ".placeholder-gray-100::placeholder", ".placeholder-gray-200::placeholder", ".placeholder-gray-300::placeholder", ".placeholder-gray-400::placeholder", ".placeholder-gray-500::placeholder", ".placeholder-gray-600::placeholder", ".placeholder-gray-700::placeholder", ".placeholder-gray-800::placeholder", ".placeholder-gray-900::placeholder", ".placeholder-red-100::placeholder", ".placeholder-red-200::placeholder", ".placeholder-red-300::placeholder", ".placeholder-red-400::placeholder", ".placeholder-red-500::placeholder", ".placeholder-red-600::placeholder", ".placeholder-red-700::placeholder", ".placeholder-red-800::placeholder", ".placeholder-red-900::placeholder", ".placeholder-orange-100::placeholder", ".placeholder-orange-200::placeholder", ".placeholder-orange-300::placeholder", ".placeholder-orange-400::placeholder", ".placeholder-orange-500::placeholder", ".placeholder-orange-600::placeholder", ".placeholder-orange-700::placeholder", ".placeholder-orange-800::placeholder", ".placeholder-orange-900::placeholder", ".placeholder-yellow-100::placeholder", ".placeholder-yellow-200::placeholder", ".placeholder-yellow-300::placeholder", ".placeholder-yellow-400::placeholder", ".placeholder-yellow-500::placeholder", ".placeholder-yellow-600::placeholder", ".placeholder-yellow-700::placeholder", ".placeholder-yellow-800::placeholder", ".placeholder-yellow-900::placeholder", ".placeholder-green-100::placeholder", ".placeholder-green-200::placeholder", ".placeholder-green-300::placeholder", ".placeholder-green-400::placeholder", ".placeholder-green-500::placeholder", ".placeholder-green-600::placeholder", ".placeholder-green-700::placeholder", ".placeholder-green-800::placeholder", ".placeholder-green-900::placeholder", ".placeholder-teal-100::placeholder", ".placeholder-teal-200::placeholder", ".placeholder-teal-300::placeholder", ".placeholder-teal-400::placeholder", ".placeholder-teal-500::placeholder", ".placeholder-teal-600::placeholder", ".placeholder-teal-700::placeholder", ".placeholder-teal-800::placeholder", ".placeholder-teal-900::placeholder", ".placeholder-blue-100::placeholder", ".placeholder-blue-200::placeholder", ".placeholder-blue-300::placeholder", ".placeholder-blue-400::placeholder", ".placeholder-blue-500::placeholder", ".placeholder-blue-600::placeholder", ".placeholder-blue-700::placeholder", ".placeholder-blue-800::placeholder", ".placeholder-blue-900::placeholder", ".placeholder-indigo-100::placeholder", ".placeholder-indigo-200::placeholder", ".placeholder-indigo-300::placeholder", ".placeholder-indigo-400::placeholder", ".placeholder-indigo-500::placeholder", ".placeholder-indigo-600::placeholder", ".placeholder-indigo-700::placeholder", ".placeholder-indigo-800::placeholder", ".placeholder-indigo-900::placeholder", ".placeholder-purple-100::placeholder", ".placeholder-purple-200::placeholder", ".placeholder-purple-300::placeholder", ".placeholder-purple-400::placeholder", ".placeholder-purple-500::placeholder", ".placeholder-purple-600::placeholder", ".placeholder-purple-700::placeholder", ".placeholder-purple-800::placeholder", ".placeholder-purple-900::placeholder", ".placeholder-pink-100::placeholder", ".placeholder-pink-200::placeholder", ".placeholder-pink-300::placeholder", ".placeholder-pink-400::placeholder", ".placeholder-pink-500::placeholder", ".placeholder-pink-600::placeholder", ".placeholder-pink-700::placeholder", ".placeholder-pink-800::placeholder", ".placeholder-pink-900::placeholder" ], [ ".pointer-events-none", ".pointer-events-auto" ], [ ".static", ".fixed", ".absolute", ".relative", ".sticky" ], [ ".inset-0", ".inset-auto", ".inset-y-0", ".inset-x-0", ".inset-y-auto", ".inset-x-auto", ".top-0", ".right-0", ".bottom-0", ".left-0", ".top-auto", ".right-auto", ".bottom-auto", ".left-auto" ], [ ".resize-none", ".resize-y", ".resize-x", ".resize" ], [ ".shadow", ".shadow-md", ".shadow-lg", ".shadow-xl", ".shadow-2xl", ".shadow-inner", ".shadow-outline", ".shadow-none" ], [ ".fill-current" ], [ ".stroke-current" ], [ ".table-auto", ".table-fixed" ], [ ".text-left", ".text-center", ".text-right", ".text-justify" ], [ ".text-transparent", ".text-black", ".text-white", ".text-gray-100", ".text-gray-200", ".text-gray-300", ".text-gray-400", ".text-gray-500", ".text-gray-600", ".text-gray-700", ".text-gray-800", ".text-gray-900", ".text-red-100", ".text-red-200", ".text-red-300", ".text-red-400", ".text-red-500", ".text-red-600", ".text-red-700", ".text-red-800", ".text-red-900", ".text-orange-100", ".text-orange-200", ".text-orange-300", ".text-orange-400", ".text-orange-500", ".text-orange-600", ".text-orange-700", ".text-orange-800", ".text-orange-900", ".text-yellow-100", ".text-yellow-200", ".text-yellow-300", ".text-yellow-400", ".text-yellow-500", ".text-yellow-600", ".text-yellow-700", ".text-yellow-800", ".text-yellow-900", ".text-green-100", ".text-green-200", ".text-green-300", ".text-green-400", ".text-green-500", ".text-green-600", ".text-green-700", ".text-green-800", ".text-green-900", ".text-teal-100", ".text-teal-200", ".text-teal-300", ".text-teal-400", ".text-teal-500", ".text-teal-600", ".text-teal-700", ".text-teal-800", ".text-teal-900", ".text-blue-100", ".text-blue-200", ".text-blue-300", ".text-blue-400", ".text-blue-500", ".text-blue-600", ".text-blue-700", ".text-blue-800", ".text-blue-900", ".text-indigo-100", ".text-indigo-200", ".text-indigo-300", ".text-indigo-400", ".text-indigo-500", ".text-indigo-600", ".text-indigo-700", ".text-indigo-800", ".text-indigo-900", ".text-purple-100", ".text-purple-200", ".text-purple-300", ".text-purple-400", ".text-purple-500", ".text-purple-600", ".text-purple-700", ".text-purple-800", ".text-purple-900", ".text-pink-100", ".text-pink-200", ".text-pink-300", ".text-pink-400", ".text-pink-500", ".text-pink-600", ".text-pink-700", ".text-pink-800", ".text-pink-900" ], [ ".text-xs", ".text-sm", ".text-base", ".text-lg", ".text-xl", ".text-2xl", ".text-3xl", ".text-4xl", ".text-5xl", ".text-6xl" ], [ ".italic", ".not-italic" ], [ ".uppercase", ".lowercase", ".capitalize", ".normal-case" ], [ ".underline", ".line-through", ".no-underline" ], [ ".antialiased", ".subpixel-antialiased" ], [ ".tracking-tighter", ".tracking-tight", ".tracking-normal", ".tracking-wide", ".tracking-wider", ".tracking-widest" ], [ ".select-none", ".select-text", ".select-all", ".select-auto" ], [ ".align-baseline", ".align-top", ".align-middle", ".align-bottom", ".align-text-top", ".align-text-bottom" ], [ ".visible", ".invisible" ], [ ".whitespace-normal", ".whitespace-no-wrap", ".whitespace-pre", ".whitespace-pre-line", ".whitespace-pre-wrap" ], [ ".break-normal", ".break-words", ".break-all", ".truncate" ], [ ".w-0", ".w-1", ".w-2", ".w-3", ".w-4", ".w-5", ".w-6", ".w-8", ".w-10", ".w-12", ".w-16", ".w-20", ".w-24", ".w-32", ".w-40", ".w-48", ".w-56", ".w-64", ".w-auto", ".w-px", ".w-1\\/2", ".w-1\\/3", ".w-2\\/3", ".w-1\\/4", ".w-2\\/4", ".w-3\\/4", ".w-1\\/5", ".w-2\\/5", ".w-3\\/5", ".w-4\\/5", ".w-1\\/6", ".w-2\\/6", ".w-3\\/6", ".w-4\\/6", ".w-5\\/6", ".w-1\\/12", ".w-2\\/12", ".w-3\\/12", ".w-4\\/12", ".w-5\\/12", ".w-6\\/12", ".w-7\\/12", ".w-8\\/12", ".w-9\\/12", ".w-10\\/12", ".w-11\\/12", ".w-full", ".w-screen" ], [ ".z-0", ".z-10", ".z-20", ".z-30", ".z-40", ".z-50", ".z-auto" ] ] ] } ```

Here's what the new version of the file could look like.

// .src/processTailwindFeatures.js

import _ from 'lodash'
import postcss from 'postcss'

import fs from 'fs'

import substituteTailwindAtRules from './lib/substituteTailwindAtRules'
import evaluateTailwindFunctions from './lib/evaluateTailwindFunctions'
import substituteVariantsAtRules from './lib/substituteVariantsAtRules'
import substituteResponsiveAtRules from './lib/substituteResponsiveAtRules'
import substituteScreenAtRules from './lib/substituteScreenAtRules'
import substituteClassApplyAtRules from './lib/substituteClassApplyAtRules'

import corePlugins from './corePlugins'
import processPlugins from './util/processPlugins'

export default function(getConfig) {
  return function(css) {
    const config = getConfig()
    const processedPlugins = processPlugins([...corePlugins(config), ...config.plugins], config)

    const classes = Object.entries(processedPlugins)
      .map(([feature, postcssThings]) => {
        if (feature === 'base') return []
        return (_.isArray(postcssThings) ? postcssThings : []).map(thing => {
          return thing.nodes.map(node => node.selector)
        })
      })
      .filter(array => array.length) // Filters empty arrays from `base` and `variantGenerators`

    fs.writeFile(`tailwind.classes.map.json`, JSON.stringify({ classes }, null, 2), () => {})

    return postcss([
      substituteTailwindAtRules(config, processedPlugins),
      evaluateTailwindFunctions(config),
      substituteVariantsAtRules(config, processedPlugins),
      substituteResponsiveAtRules(config),
      substituteScreenAtRules(config),
      substituteClassApplyAtRules(config, processedPlugins.utilities),
    ]).process(css, { from: _.get(css, 'source.input.file') })
  }
}

I was also looking into how to group those classes by plugin. It seems like this is going to be a little harder to solve because even if core plugins are named (name is not accessible right now but it's just a matter of passing it around until you save it on the produced postcss AST), third-party plugins are not.

We could probably solve this partially if plugin authors add a name key to the plugin object syntax that will be introduced with v1.2.0.

innocenzi commented 4 years ago

This is a really good start, but unfortunately plugin names are required for the headwind.groupBy configuration idea. :(

But with that list, it sounds like a lot more if possible with the plugin (notably the customFirst and separator options). Good work 👍

praveenperera commented 4 years ago

What if we mimic the order from the actual generated css? I think @adamwathan suggested this in discord too.

buffalom commented 4 years ago

What if we just used a regex for each item in the sortOrder config? Within each regex for simplicity maybe just sort by string asc?

Might be too complicated and not controllable enough again though.

What do you think about something like that:

"headwind.defaultSortOrder": [
    "container",
    "m-([0-9]|auto|px)",
    "mx-([0-9]|auto|px)",
    "ml-([0-9]|auto|px)",
    "mr-([0-9]|auto|px)",
    "my-([0-9]|auto|px)",
    "mt-([0-9]|auto|px)",
    "mb-([0-9]|auto|px)",
    "-m-([0-9]|auto|px)",
    ...
    "p-([0-9]|auto|px)",
    ...
]
devalnor commented 4 years ago

+1

felix-bohlin commented 2 years ago

Hi there! Super plugin!

Is there a way to just sort everything alphabetically? Not sure if that goes against the whole "opinionated" ethos.

ksample89 commented 2 years ago

Looking for the same @Flerox !

DevDhaif commented 2 years ago

@Flerox @ksample89 you could go to settings UI then search for headwind then click on Edit in settings.json then copy the headwind.defaultSortOrder array which is about 1800 lines, then go to any websites that could sort words alphabetically like https://alphabetizer.flap.tv/ paste and alphabetize then replace the old array with the new sorted one. Note: You might need to reload the extension.