Skip to content

Commit fb6c009

Browse files
author
Nikolai Lopin
authored
fix: uncontrolled input's label position (#297)
1 parent 3b5b7b8 commit fb6c009

File tree

3 files changed

+14
-8
lines changed

3 files changed

+14
-8
lines changed

src/components/Input/InnerInput.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { forwardRef, useEffect, useState } from 'react';
1+
import React, { forwardRef, useEffect, useRef, useState } from 'react';
22
import { extractClassNameProps, extractWidthProps, extractWrapperMarginProps } from '../../utils/extractProps';
33
import { useGeneratedId } from '../../utils/hooks/useGeneratedId';
44
import { BottomLinedInput } from './BottomLinedInput';
@@ -13,31 +13,36 @@ const InnerInput = forwardRef<HTMLDivElement, InputWrapperProps & InputProps>(
1313
const { classNameProps, restProps: withoutClassName } = extractClassNameProps(props);
1414
const { marginProps, restProps: withoutMargin } = extractWrapperMarginProps(withoutClassName);
1515
const { widthProps, restProps } = extractWidthProps(withoutMargin);
16+
// TODO replace with ref when implementing https://github.com/freenowtech/wave/issues/169
17+
const inputRef = useRef<HTMLInputElement>();
1618

1719
const { label, onChange, size, id: providedId, variant, ...rest } = restProps;
1820
const id = useGeneratedId(providedId);
1921

20-
const [hasValue, setHasValue] = useState(rest.value && rest.value.toString().length > 0);
22+
const [hasValue, setHasValue] = useState(rest?.value?.toString().length > 0);
23+
const hasUncontrolledValue = inputRef?.current?.value?.length > 0;
2124

22-
const handleChange = event => {
25+
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
26+
setHasValue(event.target.value.length > 0);
2327
if (onChange) {
2428
onChange(event);
2529
}
2630
};
2731

2832
useEffect(() => {
29-
setHasValue(rest.value && rest.value.toString().length > 0);
33+
setHasValue(rest?.value?.toString().length > 0);
3034
}, [rest.value]);
3135

3236
if (variant === 'boxed') {
3337
return (
3438
<InputWrapper ref={ref} {...classNameProps} {...marginProps} {...widthProps}>
3539
<BoxedInput
3640
{...rest}
41+
ref={inputRef}
3742
variant={variant}
3843
id={id}
3944
size={size}
40-
hasValue={hasValue}
45+
hasValue={hasValue || hasUncontrolledValue}
4146
onChange={handleChange}
4247
/>
4348
{label && (
@@ -57,7 +62,7 @@ const InnerInput = forwardRef<HTMLDivElement, InputWrapperProps & InputProps>(
5762
variant={variant}
5863
id={id}
5964
size={size}
60-
hasValue={hasValue}
65+
hasValue={hasValue || hasUncontrolledValue}
6166
onChange={handleChange}
6267
/>
6368
{label && (

src/components/Input/InputProps.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { ComponentPropsWithoutRef } from 'react';
1+
import { ComponentPropsWithRef } from 'react';
22
import { ResponsiveValue } from 'styled-system';
33

4-
interface InputProps extends Omit<ComponentPropsWithoutRef<'input'>, 'size' | 'width'> {
4+
interface InputProps extends Omit<ComponentPropsWithRef<'input'>, 'size' | 'width'> {
55
variant?: ResponsiveValue<'boxed' | 'bottom-lined'>;
66
size?: ResponsiveValue<'small' | 'medium'>;
77
inverted?: boolean;

src/components/Input/docs/Input.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Additionally, all native HTML input element props are supported and forwarded to
2727

2828
<Playground>
2929
<ControlledInput variant="boxed" placeholder="[email protected]" label="E-Mail Address" id='email' />
30+
<Input label='Uncontrolled input' />
3031
</Playground>
3132

3233
## Testing

0 commit comments

Comments
 (0)