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 tabindex and focus states to code blocks #215

Merged
merged 6 commits into from
Mar 12, 2021

Conversation

richardTowers
Copy link
Contributor

@richardTowers richardTowers commented Mar 11, 2021

This is required for accessibility reasons. Because some code blocks have scrollbars they need to be focusable using a keyboard.

I've copied the styles from the design system's documentation (see the code blocks in the HTML / Nunjucks tabs here: https://design-system.service.gov.uk/components/button/)

The implementation is simple when syntax highlighting is not enabled, because we can simply implement block_code to surround the code with the markup we want.

When syntax highlighting is enabled it's a bit more complicated. Middleman already includes its own implementation of block_code, which renders the source code highlighted with spans. This method doesn't look like it would be easy to customise, so instead I've resorted to post-processing the HTML (i.e. replacing the attributes on the <pre> tag using a regex).

Testing this was a bit tricky, because you need to monkey patch the class to include the block_code method. I had to clone the class and patch the clone to do avoid affecting other tests.

Example from a locally running version of the paas tech docs:

image


⚠️ Don't forget to update the gem version in the CHANGELOG before merging! When you're ready to release bump version file and generate a tag. ⚠️

@richardTowers richardTowers changed the base branch from master to table-row-headings March 11, 2021 14:51
Base automatically changed from table-row-headings to master March 12, 2021 13:04
This is required for accessibility reasons. Because some code blocks
have scrollbars they need to be focusable using a keyboard.

I've copied the styles from the design system's documentation (see the
code blocks in the HTML / Nunjucks tabs here: https://design-system.service.gov.uk/components/button/)

The implementation is simple when syntax highlighting is not enabled,
because we can simply implement `block_code` to surround the code with
the markup we want.

When syntax highlighting is enabled it's a bit more complicated.
Middleman already `include`s its own implementation of `block_code`,
which renders the source code highlighted with spans. This method
doesn't look like it would be easy to customise, so instead I've
resorted to post-processing the HTML (i.e. replacing the attributes on
the `<pre>` tag using a regex).

Testing this was a bit tricky, because you need to monkey patch the
class to include the `block_code` method. I had to clone the class and
patch the clone to do avoid affecting other tests.
This doesn't change the CSS generated, but makes it a bit clearer why
the padding is 13px in the focus state and 15px otherwise. It should
also make it easier to keep in sync with future changes to padding /
borders.
We don't need to call processor.render in every test, as it's always
called with the same arguments. That means it can be pulled out into a
`let` block.

Moving the code block tests into the top level describe lets us use
described_class in the tests, which cuts down on a bit of syntax noise.

We can get a bit clever by only replacing `processor` and not `output`
in the "with syntax highlighting" case - the test will use the `output`
block from `describe "#render a code block"`, but with the `processor`
from `describe "with syntax highlighting"`
Copy link
Contributor

@AlanGabbianelli AlanGabbianelli left a comment

Choose a reason for hiding this comment

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

Looks good 👍
Just a note on the test organisation and semantic. It would be easier to follow with a couple of minor changes:

  • only one describe block to describe what you're testing
  • two context blocks to specify the conditions of the tests

It would look something like this:

  describe "#render a code block" do
  	context "without syntax highlighting" do
      # setup for conditions without syntax highlighting

      it "sets tab index to 0"

      it "renders the code without syntax highlighting"

    context "with syntax highlighting" do
      # setup for conditions with syntax highlighting

      it "sets tab index to 0"

      it "renders the code with syntax highlighting"
    end
  end

- one describe block to describe what you're testing
- context blocks to specify the conditions of the tests
@richardTowers
Copy link
Contributor Author

Thanks! Addressed in a0c9bfd

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.

3 participants