refactor: Improve car color selection UI and interaction

- Refined color selection styling with more consistent hover and selection states
- Added dynamic styling for selected and custom color options
- Optimized layout and spacing of color selection buttons
- Improved ref handling for the component
This commit is contained in:
RustamRu 2025-03-11 23:08:08 +03:00
parent 0b9b2f4dbc
commit 2f8a172b12

View File

@ -1,11 +1,5 @@
import React, { forwardRef, useState } from 'react';
import {
Input,
Box,
Stack,
Text,
Flex,
} from '@chakra-ui/react';
import { Input, Box, Stack, Text, Flex } from '@chakra-ui/react';
import { useTranslation } from 'react-i18next';
import { CAR_COLORS } from './helper';
@ -18,7 +12,7 @@ interface CarColorSelectProps {
}
export const CarColorSelect = forwardRef<HTMLInputElement, CarColorSelectProps>(
function CarColorSelect(props) {
function CarColorSelect(props, ref) {
const [customColor, setCustomColor] = useState('');
const [isCustom, setIsCustom] = useState(false);
@ -33,7 +27,9 @@ export const CarColorSelect = forwardRef<HTMLInputElement, CarColorSelectProps>(
} as React.ChangeEvent<HTMLInputElement>);
};
const handleCustomColorChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const handleCustomColorChange = (
e: React.ChangeEvent<HTMLInputElement>,
) => {
const value = e.target.value;
setCustomColor(value);
props.onChange?.({
@ -48,46 +44,56 @@ export const CarColorSelect = forwardRef<HTMLInputElement, CarColorSelectProps>(
const currentValue = isCustom ? 'custom' : props.value;
return (
<Stack spacing={4} width="100%">
<Flex gap={3} wrap="nowrap" overflowX="auto" pb={2}>
<Stack spacing={4} width='100%' ref={ref}>
<Flex gap={2} wrap='wrap' pb={2}>
{CAR_COLORS.map(({ name, code }) => (
<Box
<Box
key={name}
flexShrink={0}
as="button"
type="button"
as='button'
type='button'
onClick={() => handleColorChange(name)}
>
<Flex
align="center"
gap={2}
p={2}
borderRadius="full"
borderWidth="2px"
borderColor={currentValue === name ? 'primary.500' : 'gray.200'}
bg={currentValue === name ? 'primary.50' : 'white'}
_hover={{
<Flex
align='center'
gap={2}
p={1}
borderRadius='full'
borderWidth='2px'
borderColor='gray.200'
bg='white'
_hover={{
borderColor: 'primary.500',
bg: currentValue === name ? 'primary.50' : 'gray.50'
bg: 'gray.50',
}}
minW={currentValue === name ? '120px' : 'auto'}
h="48px"
justify="center"
transition="all 0.2s"
justify='center'
transition='all 0.2s'
{...(currentValue === name && {
borderColor: 'primary.500',
bg: 'primary.50',
paddingInlineEnd: 3,
_hover: {
bg: 'primary.50',
},
})}
>
<Flex align="center" gap={2}>
<Flex align='center' gap={2}>
<Box
w="32px"
h="32px"
borderRadius="full"
w='32px'
h='32px'
borderRadius='full'
bg={code}
border="1px"
borderColor={currentValue === name ? 'primary.500' : 'gray.200'}
transition="all 0.2s"
boxShadow={currentValue === name ? 'sm' : 'none'}
border='1px'
borderColor='gray.200'
transition='all 0.2s'
boxShadow='none'
{...(currentValue === name && {
borderColor: 'primary.500',
boxShadow: 'sm',
})}
/>
{currentValue === name && (
<Text fontSize="xs" color="primary.700" fontWeight="medium">
<Text fontSize='xs' color='primary.700' fontWeight='medium'>
{t(`colors.${name}`)}
</Text>
)}
@ -95,60 +101,67 @@ export const CarColorSelect = forwardRef<HTMLInputElement, CarColorSelectProps>(
</Flex>
</Box>
))}
<Box
<Box
flexShrink={0}
as="button"
type="button"
as='button'
type='button'
onClick={() => handleColorChange('custom')}
>
<Flex
align="center"
<Flex
align='center'
gap={2}
p={2}
borderRadius="full"
borderWidth="2px"
borderColor={isCustom ? 'primary.500' : 'gray.200'}
bg={isCustom ? 'primary.50' : 'white'}
_hover={{
p={1}
paddingInlineEnd={3}
borderRadius='full'
borderWidth='2px'
borderColor='gray.200'
bg='white'
_hover={{
borderColor: 'primary.500',
bg: isCustom ? 'primary.50' : 'gray.50'
bg: 'gray.50',
}}
minW={isCustom ? '200px' : 'auto'}
h="48px"
justify="center"
transition="all 0.2s"
justify='center'
transition='all 0.2s'
{...(isCustom && {
borderColor: 'primary.500',
paddingInlineStart: 3,
bg: 'primary.50',
_hover: {
bg: 'primary.50',
},
})}
>
{isCustom ? (
<Flex gap={2} align="center">
<Text fontSize="xs" color="primary.700" fontWeight="medium">
<Flex gap={2} align='center'>
<Text fontSize='xs' color='primary.700' fontWeight='medium'>
{t('custom-label')}
</Text>
<Input
size="sm"
width="120px"
size='sm'
width='120px'
value={customColor}
onChange={handleCustomColorChange}
placeholder={t('placeholder')}
onClick={(e) => e.stopPropagation()}
borderColor="primary.200"
borderColor='primary.200'
_focus={{
borderColor: 'primary.500',
boxShadow: '0 0 0 1px var(--chakra-colors-primary-500)'
boxShadow: '0 0 0 1px var(--chakra-colors-primary-500)',
}}
/>
</Flex>
) : (
<Flex align="center" gap={2}>
<Flex align='center' gap={2}>
<Box
w="32px"
h="32px"
borderRadius="full"
bg="gray.100"
border="1px"
borderColor="gray.200"
transition="all 0.2s"
w='32px'
h='32px'
borderRadius='full'
bg='gray.100'
border='1px'
borderColor='gray.200'
transition='all 0.2s'
/>
<Text fontSize="xs" color="gray.500">
<Text fontSize='xs' color='gray.500'>
{t('custom')}
</Text>
</Flex>
@ -159,4 +172,4 @@ export const CarColorSelect = forwardRef<HTMLInputElement, CarColorSelectProps>(
</Stack>
);
},
);
);