Added and optimized missing RatingFieldDisplay component (#5904)
The display for Rating field type was missing, I just added it based on RatingInput in readonly mode and optimized a bit for performance also. Fixes https://github.com/twentyhq/twenty/issues/5900
This commit is contained in:
@ -1,7 +1,6 @@
|
||||
import { useState } from 'react';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { IconTwentyStarFilled } from 'twenty-ui';
|
||||
import { useContext, useState } from 'react';
|
||||
import { styled } from '@linaria/react';
|
||||
import { IconTwentyStarFilled, THEME_COMMON, ThemeContext } from 'twenty-ui';
|
||||
|
||||
import { RATING_VALUES } from '@/object-record/record-field/meta-types/constants/RatingValues';
|
||||
import { FieldRatingValue } from '@/object-record/record-field/types/FieldMetadata';
|
||||
@ -11,29 +10,38 @@ const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
`;
|
||||
|
||||
const StyledRatingIconContainer = styled.div<{ isActive?: boolean }>`
|
||||
color: ${({ isActive, theme }) =>
|
||||
isActive ? theme.font.color.secondary : theme.background.quaternary};
|
||||
const StyledRatingIconContainer = styled.div<{
|
||||
color: string;
|
||||
}>`
|
||||
color: ${({ color }) => color};
|
||||
display: inline-flex;
|
||||
`;
|
||||
|
||||
type RatingInputProps = {
|
||||
onChange: (newValue: FieldRatingValue) => void;
|
||||
onChange?: (newValue: FieldRatingValue) => void;
|
||||
value: FieldRatingValue;
|
||||
readonly?: boolean;
|
||||
};
|
||||
|
||||
const iconSizeMd = THEME_COMMON.icon.size.md;
|
||||
|
||||
export const RatingInput = ({
|
||||
onChange,
|
||||
value,
|
||||
readonly,
|
||||
}: RatingInputProps) => {
|
||||
const theme = useTheme();
|
||||
const { theme } = useContext(ThemeContext);
|
||||
|
||||
const activeColor = theme.font.color.secondary;
|
||||
const inactiveColor = theme.background.quaternary;
|
||||
|
||||
const [hoveredValue, setHoveredValue] = useState<FieldRatingValue | null>(
|
||||
null,
|
||||
);
|
||||
const currentValue = hoveredValue ?? value;
|
||||
|
||||
const selectedIndex = RATING_VALUES.indexOf(currentValue);
|
||||
|
||||
return (
|
||||
<StyledContainer
|
||||
role="slider"
|
||||
@ -44,17 +52,17 @@ export const RatingInput = ({
|
||||
tabIndex={0}
|
||||
>
|
||||
{RATING_VALUES.map((value, index) => {
|
||||
const currentIndex = RATING_VALUES.indexOf(currentValue);
|
||||
const isActive = index <= selectedIndex;
|
||||
|
||||
return (
|
||||
<StyledRatingIconContainer
|
||||
key={index}
|
||||
isActive={index <= currentIndex}
|
||||
onClick={readonly ? undefined : () => onChange(value)}
|
||||
color={isActive ? activeColor : inactiveColor}
|
||||
onClick={readonly ? undefined : () => onChange?.(value)}
|
||||
onMouseEnter={readonly ? undefined : () => setHoveredValue(value)}
|
||||
onMouseLeave={readonly ? undefined : () => setHoveredValue(null)}
|
||||
>
|
||||
<IconTwentyStarFilled size={theme.icon.size.md} />
|
||||
<IconTwentyStarFilled size={iconSizeMd} />
|
||||
</StyledRatingIconContainer>
|
||||
);
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user