8000 Rename `SkipLinkController` to `FocusController`, update unit tests & add story by lb- · Pull Request #12555 · wagtail/wagtail · GitHub
[go: up one dir, main page]

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

Rename SkipLinkController to FocusController, update unit tests & add story #12555

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

lb-
Copy link
Member
@lb- lb- commented Nov 7, 2024

Description

The SkipLinkController was one of the first controllers implemented and as such has not adopted some of the practice that's emerged through other Stimulus adoption work.

Details

This PR introduces the following:

  1. A simpler name that reflects the behaviour not the usage of the Controller
  2. Better unit tests with a structure that's aligned with many other unit testing
  3. Better JSDoc leverage with proper @example tags
  4. Abstract the common add/remove event listener behaviour and only remove the tabindex if the target element did not have one in the first place - pull this out to a robust util forceFocus as we use this in lots of other place in the code
  5. Enhance the controller to be able to trigger focus on any targeted element, so we do not have to use it for links only, also ensure we can smooth scroll into view before triggering the focus for a better user experience
  6. Add a Story that covers the example usage for additional manual testing
  7. Add a Python unit test that covers the presence of the skip link, this is not every page but at least ensures we do not accidentally remove this code from the base admin template
  8. Fix up an issue with our stubs/adapter files so we can better test scrolling with Jest function mocks

See also #12554 (a similar, in purpose, rename & clean up effort).

How to test

Within the admin interface, once refreshed, press tab. The first target element should be the 'skip to main content' link, activating this (press enter) should move your focus away and into the main content. Pressing tab again, should focus on the first focusable element in the main content (e.g. the first link '34 pages' in the screen below).

Screenshot 2024-11-08 at 7 53 46 AM

Why this matters

Eventually we want to consider broader usage of the focus controller, either made available through documentation or for 'scroll to top' type buttons around lo 8000 nger page content. This is already a request for a different issue - #12128

This also makes it easier for us to eventually centralise the Jest testing for Stimulus controllers, the await setup pattern is super useful and makes adding future unit tests much easier.

Finally, the fact that the element's name (Link) is in the controller is a bit of an anti-pattern, any element could be used (e.g. a button) and should normally not be reflected in the controller name.

While renames seem unnecessary, without this rename it may seem like we need a different controller do do any 'focus' work, when in fact Stimulus shines when we create smaller modular 'behaviour' controllers and not usage specific ones. This aligns with our Stimulus tips, which were not really full formed when this controller was created. https://docs.wagtail.org/en/stable/contributing/ui_guidelines.html#helpful-tips

Copy link
squash-labs bot commented Nov 7, 2024

Manage this branch in Squash

Test this branch here: https://lb-cleanuprename-skip-link-con-14jdc.squash.io

@lb- lb- force-pushed the cleanup/rename-skip-link-controller-to-focus branch from 0852fc5 to 26fbe6d Compare November 7, 2024 22:19
@lb- lb- force-pushed the cleanup/rename-skip-link-controller-to-focus branch from 26fbe6d to 49e73e2 Compare November 19, 2024 20:39
@lb- lb- force-pushed the cleanup/rename-skip-link-controller-to-focus branch from 49e73e2 to 291b386 Compare December 3, 2024 07:37
Copy link
Member
@laymonage laymonage left a comment

Choose a reason for hiding this comment

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

Could you remind me why this had to use a Stimulus controller over just using the <a href tag? 🤔

@lb-
Copy link
Member Author
lb- commented Dec 3, 2024

It's just a migration from the original JS that was there (links below).

My understanding is that while a plain link can work OK, it's a better experience with the focus outline being triggered. In all the sites I've worked on, there's always been a JS behaviour attached (link or buttons vary). Update, it's so that the fragment doesn't update in the URL also, which adds unwanted history.

For context:

More than happy for us to remove the JS completely but we'd probably have to consider other implications of this and get some accessibility team input first.

@lb-
Copy link
Member Author
lb- commented Dec 3, 2024

Just updated the comment above.

@lb-
Copy link
Member Author
lb- commented Mar 8, 2025

This PR would be great to get in as it will help us build on it for supporting #12128 & #12739

@lb- lb- force-pushed the cleanup/rename-skip-link-controller-to-focus branch from 291b386 to f5ce45a Compare March 8, 2025 06:24
@lb- lb- force-pushed the cleanup/rename-skip-link-controller-to-focus branch from f5ce45a to a3b18c1 Compare March 9, 2025 00:46
@lb-
Copy link
Member Author
lb- commented Mar 9, 2025

I have updated this PR to pull out the forceFocus util to a utils file, added extra handling for scrolling, async delay for 'just created' elements and added unit tests for this. This way it can be used as is for future work on #12128 & #12739 @Srishti-j18

In addition, I have fixed up some issues with the stubs/adapter and added clearer docs at the top of the file, we were including items in subs that should have been unit tests only. Update: This is also a stand alone PR #12954

@lb-
Copy link
Member Author
lb- commented Mar 9, 2025

CI failure is unrelated to this PR.

FAIL: test_ordering_by_content_type (wagtail.admin.tests.pages.test_explorer_view.TestPageExplorer) (ordering='-content_type')
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/work/wagtail/wagtail/wagtail/admin/tests/pages/test_explorer_view.py", line 192, in test_ordering_by_content_type
    self.assertEqual(page_ids, pages)
AssertionError: Lists differ: [1094, 1095, 1093] != [1094, 1093, 1095]

First differing element 1:
1095
1093

const selector =
this.targetValue || this.element.getAttribute('href') || 'main';

this.target =
Copy link
Member Author

Choose a reason for hiding this comment

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

Note. We should move this logic to the focus method. And add a unit test for the focus target appearing after initial render.

Copy link
Member Author

Choose a reason for hiding this comment

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

Might be nice to add a unit test for an element created at the same time as the focus is clicked. This is why we want to defer by a delay. Maybe using the clone controller in the unit test.

button.focus();
expect(document.activeElement).toBe(button);

expect(element.getAttribute('tabindex')).toBe(null);
Copy link
Member Author

Choose a reason for hiding this comment

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

Add another test for an element 'just created'.

@Srishti-j18
Copy link
Contributor

Should these changes be made in this PR or in #12739? I'm a little confused since I merged all the commits from this PR into #12739.

lb- added 6 commits March 12, 2025 18:40
- Ensure Jest only adapter items are in adapter.js
- Ensure Jest AND Storybook items are in stubs.js
- Add mock for someElement.scrollIntoView in the adapter
- Update the Controller import & identifier to be `w-focus` not `w-skip-link`
- Rework methods to be easier to maintain, pull out the focus event attachment handler to a function
- Add JSDoc examples & refine description
- Only add then remove the tabindex attribute if needed
- Rework unit tests to be the emerging common structure, add unit test coverage & test for the preservation of existing tabindex attributes
@lb- lb- force-pushed the cleanup/rename-skip-link-controller-to-focus branch from a3b18c1 to 0757a19 Compare March 12, 2025 08:56
@lb-
Copy link
Member Author
lb- commented Mar 12, 2025

@Srishti-j18 I have updated this PR to include a better approach to the focus & target handling so it allows for focusing on elements that did not exist when the controller connected.

Feel free to incorporate this however you need to get your PR working reliably, we can clean up your PR later once this PR is in. I have asked for a review on this within the core team but I am not sure when that will happen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 👀 for review
Development

Successfully merging this pull request may close these issues.

3 participants
0