Settings Option Card component (#8456)
fixes - #8195 --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -12,21 +12,24 @@ import { SelectControl } from '@/ui/input/components/SelectControl';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
import { SelectHotkeyScope } from '../types/SelectHotkeyScope';
|
||||
|
||||
export type SelectOption<Value extends string | number | null> = {
|
||||
export type SelectOption<Value extends string | number | boolean | null> = {
|
||||
value: Value;
|
||||
label: string;
|
||||
Icon?: IconComponent;
|
||||
};
|
||||
|
||||
export type SelectSizeVariant = 'small' | 'default';
|
||||
|
||||
type CallToActionButton = {
|
||||
text: string;
|
||||
onClick: (event: MouseEvent<HTMLDivElement>) => void;
|
||||
Icon?: IconComponent;
|
||||
};
|
||||
|
||||
export type SelectProps<Value extends string | number | null> = {
|
||||
export type SelectProps<Value extends string | number | boolean | null> = {
|
||||
className?: string;
|
||||
disabled?: boolean;
|
||||
selectSizeVariant?: SelectSizeVariant;
|
||||
disableBlur?: boolean;
|
||||
dropdownId: string;
|
||||
dropdownWidth?: `${string}px` | 'auto' | number;
|
||||
@ -54,9 +57,10 @@ const StyledLabel = styled.span`
|
||||
margin-bottom: ${({ theme }) => theme.spacing(1)};
|
||||
`;
|
||||
|
||||
export const Select = <Value extends string | number | null>({
|
||||
export const Select = <Value extends string | number | boolean | null>({
|
||||
className,
|
||||
disabled: disabledFromProps,
|
||||
selectSizeVariant,
|
||||
disableBlur = false,
|
||||
dropdownId,
|
||||
dropdownWidth = 176,
|
||||
@ -115,6 +119,7 @@ export const Select = <Value extends string | number | null>({
|
||||
<SelectControl
|
||||
selectedOption={selectedOption}
|
||||
isDisabled={isDisabled}
|
||||
selectSizeVariant={selectSizeVariant}
|
||||
/>
|
||||
) : (
|
||||
<Dropdown
|
||||
@ -125,6 +130,7 @@ export const Select = <Value extends string | number | null>({
|
||||
<SelectControl
|
||||
selectedOption={selectedOption}
|
||||
isDisabled={isDisabled}
|
||||
selectSizeVariant={selectSizeVariant}
|
||||
/>
|
||||
}
|
||||
disableBlur={disableBlur}
|
||||
@ -144,7 +150,7 @@ export const Select = <Value extends string | number | null>({
|
||||
<DropdownMenuItemsContainer hasMaxHeight>
|
||||
{filteredOptions.map((option) => (
|
||||
<MenuItem
|
||||
key={option.value}
|
||||
key={`${option.value}-${option.label}`}
|
||||
LeftIcon={option.Icon}
|
||||
text={option.label}
|
||||
onClick={() => {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { SelectOption } from '@/ui/input/components/Select';
|
||||
import { SelectOption, SelectSizeVariant } from '@/ui/input/components/Select';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import {
|
||||
@ -10,6 +10,7 @@ import {
|
||||
const StyledControlContainer = styled.div<{
|
||||
disabled?: boolean;
|
||||
hasIcon: boolean;
|
||||
selectSizeVariant?: SelectSizeVariant;
|
||||
}>`
|
||||
display: grid;
|
||||
grid-template-columns: ${({ hasIcon }) =>
|
||||
@ -17,7 +18,8 @@ const StyledControlContainer = styled.div<{
|
||||
align-items: center;
|
||||
gap: ${({ theme }) => theme.spacing(1)};
|
||||
box-sizing: border-box;
|
||||
height: ${({ theme }) => theme.spacing(8)};
|
||||
height: ${({ selectSizeVariant, theme }) =>
|
||||
selectSizeVariant === 'small' ? theme.spacing(6) : theme.spacing(8)};
|
||||
max-width: 100%;
|
||||
padding: 0 ${({ theme }) => theme.spacing(2)};
|
||||
background-color: ${({ theme }) => theme.background.transparent.lighter};
|
||||
@ -37,13 +39,15 @@ const StyledIconChevronDown = styled(IconChevronDown)<{
|
||||
`;
|
||||
|
||||
type SelectControlProps = {
|
||||
selectedOption: SelectOption<string | number | null>;
|
||||
selectedOption: SelectOption<string | number | boolean | null>;
|
||||
isDisabled?: boolean;
|
||||
selectSizeVariant?: SelectSizeVariant;
|
||||
};
|
||||
|
||||
export const SelectControl = ({
|
||||
selectedOption,
|
||||
isDisabled,
|
||||
selectSizeVariant,
|
||||
}: SelectControlProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
@ -51,6 +55,7 @@ export const SelectControl = ({
|
||||
<StyledControlContainer
|
||||
disabled={isDisabled}
|
||||
hasIcon={isDefined(selectedOption.Icon)}
|
||||
selectSizeVariant={selectSizeVariant}
|
||||
>
|
||||
{isDefined(selectedOption.Icon) ? (
|
||||
<selectedOption.Icon
|
||||
|
||||
@ -5,11 +5,11 @@ import { ComponentDecorator, IconPlus } from 'twenty-ui';
|
||||
|
||||
import { Select, SelectProps } from '../Select';
|
||||
|
||||
type RenderProps = SelectProps<string | number | null>;
|
||||
type RenderProps = SelectProps<string | number | boolean | null>;
|
||||
|
||||
const Render = (args: RenderProps) => {
|
||||
const [value, setValue] = useState(args.value);
|
||||
const handleChange = (value: string | number | null) => {
|
||||
const handleChange = (value: string | number | boolean | null) => {
|
||||
args.onChange?.(value);
|
||||
setValue(value);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user