Closed (fixed)
Project:
Mercury Theme
Version:
1.x-dev
Component:
Templates/PHP
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
6 Nov 2025 at 22:01 UTC
Updated:
26 Nov 2025 at 23:09 UTC
Jump to comment: Most recent
Comments
Comment #2
galactus86 commentedComment #3
galactus86 commentedComment #5
galactus86 commentedComment #6
pameeela commentedJust capturing my comments from Slack, this seems to undo the grouping that we introduced in #3556312: Group Tailwind classes in Twig for readability so just want to make sure we are all on the same page. I've asked @balintbrews to take a look and let us know what he recommends.
Comment #8
balintbrewsI realized that the way we added grouping in #3556312: Group Tailwind classes in Twig for readability doesn't communicate to
prettier-plugin-tailwindcsswhere it should look for class names to sort: Prettier runs static analysis only, so it can't figure out that what we define in a variable will end up in theclassattribute. I also missed that the class names that we would like to group together should be added as a single string rather than separate strings in an array. So what we're currently seeing is just@zackad/prettier-plugin-twigformatting the array, andprettier-plugin-tailwindcssnot recognizing that it needs to do something.→ The fix is to move the array inside the
classattribute, and keep class name groups in single strings:da5afd69.There would be a much nicer way to do this, and that is making use of the
html_cvafunction, and setting"tailwindFunctions": ["html_cva"]inprettierrc.json. Two for the price of one, we'd get sorting, because that would tellprettier-plugin-tailwindcssto sort inside the arguments of that function call, andhtml_cvawould give us a really elegant way to handle variations in the same component, so we could abandon conditionally concatenating the class names. (We already bundle CVA for Code Components in Canvas to encourage this pattern.)That all sounds awesome, but there are complications:
html_cvafromtwig-extra-bundle, and make Mercury dependent on that module.html_cva. I'm not sure what it would take to make Twing aware ofhtml_cva, and inject the implementation of the CVA JavaScript library for the rendering. Quickly scanning Twing's documentation, it doesn't seem like it's easily pluggable. So I think with this we're hitting one of the limitations of not using Drupal for rendering the stories.Comment #9
pameeela commented@balintbrews I see, thank you for sorting that! So the grouping is still something we do ourselves, but if done this way, prettier will not undo it.
I think CVA sounds like a great option, but the refactoring probably is out of scope for 1.0.
Just one other question, should we commit the other prettier fixes all at once? There are changes to almost every Twig file when I run it locallly.
Comment #10
balintbrewsRight, the grouping should be subject to opinion. Sometimes you don't even want it, other times you would want to group based on the needs of the current component.
👍
Yes, but we should also make sure that a Prettier check runs on CI, otherwise it's easy to commit without formatting. We would need scripts in
package.json, e.g.:Then we may want to add a
.prettierignorefile to exclude certain files. I was going to add all these, but I got confused, so I stopped to ask some questions.package.jsonto lint the JavaScript code with ESLint, and the CSS code with Stylelint. But I don't see config files for these. I spottedeslintConfiginpackage.json, but it's not being picked up when I runpnpm lint:js, and it fails with an error message telling us that it is missing the config file. I get a similar error when runningpnpm lint:css.We need to get these tighten up, because adding formatting with Prettier while not doing any linting and format checks on CI will be very disruptive. Imagine I want to submit an MR, and I want to format and lint my code, but I also get other files changed, because those may have been committed without any quality check.
Comment #11
balintbrewsComment #12
balintbrewsTurns out ESLint and Stylelint have never been set up for the project. Since both exclude any stylistic rules anyway in favor of Prettier, I just went ahead and added scripts to
package.jsonto work with Prettier, and added the format check as part of the newly addedlintjob.I then reformatted all files. Many of them were producing parsing errors due to techniques that static analysis tools can't work with. Fixing these also result in better readability.
Here are the types of errors I had to fix manually (marked with "⚠️ Refactored" comment in GitLab):
{{ attributes }}to HTML tags without a space. For example, instead of<div{{ attributes }}>, we need to have<div {{ attributes }}>. I won't highlight all the places where I fixed this, because this is a trivial change.components/button/button.twigandcomponents/blockquote/blockquote.twigadded attributes with inline Twig control structures ({% if %}), and/or had them directly within HTML tag attributes. I refactored those to assign values to variables.This will never be static analysis friendly. But a better reason is that it's also not very readable. A similar issue is using dynamic tag names, like
<h{{ heading_level }}>. I refactored the following files and tested manually in Canvas (not in Storybook):components/card-profile/card-profile.twigcomponents/collapsible-section/collapsible-section.twigcomponents/heading/heading.twigcomponents/menu-footer/menu-footer.twigcomponents/menu-footer/menu-footer~main.twigcomponents/menu-utility/menu-utility.twigcomponents/menu-utility/menu-utility~main.twigcomponents/pager/pager.twigtemplates/views/views-view.html.twigThe followings don't work in Canvas, so I didn't test them:
components/menu-footer/menu-footer.twig(andcomponents/menu-footer/menu-footer~main.twig)components/menu-utility/menu-utility.twig(andcomponents/menu-utility/menu-utility~main.twig)components/pager/pager.twig— This component shows up in Canvas, but it renders nothing, and it has no props or slots, so I don't understand how it's supposed to work.I manually compared how the refactored components render in Canvas to how they do in the 1.x branch, but additional testing by someone who has spent more time with them would be appreciated.
Comment #13
balintbrewsExample pipeline for a commit violating Prettier formatting rules: https://git.drupalcode.org/issue/mercury-3556548/-/pipelines/657011.
Comment #14
lanny heidbreder commentedIn general I hate to tie a design system to a specific CMS, and to require that CMS to be up and running locally to make local changes. In an official Drupal project like this, though, it might not be terrible. However, we already have a few custom Twing filters and functions (see
filters.jsandfunctions.jsinvitePlugins/twingCustoms) and it's not hard at all to use any old JS function as one. So if the PHPhtml_cvafunction conforms well to the original, we can just import that NPM package and glue it in.Also, the
tailwind_mergefilter mentioned in the Twig docs forhtml_cvais derived from an original JS version, so we can have that easily, too (though the PHP one doesn't seem to support Tailwind v4 yet, so that may be a blocker to this whole effort, depending on how vitaltailwind_mergeis in practice).Comment #15
phenaproximaComment #16
phenaproximaEverything done in this MR seems reasonable to me, but it does need a quick manual test from Pam, in the context of Byte, to make sure we didn't accidentally break any styling.
RTBC from a code review standpoint, but should not be committed until Pam confirms it's good.
Comment #17
pameeela commentedTaking a look now...
Comment #19
phenaproxima