diff --git a/packages/core/package.json b/packages/core/package.json
index 2f9e42746..002761ade 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -1,7 +1,7 @@
{
"name": "@department-of-veterans-affairs/component-library",
"description": "VA.gov component library. Includes React and web components.",
- "version": "19.0.1",
+ "version": "19.1.0",
"license": "MIT",
"scripts": {
"build": "webpack"
diff --git a/packages/storybook/stories/va-number-input-uswds.stories.jsx b/packages/storybook/stories/va-number-input-uswds.stories.jsx
index dbde74ec3..721d6420c 100644
--- a/packages/storybook/stories/va-number-input-uswds.stories.jsx
+++ b/packages/storybook/stories/va-number-input-uswds.stories.jsx
@@ -11,7 +11,15 @@ export default {
docs: {
page: () => ,
},
- }
+ },
+ argTypes: {
+ inputmode: {
+ control: {
+ type: 'select',
+ options: ['decimal', 'numeric'],
+ },
+ },
+ },
};
const defaultArgs = {
@@ -21,6 +29,7 @@ const defaultArgs = {
'required': false,
'error': undefined,
'value': 0,
+ 'inputmode': 'numeric',
'min': undefined,
'max': undefined,
hint: null,
@@ -35,6 +44,7 @@ const vaNumberInput = args => {
required,
error,
value,
+ inputmode,
min,
max,
hint,
@@ -50,6 +60,7 @@ const vaNumberInput = args => {
required={required}
error={error}
value={value}
+ inputmode={inputmode}
max={max}
min={min}
hint={hint}
diff --git a/packages/storybook/stories/va-number-input.stories.jsx b/packages/storybook/stories/va-number-input.stories.jsx
index 8d5f7865a..47412b09e 100644
--- a/packages/storybook/stories/va-number-input.stories.jsx
+++ b/packages/storybook/stories/va-number-input.stories.jsx
@@ -11,7 +11,15 @@ export default {
docs: {
page: () => ,
},
- }
+ },
+ argTypes: {
+ inputmode: {
+ control: {
+ type: 'select',
+ options: ['decimal', 'numeric'],
+ },
+ },
+ },
};
const defaultArgs = {
@@ -21,6 +29,7 @@ const defaultArgs = {
'required': false,
'error': undefined,
'value': 0,
+ 'inputmode': 'numeric',
'min': undefined,
'max': undefined,
hint: null,
@@ -36,6 +45,7 @@ const vaNumberInput = args => {
required,
error,
value,
+ inputmode,
min,
max,
hint,
@@ -51,6 +61,7 @@ const vaNumberInput = args => {
required={required}
error={error}
value={value}
+ inputmode={inputmode}
max={max}
min={min}
hint={hint}
diff --git a/packages/web-components/src/components.d.ts b/packages/web-components/src/components.d.ts
index 38ab8466b..bf877fc64 100644
--- a/packages/web-components/src/components.d.ts
+++ b/packages/web-components/src/components.d.ts
@@ -678,6 +678,10 @@ export namespace Components {
* Optional hint text.
*/
"hint"?: string;
+ /**
+ * The inputmode attribute.
+ */
+ "inputmode"?: 'decimal' | 'numeric';
/**
* The label for the text input.
*/
@@ -2473,6 +2477,10 @@ declare namespace LocalJSX {
* Optional hint text.
*/
"hint"?: string;
+ /**
+ * The inputmode attribute.
+ */
+ "inputmode"?: 'decimal' | 'numeric';
/**
* The label for the text input.
*/
diff --git a/packages/web-components/src/components/va-number-input/test/va-number-input.e2e.ts b/packages/web-components/src/components/va-number-input/test/va-number-input.e2e.ts
index 273bfa31e..0e99b4f5b 100644
--- a/packages/web-components/src/components/va-number-input/test/va-number-input.e2e.ts
+++ b/packages/web-components/src/components/va-number-input/test/va-number-input.e2e.ts
@@ -141,6 +141,15 @@ describe('va-number-input', () => {
expect(analyticsSpy).not.toHaveReceivedEvent();
});
+ it('defaults to type of text', async () => {
+ const page = await newE2EPage();
+ await page.setContent('');
+
+ // Level-setting expectations
+ const inputEl = await page.find('va-number-input >>> input');
+ expect(inputEl.getAttribute('type')).toBe('text');
+ });
+
it('sets a range based on min and max attributes', async () => {
const page = await newE2EPage();
await page.setContent('');
@@ -150,6 +159,16 @@ describe('va-number-input', () => {
expect(inputEl.getAttribute('max')).toBe('4');
});
+ it('allows manually setting the inputmode attribute', async () => {
+ const inputModes = ['decimal', 'numeric'];
+ for (const inputMode of inputModes) {
+ const page = await newE2EPage();
+ await page.setContent(``);
+ const inputEl = await page.find('va-number-input >>> input');
+ expect(inputEl.getAttribute('inputmode')).toBe(inputMode);
+ }
+ });
+
it('renders a "$" if currency flag set to true', async () => {
const page = await newE2EPage();
await page.setContent('');
@@ -314,6 +333,15 @@ describe('va-number-input', () => {
expect(analyticsSpy).not.toHaveReceivedEvent();
});
+ it('uswds defaults to type of text', async () => {
+ const page = await newE2EPage();
+ await page.setContent('');
+
+ // Level-setting expectations
+ const inputEl = await page.find('va-number-input >>> input');
+ expect(inputEl.getAttribute('type')).toBe('text');
+ });
+
it('uswds sets a range based on min and max attributes', async () => {
const page = await newE2EPage();
await page.setContent('');
@@ -323,6 +351,16 @@ describe('va-number-input', () => {
expect(inputEl.getAttribute('max')).toBe('4');
});
+ it('uswds allows manually setting the inputmode attribute', async () => {
+ const inputModes = ['decimal', 'numeric'];
+ for (const inputMode of inputModes) {
+ const page = await newE2EPage();
+ await page.setContent(``);
+ const inputEl = await page.find('va-number-input >>> input');
+ expect(inputEl.getAttribute('inputmode')).toBe(inputMode);
+ }
+ });
+
it('uswds adds aria-describedby input-message id', async () => {
const page = await newE2EPage();
await page.setContent('');
diff --git a/packages/web-components/src/components/va-number-input/va-number-input.tsx b/packages/web-components/src/components/va-number-input/va-number-input.tsx
index 72198efc8..08edbe3b9 100644
--- a/packages/web-components/src/components/va-number-input/va-number-input.tsx
+++ b/packages/web-components/src/components/va-number-input/va-number-input.tsx
@@ -46,6 +46,12 @@ export class VaNumberInput {
*/
@Prop() required?: boolean = false;
+ /**
+ * The inputmode attribute.
+ */
+ @Prop() inputmode?: 'decimal' | 'numeric';
+
+
/**
* Emit component-library-analytics events on the blur event.
*/
@@ -143,6 +149,7 @@ export class VaNumberInput {
label,
required,
error,
+ inputmode,
name,
max,
min,
@@ -158,7 +165,8 @@ export class VaNumberInput {
const ariaDescribedbyIds = `${messageAriaDescribedby ? 'input-message' : ''} ${error ? 'input-error-message' : ''}`
.trim() || null; // Null so we don't add the attribute if we have an empty string
-
+ const inputMode = inputmode ? inputmode : 'numeric';
+
if (uswds) {
const labelClasses = classnames({
'usa-label': true,
@@ -197,7 +205,7 @@ export class VaNumberInput {
aria-invalid={error ? 'true' : 'false'}
id="inputField"
type="text"
- inputmode="numeric"
+ inputmode={inputMode}
pattern="[0-9]+(\.[0-9]{1,})?"
name={name}
max={max}
@@ -243,7 +251,7 @@ export class VaNumberInput {
aria-invalid={error ? 'true' : 'false'}
id="inputField"
type="text"
- inputmode="numeric"
+ inputmode={inputMode}
pattern="[0-9]+(\.[0-9]{1,})?"
name={name}
max={max}