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:
parent
0b9b2f4dbc
commit
2f8a172b12
@ -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>
|
||||
);
|
||||
},
|
||||
);
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user