Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Tag component #4

Merged
merged 6 commits into from
Aug 29, 2020
Merged

Add Tag component #4

merged 6 commits into from
Aug 29, 2020

Conversation

tijmenb
Copy link
Contributor

@tijmenb tijmenb commented May 5, 2020

Quick PR to discuss some patterns and approaches.

@@ -0,0 +1,3 @@
<strong class="govuk-tag <%= css_classes %>">
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For Apply we need to add a custom CSS class. Do we skip doing that for now?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

end

def css_classes
@colour ? "govuk-tag--#{@colour}" : ''
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we validate the colours?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or should we just allow passing in classes like the nunjucks macro?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The angle I took with the form builder was to provide arguments for the documented features of a component. Here's a relevant example for configuring input width; in this case as a user, I'd probably want to be able to call something like Tag::TagComponent.new(text: 'Danger', colour: 'red').

Copy link
Collaborator

@tvararu tvararu May 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are mixed feelings on this. @adamsilver once tried doing something custom with a component in the Form builder that wasn't possible because you couldn't pass in custom classes. I ended up submitting a patch upstream: x-govuk/govuk-form-builder#96

The design system does allow you to pass custom classes for most of its components, and I think it's to allow users to break encapsulation where it's necessary, such as defining new variants of a component that are not yet upstream.

I think it makes sense to allow not only passing in classes but also providing smart arguments that interpret the specification in order to make components easy to use. So though it's more hard work, I think all 3 of these have their use-cases, and should be supported:

GovukComponent::Tag.new(text: 'Danger', colour: 'red')

GovukComponent::Tag.new(text: 'Danger', colour: 'danger')

GovukComponent::Tag.new(text: 'Danger', classes: 'govuk-tag--red')

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If anything, the 'danger' semantic variant could be dropped, I think it's the least important.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What makes the nunjuck macros great is that they also allow you to pass in additional html attributes and the fixability it brings. Heres some standards they use to determine the API for components. I think we should inherit this to help use keep this gem up to date when the govuk-frontend makes breaking changes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Nunjucks macros are powerful and flexible but I'm really not a fan of passing in strings of HTML. Invariably, from experience, you just end up with HTML in a string in a block of JavaScript/Ruby in a HTML(-like) template.

Comment on lines 9 to 14
expect(html).to eql(<<~html
<strong class="govuk-tag govuk-tag--green">
Alert
</strong>
html
)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is different from the existing tests. I wonder if this makes it easier to check whether or not the HTML is correctly formed. For me this was easier to do then translating it into have_css assertions like the previous tests.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is similar to Jest inline snapshots from the JavaScript world, can confirm it is a very efficient and sane way for testing small blocks of HTML or JSON.

One difference is that jest (rspec equivalent) gives you a button (jest --updateSnapshot) to update all out of date snapshots, which makes refactoring tests en-masse very easy for banal changes.

Copy link
Member

@peteryates peteryates May 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tend to lean towards the have_css approach because it's ignorant of whitespace, indentation etc.

expect(html).to have_css('strong', class: 'govuk-tag govuk-tag--green', text: 'Alert')

On smaller, simpler components matching the HTML exactly works well and is readable, this is fine by me

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah agree re: whitespace @peteryates. That's where having a tool do it for you comes in really handy.

(This exists but it doesn't look maintained https://github.com/yesmeck/rspec-snapshot)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 If we render the components on a page we could use jest to snapshot the component. We could go one step further and do some visual regression testing using jest-image-snapshot (developed by american express) https://www.npmjs.com/package/jest-image-snapshot

@aliuk2012
Copy link
Contributor

These are the params that govuk-frontend nunjuck macro accepts https://github.com/alphagov/govuk-frontend/blob/master/src/govuk/components/tag/tag.yaml#L1-L17

@peteryates peteryates mentioned this pull request May 18, 2020
21 tasks
@peteryates
Copy link
Member

I've rebased the above work and modernised it a bit and made it consistent with other components, plus added to the examples page.

Screenshot from 2020-08-28 11-31-17

@adamsilver
Copy link

@peteryates you don't need to (and shouldn't) capitalise the text, the CSS styling takes care of that.

@peteryates
Copy link
Member

peteryates commented Aug 28, 2020

@adamsilver capitalize only changes the first letter here, so red becomes Red in the output HTML. However I agree it's unnecessary, I'll remove it.

It's unnecessary and displayed in uppercase on the page anyway.
@peteryates peteryates marked this pull request as ready for review August 29, 2020 10:00
@peteryates peteryates merged commit 5cb12b9 into master Aug 29, 2020
@peteryates peteryates deleted the add-tag-component branch August 29, 2020 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants