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

Update components to use Component #4205

Merged
merged 12 commits into from
Oct 11, 2024
Merged

Update components to use Component #4205

merged 12 commits into from
Oct 11, 2024

Conversation

patrickpatrickpatrick
Copy link
Contributor

@patrickpatrickpatrick patrickpatrickpatrick commented Oct 10, 2024

What

Make components in govuk-design-system extend Component. This means we can:

  • Rename this.$module to $this.$root in a given component
  • Remove initialisation checks that occur in Component in a given component
  • Use isSupported function to check component support in a given component

In addition, changes were needed to EmbedCard and Navigation in light of changes to how components are now initialised.

In this PR, we also add configuration for Typescript to look up .ts files, which allows us to be able to add a shorthand ambient module definition for govuk-frontend. This means Typescript/JSDoc will not throw any errors when calling this.$root in a class that extends Component.

Why

Component is now available as of v5.7.0 of govuk-frontend. We also have made changes to initialisation to prevent multi-initialisation occurring which means using body as a root module is now no longer supported.

Copy link

netlify bot commented Oct 10, 2024

You can preview this change here:

Name Link
🔨 Latest commit 04a7ba2
🔍 Latest deploy log https://app.netlify.com/sites/govuk-design-system-preview/deploys/670907de3eddac0008fa1b51
😎 Deploy Preview https://deploy-preview-4205--govuk-design-system-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@romaricpascal
Copy link
Member

Apologies for the push on this branch, that was meant for a separate PR for discussion 😬

*
* @throws {Error} when component not supported
*/
checkSupport() {
Copy link
Member

Choose a reason for hiding this comment

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

issue GOV.UK Frontend's Component will call the static checkSupport method, which is unchanged, and not run this code. It's fine to keep these checks in the constructor as they need to access this.$root 😊

@@ -48,7 +48,7 @@ createAll(Copy)
new OptionsTable()

// Initialise mobile navigation
new Navigation(document)
new Navigation(document.body)
Copy link
Member

Choose a reason for hiding this comment

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

suggestion Given the Navigation component now has a moduleName, how about adding a data-module="app-navigation" on the <body> and using createAll.

This would handle any errors thrown where GOV.UK Frontend is not supported, as those would prevent further code in this script to execute at the moment.

src/javascripts/application.mjs Show resolved Hide resolved
// Exit if we're on the cookies page to avoid circular journeys
this.onCookiesPage()
) {
return this
}

this.$cookieBanner = $module
this.$cookieBanner = this.$root
Copy link
Member

Choose a reason for hiding this comment

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

suggestion We may as well replace this.$cookieBanner by this.$root in the whole component.

if (
!($module instanceof HTMLElement) ||
!document.body.classList.contains('govuk-frontend-supported') ||
// Exit if we're on the cookies page to avoid circular journeys
this.onCookiesPage()
Copy link
Member

Choose a reason for hiding this comment

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

question If we make onCookiesPage() static or even a function in the module, could this be part of checkSupport()?


this.$page = $module
this.$page = this.$root
Copy link
Member

Choose a reason for hiding this comment

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

suggestion Similarly to the cookie-banner, I think we can use this.$root instead of this.$page across the whole component rather than assign to another instance variable.

- Rename `this.$module` to `$this.$root`
- Remove initialisation checks that occur in `Component`
 - Rename `this.$module` to `$this.$root`
 - Remove initialisation checks that occur in `Component`
 - `onCookiesPage` now a static function
 - Use `isSupported` function to check component support
- Rename `this.$module` to `$this.$root`
- Remove initialisation checks that occur in `Component`
- Rename `this.$module` to `$this.$root`
- Remove initialisation checks that occur in `Component`
- Use `isSupported` function to check component support
 - Rename `this.$module` to `$this.$root`
 - Remove initialisation checks that occur in `Component`
 - Use `isSupported` function to check component support
 - Update `EmbedCard` initialisation code in `application.mjs` to
 prevent error on multiple initialisation and catch the error thrown if
 user has not accepted campaign cookies
- Rename `this.$module` to `$this.$root`
- Remove initialisation checks that occur in `Component`
- Rename `this.$module` to `$this.$root` in `Navigation`
- Remove initialisation checks that occur in `Component` in `Navigation`
- Use `createAll` in `application.mjs` to initialise component (so that
errors thrown are caught)
- Add `data-module="app-navigation"` to `body` of page instead of
initialising `Navigation` on `document` (which is now no longer
supported due to the new initialisation method that sets attributes) so
`createAll(Navigation)` can be used
- Rename `this.$module` to `$this.$root`
- Remove initialisation checks that occur in `Component`
- Use `isSupported` function to check component support
- Rename `this.$module` to `$this.$root`
- Remove initialisation checks that occur in `Component`
- Rename `this.$module` to `$this.$root`
- Remove initialisation checks that occur in `Component`
As govuk-frontend provides no types, TypeScript will type its exports as `any`,
but be unable to acknowledge fields inherited from parent classes
leading to errors when trying to assign or use them.

TypeScript's shorthand ambient modules seem to also make inherited fields typed as `any`.
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#shorthand-ambient-module-declarations

This will override any other definition of the `govuk-frontend` module, either in another `.d.ts` file
or in `@types/govuk-frontend`.
Copy link
Member

@romaricpascal romaricpascal 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! Thanks for splitting it up component by component as well 🙌🏻 ⛵

@romaricpascal romaricpascal merged commit 25885b2 into main Oct 11, 2024
15 checks passed
@romaricpascal romaricpascal deleted the use-new-components branch October 11, 2024 14:20
@romaricpascal romaricpascal linked an issue Oct 11, 2024 that may be closed by this pull request
4 tasks
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.

Refactor existing components to use the new Component class
2 participants