Make milestone page tabs Pajamas-compliant
What does this MR do and why?
This MR does three things that are linked:
- Removes
role
attributes ingl_tabs_nav
andgl_tab_link_to
helpers.- This is because the tab* roles are meant to be used for dynamic tabs. These helpers, on
their own, only create a nav that looks like tabs, and so should not
define these roles. Also, there were no
role="tab"
descendants, which broke these roles anyway.
- This is because the tab* roles are meant to be used for dynamic tabs. These helpers, on
their own, only create a nav that looks like tabs, and so should not
define these roles. Also, there were no
- Implements a new JS class for managing tabs created by the above helpers.
- This is similar to Bootstrap's tab behaviour that we use (e.g., via
data-toggle="tab"
). See below for more discussion of this.
- This is similar to Bootstrap's tab behaviour that we use (e.g., via
- Migrate the project/group milestone page's tabs to the Rails helpers and this new JS behaviour.
Why a new JS class for behaviour instead of migrating to Vue?
We have a number of tab implementations written in HAML that rely on Bootstrap's JS for interactivity. We want to migrate them to be Pajamas-compliant. We could do this in two ways:
- Rewrite the tabs/pages in Vue (using
@gitlab/ui
'sGlTabs
component) - Write our own small script to make them interactive.
If the entire page were rewritten in Vue, that would obviously be a lot of work. If only the tabs were ported, then somehow the Vue app for the tabs would need to be aware of HAML markup elsewhere in the page, which would be a rather awkward architecture. If and when the entire page were rewritten in Vue, that architecture would have to be replaced/removed anyway.
So, the simplest solution to make our existing tabs Pajamas-compliant is to reimplement something like Bootstrap's JS for tabs, made suitable for our needs/styling.
Why the different API style compared to Bootstrap?
Bootstrap relies on document-bound event delegation and data-toggle
attributes for hooks, and dynamically instantiates for elements found. The JS class added here must be explicitly instantiated each time.
This difference allows us to:
- more easily track usage (less magic, explicit/greppable references)
- augment the DOM for improved accessibility at page load, rather than when the user first iteracts with the element, which would be too late.
Screenshots or screen recordings
Before | After |
---|---|
before | after |
How to set up and validate locally
- Check out this MR
- Visit the Project or Group milestone page (e.g.,
/gitlab-org/gitlab-shell/-/milestones/4
)
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.