Skip to content

Commit

Permalink
Merge pull request #4562 from alphagov/match-media
Browse files Browse the repository at this point in the history
Use CSS custom properties for component `matchMedia()`
  • Loading branch information
colinrotherham committed Dec 15, 2023
2 parents 1d26626 + 05b819a commit 3baa804
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 15 deletions.
21 changes: 21 additions & 0 deletions packages/govuk-frontend/src/govuk/common/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,27 @@ export function getFragmentFromUrl(url) {
return url.split('#').pop()
}

/**
* Get GOV.UK Frontend breakpoint value from CSS custom property
*
* @private
* @param {string} name - Breakpoint name
* @returns {{ property: string, value?: string }} Breakpoint object
*/
export function getBreakpoint(name) {
const property = `--govuk-frontend-breakpoint-${name}`

// Get value from `<html>` with breakpoints on CSS :root
const value = window
.getComputedStyle(document.documentElement)
.getPropertyValue(property)

return {
property,
value: value || undefined
}
}

/**
* Move focus to element
*
Expand Down
40 changes: 30 additions & 10 deletions packages/govuk-frontend/src/govuk/components/header/header.mjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { getBreakpoint } from '../../common/index.mjs'
import { ElementError } from '../../errors/index.mjs'
import { GOVUKFrontendComponent } from '../../govuk-frontend-component.mjs'

Expand Down Expand Up @@ -83,23 +84,42 @@ export class Header extends GOVUKFrontendComponent {
this.$menu = $menu
this.$menuButton = $menuButton

// Set the matchMedia to the govuk-frontend desktop breakpoint
this.mql = window.matchMedia('(min-width: 48.0625em)')
this.setupResponsiveChecks()

this.$menuButton.addEventListener('click', () =>
this.handleMenuButtonClick()
)
}

/**
* Setup viewport resize check
*
* @private
*/
setupResponsiveChecks() {
const breakpoint = getBreakpoint('desktop')

if (!breakpoint.value) {
throw new ElementError({
componentName: 'Header',
identifier: `CSS custom property (\`${breakpoint.property}\`) on pseudo-class \`:root\``
})
}

// Media query list for GOV.UK Frontend desktop breakpoint
this.mql = window.matchMedia(`(min-width: ${breakpoint.value})`)

// MediaQueryList.addEventListener isn't supported by Safari < 14 so we need
// to be able to fall back to the deprecated MediaQueryList.addListener
if ('addEventListener' in this.mql) {
this.mql.addEventListener('change', () => this.syncState())
this.mql.addEventListener('change', () => this.checkMode())
} else {
// @ts-expect-error Property 'addListener' does not exist
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
this.mql.addListener(() => this.syncState())
this.mql.addListener(() => this.checkMode())
}

this.syncState()
this.$menuButton.addEventListener('click', () =>
this.handleMenuButtonClick()
)
this.checkMode()
}

/**
Expand All @@ -112,7 +132,7 @@ export class Header extends GOVUKFrontendComponent {
*
* @private
*/
syncState() {
checkMode() {
if (!this.mql || !this.$menu || !this.$menuButton) {
return
}
Expand Down Expand Up @@ -142,7 +162,7 @@ export class Header extends GOVUKFrontendComponent {
*/
handleMenuButtonClick() {
this.menuIsOpen = !this.menuIsOpen
this.syncState()
this.checkMode()
}

/**
Expand Down
14 changes: 12 additions & 2 deletions packages/govuk-frontend/src/govuk/components/tabs/tabs.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getFragmentFromUrl } from '../../common/index.mjs'
import { getBreakpoint, getFragmentFromUrl } from '../../common/index.mjs'
import { ElementError } from '../../errors/index.mjs'
import { GOVUKFrontendComponent } from '../../govuk-frontend-component.mjs'

Expand Down Expand Up @@ -105,7 +105,17 @@ export class Tabs extends GOVUKFrontendComponent {
* @private
*/
setupResponsiveChecks() {
this.mql = window.matchMedia('(min-width: 40.0625em)')
const breakpoint = getBreakpoint('tablet')

if (!breakpoint.value) {
throw new ElementError({
componentName: 'Tabs',
identifier: `CSS custom property (\`${breakpoint.property}\`) on pseudo-class \`:root\``
})
}

// Media query list for GOV.UK Frontend tablet breakpoint
this.mql = window.matchMedia(`(min-width: ${breakpoint.value})`)

// MediaQueryList.addEventListener isn't supported by Safari < 14 so we need
// to be able to fall back to the deprecated MediaQueryList.addListener
Expand Down
2 changes: 1 addition & 1 deletion packages/govuk-frontend/src/govuk/core/_all.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import "govuk-frontend-version";
@import "govuk-frontend-properties";
@import "links";
@import "lists";
@import "typography";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@
// This variable is automatically overwritten during builds and releases.
// It doesn't need to be updated manually.
--govuk-frontend-version: "development";

// CSS custom property for each breakpoint
@each $name, $value in $govuk-breakpoints {
--govuk-frontend-breakpoint-#{$name}: #{govuk-px-to-rem($value)};
}
}
14 changes: 12 additions & 2 deletions packages/govuk-frontend/tasks/build/release.unit.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,18 @@ describe('dist/', () => {
)
})

it('should contain version number custom property', () => {
it('should contain CSS custom properties', () => {
// GOV.UK Frontend version number
expect(stylesheet).toContain(`--govuk-frontend-version:"${pkg.version}"`)

// Breakpoints for `window.matchMedia()` in Header, Tabs components
expect(stylesheet).toContain('--govuk-frontend-breakpoint-mobile:20rem')
expect(stylesheet).toContain(
'--govuk-frontend-breakpoint-tablet:40.0625rem'
)
expect(stylesheet).toContain(
'--govuk-frontend-breakpoint-desktop:48.0625rem'
)
})
})

Expand All @@ -70,7 +80,7 @@ describe('dist/', () => {
'../packages/govuk-frontend/src/govuk/all.scss'
)
expect(sourcemap.sources).toContain(
'../packages/govuk-frontend/src/govuk/core/_govuk-frontend-version.scss'
'../packages/govuk-frontend/src/govuk/core/_govuk-frontend-properties.scss'
)
})
})
Expand Down

0 comments on commit 3baa804

Please sign in to comment.