Macros abstract our class names, if we were to change our class names, macro usage would break for our users.
In our button examples, we pass the internal button modifier class to make a button into a start button.
We could consider passing a boolean instead so that if we choose to change how our classes work, macros still function.
For example instead of
- name: start
data:
text: Start now button
classes: 'govuk-c-button--start'
We could do:
- name: start
data:
text: Start now button
start: true
See also the GOV.UK Publishing component: http://govuk-static.herokuapp.com/component-guide/button/start_now_button
We constructed the class based on booleans, then finally merge with classes and inject into the markup.
Edit:
I put together an example showing how you can restructure the macro to avoid the confusing forking logic.
This approach only forks on individual parts of the template, which is easier to reason about.
https://glitch.com/edit/#!/flag-based-macro-approach?path=views/index.html:15:26
we wen't through this discussion when we standardised component api, previous version of button macro had boolean (https://github.com/alphagov/govuk-frontend/commit/4559379446391bfcfb8ef620ff987c0b183ba63d#diff-c8d55831d340874284fc322fd388fca6R14)
That was clashing with other components where boolean wouldn't work
yeh at the time we thought MVP, classes will work. However @nickcolley makes a good point, that this is fragile - if we ever change our class names, it would break.
we also discussed something like
variant: 'start'
which is more flexible
Interesting idea, we could consider modifier: 'start' if we wanted to align with BEM.
I think the reason I prefer Boolean flags is that you may want to do other things than just add a modifier class.
@igloosi can you explain what you mean? The commit you linked to doesn't make it clear why that does not work.
A good example of where the convention 'breaks' is the way the list component used to work - there are multiple boolean possibilities but only one of them is possible at a time and the order of precedence is undefined.
I think we discussed moving to a 'modifier' approach but it's not always clear how that would work if you wanted to legitimately 'combine' modifiers - e.g. perhaps a label that is both --bold and --large and so we went with the simplest option which was to use the classes functionality we needed to provide anyway.
I think a modifiers list of strings could provide all of the benefits of classes without the drawback of having to specify fragile classnames.
Start button example:
{{ govukButton({text: "Start now button", modifiers: "start"}) }}
Large, bold label (fictional) example:
{{ govukLabel({text: "Some label", modifiers: "large bold"}) }}
I don't know how powerful nunjucks' macro system is mind you...
Closing this for now – let's see if this is something that comes up in user research or once we've got some experience rolling out breaking changes.
Two more use cases raised #1150 and #1151.
Just to add why this would be important for us -
This is an interesting proposal, but we'd need to decide which of the many classes that it's possible to legitimately apply to a component should be turned into parameters. And of course, a new parameter, no matter how simple, is a new thing for users to discover and remember.
Most helpful comment
Two more use cases raised #1150 and #1151.