mirror of
https://github.com/Unleash/unleash.git
synced 2025-06-27 01:19:00 +02:00
chore(1-3679): use numeric input mode for numbers. (#9875)
Adds inputmode='decimal' to input fields with number input. As discussed on the [GOV.UK blog](https://technology.blog.gov.uk/2020/02/24/why-the-gov-uk-design-system-team-changed-the-input-type-for-numbers/), this finds a balance between giving numeric input options to mobile devices and improving validation / user experience. They mention this bit in their [design system guideline](https://design-system.service.gov.uk/components/text-input/#numbers) > Do not use `<input type="number">` unless your user research shows that there’s a need for it. With `<input type="number">` there’s a risk of users accidentally incrementing a number when they’re trying to do something else - for example, scroll up or down the page. And if the user tries to enter something that’s not a number, there’s no explicit feedback about what they’re doing wrong. I've purposefully not included the `pattern="[0-9]*"` attribute here, because the browser error messages conflict with our own and have several drawbacks in terms of accessibility according to Adrian Roselli's ["Avoid default field validation"](https://adrianroselli.com/2019/02/avoid-default-field-validation.html). Instead, the validation here will be part of the validation handling later. Also, I've opted for using `decimal` instead of `numeric`, because we allow you to store decimal values and that inputmode also adds the decimal separator to the keyboard. As always, however, there's complications: several languages (including Norwegian) use a comma as a decimal separator instead of a period, so the keyboard will likely contain numbers and a comma instead of a period. This is a problem because JS doesn't recognize "45,6" as a valid number. I've added a follow-up task to look into this. I thought at first it would just be expanding the validation, but because it's stored as a string on the back end and the SDKs presumably parse it, we can't just suddenly allow commas as decimal separators.
This commit is contained in:
parent
33f23cc0c1
commit
bc342c5b13
@ -17,15 +17,16 @@ const StyledChip = styled(ValueChip, {
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
interface AddValuesProps {
|
type Props = {
|
||||||
onAddValue: (newValue: string) => void;
|
onAddValue: (newValue: string) => void;
|
||||||
removeValue: () => void;
|
removeValue: () => void;
|
||||||
currentValue?: string;
|
currentValue?: string;
|
||||||
helpText?: string;
|
helpText?: string;
|
||||||
}
|
inputType: 'text' | 'number';
|
||||||
|
};
|
||||||
|
|
||||||
export const AddSingleValueWidget = forwardRef<HTMLDivElement, AddValuesProps>(
|
export const AddSingleValueWidget = forwardRef<HTMLDivElement, Props>(
|
||||||
({ currentValue, onAddValue, removeValue, helpText }, ref) => {
|
({ currentValue, onAddValue, removeValue, helpText, inputType }, ref) => {
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const positioningRef = useRef<HTMLDivElement>(null);
|
const positioningRef = useRef<HTMLDivElement>(null);
|
||||||
useImperativeHandle(
|
useImperativeHandle(
|
||||||
@ -55,6 +56,9 @@ export const AddSingleValueWidget = forwardRef<HTMLDivElement, AddValuesProps>(
|
|||||||
onDelete={currentValue ? removeValue : undefined}
|
onDelete={currentValue ? removeValue : undefined}
|
||||||
/>
|
/>
|
||||||
<AddValuesPopover
|
<AddValuesPopover
|
||||||
|
inputProps={{
|
||||||
|
inputMode: inputType === 'number' ? 'decimal' : 'text',
|
||||||
|
}}
|
||||||
initialValue={currentValue}
|
initialValue={currentValue}
|
||||||
onAdd={handleAdd}
|
onAdd={handleAdd}
|
||||||
helpText={helpText}
|
helpText={helpText}
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
import { Button, Popover, styled, TextField } from '@mui/material';
|
import {
|
||||||
|
Button,
|
||||||
|
type InputBaseComponentProps,
|
||||||
|
Popover,
|
||||||
|
styled,
|
||||||
|
TextField,
|
||||||
|
} from '@mui/material';
|
||||||
import { ScreenReaderOnly } from 'component/common/ScreenReaderOnly/ScreenReaderOnly';
|
import { ScreenReaderOnly } from 'component/common/ScreenReaderOnly/ScreenReaderOnly';
|
||||||
import { type FC, useId, useRef, useState } from 'react';
|
import { type FC, useId, useRef, useState } from 'react';
|
||||||
|
|
||||||
@ -34,6 +40,7 @@ type AddValuesProps = {
|
|||||||
anchorEl: HTMLElement | null;
|
anchorEl: HTMLElement | null;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
helpText?: string;
|
helpText?: string;
|
||||||
|
inputProps?: InputBaseComponentProps;
|
||||||
};
|
};
|
||||||
|
|
||||||
const HelpText = styled('p')(({ theme }) => ({
|
const HelpText = styled('p')(({ theme }) => ({
|
||||||
@ -52,6 +59,7 @@ export const AddValuesPopover: FC<AddValuesProps> = ({
|
|||||||
open,
|
open,
|
||||||
onClose,
|
onClose,
|
||||||
helpText,
|
helpText,
|
||||||
|
inputProps,
|
||||||
}) => {
|
}) => {
|
||||||
const [inputValue, setInputValue] = useState(initialValue || '');
|
const [inputValue, setInputValue] = useState(initialValue || '');
|
||||||
const [error, setError] = useState('');
|
const [error, setError] = useState('');
|
||||||
@ -119,6 +127,9 @@ export const AddValuesPopover: FC<AddValuesProps> = ({
|
|||||||
error={!!error}
|
error={!!error}
|
||||||
helperText={error}
|
helperText={error}
|
||||||
aria-describedby={helpTextId}
|
aria-describedby={helpTextId}
|
||||||
|
inputProps={{
|
||||||
|
...inputProps,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<AddButton
|
<AddButton
|
||||||
variant='text'
|
variant='text'
|
||||||
|
@ -303,6 +303,9 @@ export const EditableConstraint: FC<Props> = ({
|
|||||||
? 'Add a single number'
|
? 'Add a single number'
|
||||||
: 'A semver value should be of the format X.Y.Z'
|
: 'A semver value should be of the format X.Y.Z'
|
||||||
}
|
}
|
||||||
|
inputType={
|
||||||
|
inputType.type === 'number' ? 'number' : 'text'
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case 'multiple values':
|
case 'multiple values':
|
||||||
|
Loading…
Reference in New Issue
Block a user