Skip to content

Commit

Permalink
Merge pull request #2960 from alphagov/v5-classes
Browse files Browse the repository at this point in the history
Preview v5: Convert all components to ES2015 classes
  • Loading branch information
colinrotherham committed Jul 27, 2023
2 parents 1475540 + 9157877 commit f7a9918
Show file tree
Hide file tree
Showing 20 changed files with 1,093 additions and 715 deletions.
40 changes: 40 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module.exports = {
extends: [
'eslint:recommended',
'plugin:import/recommended',
'plugin:jsdoc/recommended-typescript-flavor',
'plugin:n/recommended',
'plugin:promise/recommended'
],
Expand All @@ -22,6 +23,7 @@ module.exports = {
},
plugins: [
'import',
'jsdoc',
'n',
'promise'
],
Expand All @@ -35,9 +37,47 @@ module.exports = {
}
],

// JSDoc blocks are optional
'jsdoc/require-jsdoc': 'off',
'jsdoc/require-param-description': 'off',
'jsdoc/require-param': 'off',

// Check for valid formatting
'jsdoc/check-line-alignment': [
'warn',
'never', {
wrapIndent: ' '
}
],

// Add unknown @jest-environment tag name
'jsdoc/check-tag-names': [
'warn', {
definedTags: ['jest-environment']
}
],

// Require hyphens before param description
// Aligns with TSDoc style: https://tsdoc.org/pages/tags/param/
'jsdoc/require-hyphen-before-param-description': 'warn',

// Maintain new line after description
'jsdoc/tag-lines': [
'warn',
'never', {
startLines: 1
}
],

// Automatically use template strings
'no-useless-concat': 'error',
'prefer-template': 'error'
},
settings: {
jsdoc: {
// Allows us to use type declarations that exist in our dependencies
mode: 'typescript'
}
}
},
{
Expand Down
5 changes: 2 additions & 3 deletions lib/colours.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function getColourFromSass (sass, variableName) {
* Extracts the colour palette from the $govuk-colours map defined in
* settings/_colours-palette.scss in GOV.UK Frontend
*
* @return Object mapping colour names to their hexadecimal values
* @returns Object mapping colour names to their hexadecimal values
*/

const palette = function () {
Expand Down Expand Up @@ -58,9 +58,8 @@ const palette = function () {
* }
* ```
*
* @return Object containing 'groups' of colours
* @returns {{ [color: string]: { name: string, notes?: string }[] }} Groups of colours
*/

const applied = function () {
const data = require('../data/colours.json')
const sass = parseSCSS('_colours-applied.scss')
Expand Down
1 change: 1 addition & 0 deletions lib/fingerprints/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ const hashAssets = (config) => (files, metalsmith, done) => {
*
* @param {import('metalsmith').Files} files - Metalsmith files
* @param {import('metalsmith')} metalsmith - Metalsmith builder
* @returns {(pathAsset: string) => { path: string; hash: string; }} File hasher
*/
const hashAsset = (files, metalsmith) => {
const metadata = metalsmith.metadata()
Expand Down
3 changes: 2 additions & 1 deletion lib/get-macro-options/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ function getAdditionalComponentOptions (options) {
* }
* ```
*
* */
* @returns {{ name: string, id: string, options: unknown[] }} Macro options
*/
function getMacroOptions (componentName) {
// The design system uses a different name for the input component.
if (componentName === 'text-input') {
Expand Down
4 changes: 4 additions & 0 deletions lib/marked-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class DesignSystemRenderer extends marked.Renderer {
/**
* Assume HTML when no code block language provided
* (for example, HTML code inside Markdown)
*
* @returns {string} Code block
*/
code (code, language, isEscaped) {
return !language
Expand All @@ -28,6 +30,8 @@ class DesignSystemRenderer extends marked.Renderer {

/**
* Avoid wrapping `<img>` image tags in `<p>` paragraphs
*
* @returns {string} Paragraph
*/
paragraph (text) {
return text.trim().startsWith('<img')
Expand Down
170 changes: 84 additions & 86 deletions lib/metalsmith-title-checker.js
Original file line number Diff line number Diff line change
@@ -1,86 +1,84 @@
/**
* Metalsmith plugin to check each page has a unique title.
* Which is required to make sure users of assistive technologies can navigate easily.
*
* @return {Function}
*/

function groupFilesByTitle (filenames, files) {
const groupedFiles = {}

filenames
.forEach((filename, index) => {
const { title } = files[filename]
// If an title exists and is not the current index it means it is a duplicate.
if (!groupedFiles[title]) {
groupedFiles[title] = []
}
groupedFiles[title].push({
// Add the filename to the file object for convenience
__filename: filename,
...files[filename]
})
})

return groupedFiles
}

function getDuplicateTitles (groupedFiles) {
const duplicateGroupedTitles = {}

for (const title in groupedFiles) {
const group = groupedFiles[title]

const groupedWithoutExcludedFiles =
group
// Default examples always have a duplicated title,
// this is OK since the iframes are appended with 'example'.
.filter(file => !file.__filename.includes('/default/'))
// Filter out Windows default paths too:
.filter(file => !file.__filename.includes('\\default\\'))
// Code examples always have a duplicated title,
// as it's only used for the code example not the iframe.
.filter(file => !file.__filename.endsWith('code.njk'))

if (groupedWithoutExcludedFiles.length > 1) {
duplicateGroupedTitles[title] = groupedWithoutExcludedFiles
}
}

return duplicateGroupedTitles
}

module.exports = function titleChecker () {
return (files, metalsmith, done) => {
const nunjucksFileNames =
Object
.keys(files)
// Filter files that are Nunjucks, which have frontmatter.
.filter(filename => filename.endsWith('.njk'))

const groupedFilesByTitle = groupFilesByTitle(nunjucksFileNames, files)
const filesWithDuplicateTitles = getDuplicateTitles(groupedFilesByTitle)

if (Object.keys(filesWithDuplicateTitles).length) {
let duplicateErrorMessage = ''
for (const title in filesWithDuplicateTitles) {
const group = filesWithDuplicateTitles[title]
duplicateErrorMessage += `The title "${title}" is duplicated ${group.length} times in the following file(s):\n`
duplicateErrorMessage += group.map(file => `- ${file.__filename}`).join('\n')
duplicateErrorMessage += '\n\n'
}
throw Error(duplicateErrorMessage)
}

const filesWithoutTitles = nunjucksFileNames.filter(filename => !files[filename].title)

if (filesWithoutTitles.length) {
throw Error(
`The following file(s) do not have titles:\n\n${
filesWithoutTitles.map(file => `- ${file}`).join('\n')
}\n`
)
}
done()
}
}
/**
* Metalsmith plugin to check each page has a unique title.
* Which is required to make sure users of assistive technologies can navigate easily.
*/

function groupFilesByTitle (filenames, files) {
const groupedFiles = {}

filenames
.forEach((filename, index) => {
const { title } = files[filename]
// If an title exists and is not the current index it means it is a duplicate.
if (!groupedFiles[title]) {
groupedFiles[title] = []
}
groupedFiles[title].push({
// Add the filename to the file object for convenience
__filename: filename,
...files[filename]
})
})

return groupedFiles
}

function getDuplicateTitles (groupedFiles) {
const duplicateGroupedTitles = {}

for (const title in groupedFiles) {
const group = groupedFiles[title]

const groupedWithoutExcludedFiles =
group
// Default examples always have a duplicated title,
// this is OK since the iframes are appended with 'example'.
.filter(file => !file.__filename.includes('/default/'))
// Filter out Windows default paths too:
.filter(file => !file.__filename.includes('\\default\\'))
// Code examples always have a duplicated title,
// as it's only used for the code example not the iframe.
.filter(file => !file.__filename.endsWith('code.njk'))

if (groupedWithoutExcludedFiles.length > 1) {
duplicateGroupedTitles[title] = groupedWithoutExcludedFiles
}
}

return duplicateGroupedTitles
}

module.exports = function titleChecker () {
return (files, metalsmith, done) => {
const nunjucksFileNames =
Object
.keys(files)
// Filter files that are Nunjucks, which have frontmatter.
.filter(filename => filename.endsWith('.njk'))

const groupedFilesByTitle = groupFilesByTitle(nunjucksFileNames, files)
const filesWithDuplicateTitles = getDuplicateTitles(groupedFilesByTitle)

if (Object.keys(filesWithDuplicateTitles).length) {
let duplicateErrorMessage = ''
for (const title in filesWithDuplicateTitles) {
const group = filesWithDuplicateTitles[title]
duplicateErrorMessage += `The title "${title}" is duplicated ${group.length} times in the following file(s):\n`
duplicateErrorMessage += group.map(file => `- ${file.__filename}`).join('\n')
duplicateErrorMessage += '\n\n'
}
throw Error(duplicateErrorMessage)
}

const filesWithoutTitles = nunjucksFileNames.filter(filename => !files[filename].title)

if (filesWithoutTitles.length) {
throw Error(
`The following file(s) do not have titles:\n\n${
filesWithoutTitles.map(file => `- ${file}`).join('\n')
}\n`
)
}
done()
}
}
Loading

0 comments on commit f7a9918

Please sign in to comment.