Skip to content

Commit

Permalink
feat: pr comments
Browse files Browse the repository at this point in the history
  • Loading branch information
kostasdano committed Jul 26, 2023
1 parent 158ab59 commit a45393c
Show file tree
Hide file tree
Showing 8 changed files with 372 additions and 313 deletions.
9 changes: 9 additions & 0 deletions src/components/NumberField/NumberField.style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { css, SerializedStyles } from '@emotion/react';
import { rem } from 'theme/utils';

export const groupStyles = (): SerializedStyles => {
return css`
/** @TODO: add tokens instead of rem */
width: ${`calc(100% - ${rem(44)})`};
`;
};
16 changes: 16 additions & 0 deletions src/components/NumberField/NumberField.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@ describe('NumberField', () => {
expect(input).toHaveValue('12.00');
});

it('increases and decreases the number through keyboard', async () => {
renderNumberField({ step: 0.5, hasStepper: true });
input = screen.getByTestId('input') as HTMLInputElement;

userEvent.type(input, '12.00');
userEvent.click(document.body);

userEvent.click(input);

userEvent.type(input, '{arrowup}');
expect(input).toHaveValue('12.50');

userEvent.type(input, '{arrowdown}');
expect(input).toHaveValue('12.00');
});

it('it rejects number input outside min and max given', async () => {
renderNumberField({ minValue: 10, maxValue: 20 });
input = screen.getByTestId('input') as HTMLInputElement;
Expand Down
87 changes: 35 additions & 52 deletions src/components/NumberField/NumberField.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
import useCombinedRefs from 'hooks/useCombinedRefs';
import { useTheme } from 'index';
import useFieldUtils from 'hooks/useFieldUtils';
import { omit } from 'lodash';
import React, { useMemo } from 'react';
import { NumberField as ReactAriaNumberField, Group, Input, } from 'react-aria-components';
import React from 'react';
import { NumberField as ReactAriaNumberField, Group, Input } from 'react-aria-components';
import { generateUniqueID } from 'utils/helpers';

import Stepper from './components/Stepper/Stepper';
import { groupStyles } from './NumberField.style';
import { TextFieldProps } from '../TextField/TextField';
import { getTextInputBaseTokens } from '../TextInputBase/TextInputBase.tokens';
import Icon, { AcceptedIconNames } from 'components/Icon';
import Label from 'components/Label';
import { suffixContainerStyle } from 'components/TextField/TextField.style';
import TextInputBase from 'components/TextInputBase/TextInputBase';
import { inputStyle } from 'components/TextInputBase/TextInputBase.style';

export type NumberFieldProps = Omit<TextFieldProps, 'mask' | 'maskChar' | 'value' | 'onChange'> & {
export type NumberFieldProps = Omit<
TextFieldProps,
| 'mask'
| 'maskChar'
| 'value'
| 'onChange'
| 'isMulti'
| 'onMultiValueClearAll'
| 'onMultiValueDelete'
> & {
/** Callback fired when the `input` is changed. */
onChange?: (value: number) => void;
/** The value of the `input` element. */
Expand Down Expand Up @@ -52,52 +59,28 @@ const NumberField = React.forwardRef<HTMLInputElement, NumberFieldProps>((props,
...rest
} = props;

const theme = useTheme();
const tokens = getTextInputBaseTokens(theme);

const inputRef = React.useRef<HTMLInputElement>(null);
const combinedRefs = useCombinedRefs(inputRef, ref);

const isLocked = status?.type === 'read-only';
const hintMessageId = status?.hintMessage ? status?.id ?? `${id}_hintMessage` : undefined;

const handleClick = () => {
if (!isLocked && !isDisabled) {
combinedRefs.current?.focus();
}
};

const suffixContent = useMemo(() => {
if (isLocked || typeof suffix === 'string') {
const iconName = isLocked ? 'lock' : suffix;

return (
<Icon
name={iconName as AcceptedIconNames}
size={16}
color={theme.utils.getColor('lightGrey', 650)}
/>
);
}

return suffix;
}, [isLocked, suffix, theme.utils]);

const textInputBaseSx = useMemo(
() =>
!suffixContent && !hasStepper
? {
textField: {
paddingRight: tokens('paddingContentLeft'),
},
}
: {},
[hasStepper, suffixContent, tokens]
);
const {
isLocked,
hintMessageId,
handleContainerClick,
suffixContent,
combinedRefs,
textInputBaseSx,
} = useFieldUtils({
id,
suffix,
status,
isDisabled,
ref,
});

return (
<div onClick={handleClick}>
<TextInputBase {...props} status={{ ...status, id: hintMessageId }} sx={textInputBaseSx}>
<div onClick={handleContainerClick}>
<TextInputBase
{...props}
status={{ ...status, id: hintMessageId }}
sx={textInputBaseSx(!suffixContent && !hasStepper)}
>
<div css={{ width: '100%' }}>
<ReactAriaNumberField
value={value}
Expand All @@ -107,7 +90,7 @@ const NumberField = React.forwardRef<HTMLInputElement, NumberFieldProps>((props,
minValue={minValue}
maxValue={maxValue}
>
<Group>
<Group css={hasStepper ? groupStyles() : {}}>
<Input
id={id}
readOnly={isLocked || isReadOnly}
Expand Down
Loading

0 comments on commit a45393c

Please sign in to comment.