From 686a08762a4bfb790b80aabdf7021f58b44fd305 Mon Sep 17 00:00:00 2001 From: Patrick Cartlidge Date: Thu, 2 May 2024 10:46:20 +0100 Subject: [PATCH] Fix input value not being set if the value was '0' Fixes #4669. Input component now uses govukAttributes macro to validate and format attributes. Test and example added for edge case outlined in issue #4669. Co-authored-by: Colin Rotherham --- CHANGELOG.md | 1 + nothing | 177 ++++++++++++++++++ .../src/govuk/components/input/input.yaml | 8 + .../src/govuk/components/input/template.njk | 64 ++++++- .../govuk/components/input/template.test.js | 7 + 5 files changed, 247 insertions(+), 10 deletions(-) create mode 100644 nothing diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c7d6a7ce1..774b9cabf8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ We've made fixes to GOV.UK Frontend in the following pull requests: - [#4942: Remove duplicate `errorMessage` argument for the password input component](https://github.com/alphagov/govuk-frontend/pull/4942) - thanks to [Tim South](https://github.com/tim-s-ccs) for contributing this change - [#4961: Fix tree-shaking when importing `govuk-frontend`](https://github.com/alphagov/govuk-frontend/pull/4961) +- [#4963: Fix input value not being set if the value was '0'](https://github.com/alphagov/govuk-frontend/pull/4963) – thanks to [@dwp-dmitri-algazin](https://github.com/dwp-dmitri-algazin) for reporting this issue ## 5.3.1 (Fix release) diff --git a/nothing b/nothing new file mode 100644 index 0000000000..7cb1e1d473 --- /dev/null +++ b/nothing @@ -0,0 +1,177 @@ +module.exports = { + extends: ['standard', 'prettier'], + ignorePatterns: [ + '**/dist/**', + '**/vendor/**', + + // Enable dotfile linting + '!.*', + 'node_modules', + 'node_modules/.*', + + // Prevent CHANGELOG history changes + 'CHANGELOG.md' + ], + overrides: [ + { + extends: [ + 'eslint:recommended', + 'plugin:import/recommended', + 'plugin:jest/style', + 'plugin:jsdoc/recommended-typescript-flavor', + 'plugin:n/recommended', + 'plugin:promise/recommended', + 'prettier' + ], + files: [ + '**/*.{cjs,js,mjs}', + + // Check markdown `*.md` contains valid code blocks + // https://github.com/eslint/eslint-plugin-markdown#advanced-configuration + '**/*.md/*.{cjs,js,mjs}' + ], + parserOptions: { + ecmaVersion: 'latest' + }, + plugins: ['import', 'jsdoc', 'n', 'promise', 'jest'], + rules: { + // Check import or require statements are A-Z ordered + 'import/order': [ + 'error', + { + alphabetize: { order: 'asc' }, + 'newlines-between': 'always' + } + ], + + // Check for valid formatting + 'jsdoc/check-line-alignment': [ + 'warn', + 'never', + { + wrapIndent: ' ' + } + ], + + // JSDoc blocks can use `@preserve` to prevent removal + 'jsdoc/check-tag-names': [ + 'warn', + { + definedTags: ['preserve'] + } + ], + + // JSDoc blocks are optional by default + 'jsdoc/require-jsdoc': 'off', + + // JSDoc @param required in (optional) blocks but + // @param description is not necessary by default + 'jsdoc/require-param-description': 'off', + 'jsdoc/require-param': 'error', + + // 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 + } + ], + + // Ignore `govuk-frontend` exports as they require auto-generated files + 'import/no-unresolved': ['error', { ignore: ['govuk-frontend'] }], + 'n/no-missing-import': ['error', { allowModules: ['govuk-frontend'] }], + 'n/no-missing-require': ['error', { allowModules: ['govuk-frontend'] }], + + // Automatically use template strings + 'no-useless-concat': 'error', + 'prefer-template': 'error', + + // Flow control – avoid continue and else blocks after return statements + // in if statements + 'no-continue': 'error', + 'no-else-return': 'error', + + // Avoid hard to read multi assign statements + 'no-multi-assign': 'error' + }, + settings: { + jsdoc: { + // Allows us to use type declarations that exist in our dependencies + mode: 'typescript' + } + } + }, + { + // Extensions required for ESM import + files: ['**/*.mjs'], + rules: { + 'import/extensions': [ + 'error', + 'always', + { + ignorePackages: true, + pattern: { + cjs: 'always', + js: 'always', + mjs: 'always' + } + } + ] + } + }, + { + files: ['**/*.test.{cjs,js,mjs}'], + env: { + jest: true + } + }, + { + // Matches Puppeteer environment in jest.config.mjs + // to ignore unknown Jest Puppeteer globals + files: ['**/*.puppeteer.test.{js,mjs}'], + globals: { + page: 'readonly', + browser: 'readonly', + jestPuppeteer: 'readonly' + } + }, + { + // Add plugin for markdown `*.md` code blocks. Its config is in the new + // "flat" format, so we need to use the legacy config + extends: ['plugin:markdown/recommended-legacy'], + files: ['**/*.md'], + plugins: ['markdown'], + processor: 'markdown/markdown' + }, + { + files: [ + '**/coding-standards/component-options.md/*.{cjs,js,mjs}', + '**/coding-standards/js.md/*.{cjs,js,mjs}' + ], + env: { + browser: true + }, + rules: { + // Ignore unused example code + 'no-new': 'off', + 'no-undef': 'off', + 'no-unused-expressions': 'off', + 'no-unused-vars': 'off', + 'no-useless-constructor': 'off', + + // Ignore paths to example modules + 'import/no-unresolved': 'off', + 'n/no-missing-import': 'off' + } + } + ], + parserOptions: { + project: './tsconfig.json' + }, + root: true +} diff --git a/packages/govuk-frontend/src/govuk/components/input/input.yaml b/packages/govuk-frontend/src/govuk/components/input/input.yaml index 439bc6a333..09c74b6fe2 100644 --- a/packages/govuk-frontend/src/govuk/components/input/input.yaml +++ b/packages/govuk-frontend/src/govuk/components/input/input.yaml @@ -399,6 +399,14 @@ examples: label: text: With value value: QQ 12 34 56 C + - name: zero value + hidden: true + options: + id: with-zero-value + name: with-zero-value + label: + text: With zero value + value: 0 - name: with describedBy hidden: true options: diff --git a/packages/govuk-frontend/src/govuk/components/input/template.njk b/packages/govuk-frontend/src/govuk/components/input/template.njk index bb4666d4ac..c3e1431aef 100644 --- a/packages/govuk-frontend/src/govuk/components/input/template.njk +++ b/packages/govuk-frontend/src/govuk/components/input/template.njk @@ -3,9 +3,20 @@ {% from "../hint/macro.njk" import govukHint %} {% from "../label/macro.njk" import govukLabel %} +{#- Set classes for this component #} +{%- set classNames = "govuk-input" -%} + +{%- if params.classes %} + {% set classNames = classNames + " " + params.classes %} +{% endif %} + +{%- if params.errorMessage %} + {% set classNames = classNames + " govuk-input--error" %} +{% endif %} + {#- a record of other elements that we need to associate with the input using aria-describedby – for example hints or error messages -#} -{% set describedBy = params.describedBy if params.describedBy else "" -%} +{% set describedBy = params.describedBy if params.describedBy else undefined -%} {%- set hasPrefix = true if params.prefix and (params.prefix.text or params.prefix.html) else false %} {%- set hasSuffix = true if params.suffix and (params.suffix.text or params.suffix.html) else false %} @@ -13,15 +24,48 @@ {%- set hasAfterInput = true if params.formGroup.afterInput and (params.formGroup.afterInput.text or params.formGroup.afterInput.html) else false %} {%- macro _inputElement(params) -%} - {%- endmacro -%} diff --git a/packages/govuk-frontend/src/govuk/components/input/template.test.js b/packages/govuk-frontend/src/govuk/components/input/template.test.js index 013b983694..d8795ba14a 100644 --- a/packages/govuk-frontend/src/govuk/components/input/template.test.js +++ b/packages/govuk-frontend/src/govuk/components/input/template.test.js @@ -71,6 +71,13 @@ describe('Input', () => { expect($component.val()).toBe('QQ 12 34 56 C') }) + it('renders with zero value', () => { + const $ = render('input', examples['zero value']) + + const $component = $('.govuk-input') + expect($component.val()).toBe('0') + }) + it('renders with aria-describedby', () => { const $ = render('input', examples['with describedBy'])