Fix - Input box shadow, left icon focus and new size variant (#9902)

Favorite folder input needs to be 28px --- added a new sizeVariant 
Removed box shadow completely -- checked with @Bonapara 
The left icon used to be of color light on focus -- added a state to
check if input is focused

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
This commit is contained in:
nitin
2025-01-30 00:14:25 +05:30
committed by GitHub
parent 0d6f4a32a7
commit 4edbb13706
3 changed files with 34 additions and 16 deletions

View File

@ -16,7 +16,6 @@ import {
IconComponent, IconComponent,
IconEye, IconEye,
IconEyeOff, IconEyeOff,
RGBA,
} from 'twenty-ui'; } from 'twenty-ui';
import { useCombinedRefs } from '~/hooks/useCombinedRefs'; import { useCombinedRefs } from '~/hooks/useCombinedRefs';
import { turnIntoEmptyStringIfWhitespacesOnly } from '~/utils/string/turnIntoEmptyStringIfWhitespacesOnly'; import { turnIntoEmptyStringIfWhitespacesOnly } from '~/utils/string/turnIntoEmptyStringIfWhitespacesOnly';
@ -54,12 +53,13 @@ const StyledInput = styled.input<
flex-grow: 1; flex-grow: 1;
font-family: ${({ theme }) => theme.font.family}; font-family: ${({ theme }) => theme.font.family};
font-weight: ${({ theme }) => theme.font.weight.regular}; font-weight: ${({ theme }) => theme.font.weight.regular};
height: ${({ sizeVariant }) => (sizeVariant === 'sm' ? '20px' : '32px')}; height: ${({ sizeVariant }) =>
sizeVariant === 'sm' ? '20px' : sizeVariant === 'md' ? '28px' : '32px'};
outline: none; outline: none;
padding: ${({ theme, sizeVariant }) => padding: ${({ theme, sizeVariant }) =>
sizeVariant === 'sm' ? `${theme.spacing(2)} 0` : theme.spacing(2)}; sizeVariant === 'sm' ? `${theme.spacing(2)} 0` : theme.spacing(2)};
padding-left: ${({ theme, LeftIcon }) => padding-left: ${({ theme, LeftIcon }) =>
LeftIcon ? `calc(${theme.spacing(4)} + 16px)` : theme.spacing(2)}; LeftIcon ? `calc(${theme.spacing(3)} + 16px)` : theme.spacing(2)};
width: ${({ theme, width }) => width: ${({ theme, width }) =>
width ? `calc(${width}px + ${theme.spacing(5)})` : '100%'}; width ? `calc(${width}px + ${theme.spacing(5)})` : '100%'};
@ -76,8 +76,9 @@ const StyledInput = styled.input<
&:focus { &:focus {
${({ theme }) => { ${({ theme }) => {
return `box-shadow: 0px 0px 0px 3px ${RGBA(theme.color.blue, 0.1)}; return `
border-color: ${theme.color.blue};`; border-color: ${theme.color.blue};
`;
}}; }};
} }
`; `;
@ -88,11 +89,16 @@ const StyledErrorHelper = styled.div`
padding: ${({ theme }) => theme.spacing(1)}; padding: ${({ theme }) => theme.spacing(1)};
`; `;
const StyledLeftIconContainer = styled.div` const StyledLeftIconContainer = styled.div<{ sizeVariant: TextInputV2Size }>`
align-items: center; align-items: center;
display: flex; display: flex;
justify-content: center; justify-content: center;
padding-left: ${({ theme }) => theme.spacing(2)}; padding-left: ${({ theme, sizeVariant }) =>
sizeVariant === 'sm'
? theme.spacing(0.5)
: sizeVariant === 'md'
? theme.spacing(1)
: theme.spacing(2)};
position: absolute; position: absolute;
top: 0; top: 0;
bottom: 0; bottom: 0;
@ -113,9 +119,10 @@ const StyledTrailingIconContainer = styled.div<
margin: auto 0; margin: auto 0;
`; `;
const StyledTrailingIcon = styled.div` const StyledTrailingIcon = styled.div<{ isFocused?: boolean }>`
align-items: center; align-items: center;
color: ${({ theme }) => theme.font.color.light}; color: ${({ theme, isFocused }) =>
isFocused ? theme.font.color.secondary : theme.font.color.light};
cursor: ${({ onClick }) => (onClick ? 'pointer' : 'default')}; cursor: ${({ onClick }) => (onClick ? 'pointer' : 'default')};
display: flex; display: flex;
justify-content: center; justify-content: center;
@ -123,7 +130,7 @@ const StyledTrailingIcon = styled.div`
const INPUT_TYPE_PASSWORD = 'password'; const INPUT_TYPE_PASSWORD = 'password';
export type TextInputV2Size = 'sm' | 'md'; export type TextInputV2Size = 'sm' | 'md' | 'lg';
export type TextInputV2ComponentProps = Omit< export type TextInputV2ComponentProps = Omit<
InputHTMLAttributes<HTMLInputElement>, InputHTMLAttributes<HTMLInputElement>,
@ -169,7 +176,7 @@ const TextInputV2Component = (
LeftIcon, LeftIcon,
autoComplete, autoComplete,
maxLength, maxLength,
sizeVariant = 'md', sizeVariant = 'lg',
dataTestId, dataTestId,
}: TextInputV2ComponentProps, }: TextInputV2ComponentProps,
// eslint-disable-next-line @nx/workspace-component-props-naming // eslint-disable-next-line @nx/workspace-component-props-naming
@ -181,11 +188,22 @@ const TextInputV2Component = (
const combinedRef = useCombinedRefs(ref, inputRef); const combinedRef = useCombinedRefs(ref, inputRef);
const [passwordVisible, setPasswordVisible] = useState(false); const [passwordVisible, setPasswordVisible] = useState(false);
const [isFocused, setIsFocused] = useState(false);
const handleTogglePasswordVisibility = () => { const handleTogglePasswordVisibility = () => {
setPasswordVisible(!passwordVisible); setPasswordVisible(!passwordVisible);
}; };
const handleFocus: FocusEventHandler<HTMLInputElement> = (event) => {
setIsFocused(true);
onFocus?.(event);
};
const handleBlur: FocusEventHandler<HTMLInputElement> = (event) => {
setIsFocused(false);
onBlur?.(event);
};
const inputId = useId(); const inputId = useId();
return ( return (
@ -197,8 +215,8 @@ const TextInputV2Component = (
)} )}
<StyledInputContainer> <StyledInputContainer>
{!!LeftIcon && ( {!!LeftIcon && (
<StyledLeftIconContainer> <StyledLeftIconContainer sizeVariant={sizeVariant}>
<StyledTrailingIcon> <StyledTrailingIcon isFocused={isFocused}>
<LeftIcon size={theme.icon.size.md} /> <LeftIcon size={theme.icon.size.md} />
</StyledTrailingIcon> </StyledTrailingIcon>
</StyledLeftIconContainer> </StyledLeftIconContainer>
@ -211,8 +229,8 @@ const TextInputV2Component = (
autoComplete={autoComplete || 'off'} autoComplete={autoComplete || 'off'}
ref={combinedRef} ref={combinedRef}
tabIndex={tabIndex ?? 0} tabIndex={tabIndex ?? 0}
onFocus={onFocus} onFocus={handleFocus}
onBlur={onBlur} onBlur={handleBlur}
type={passwordVisible ? 'text' : type} type={passwordVisible ? 'text' : type}
onChange={(event: ChangeEvent<HTMLInputElement>) => { onChange={(event: ChangeEvent<HTMLInputElement>) => {
onChange?.( onChange?.(

View File

@ -36,7 +36,6 @@ const StyledButton = styled('button')`
text-decoration: none; text-decoration: none;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
:hover { :hover {
background: ${({ theme }) => theme.background.transparent.light}; background: ${({ theme }) => theme.background.transparent.light};
} }

View File

@ -78,6 +78,7 @@ export const NavigationDrawerInput = ({
onChange={onChange} onChange={onChange}
placeholder={placeholder} placeholder={placeholder}
onFocus={handleFocus} onFocus={handleFocus}
sizeVariant="md"
fullWidth fullWidth
autoFocus autoFocus
/> />