Add icon select to manual trigger (#12724)
## After <img width="1220" alt="image" src="https://github.com/user-attachments/assets/98a73aae-80d7-4e92-93d3-be13210da88b" /> <img width="1131" alt="image" src="https://github.com/user-attachments/assets/9919e415-4355-4995-8979-9055b821f1e9" /> <img width="1300" alt="image" src="https://github.com/user-attachments/assets/27f11cb3-d72c-468a-a641-8414172b9b54" /> <img width="1353" alt="image" src="https://github.com/user-attachments/assets/2f0037f2-fe17-48b6-b7e6-c7528687a5fd" />
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { ReactNode, useMemo, useState } from 'react';
|
||||
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
@ -25,6 +25,8 @@ import {
|
||||
LightIconButton,
|
||||
} from 'twenty-ui/input';
|
||||
import { IconPickerHotkeyScope } from '../types/IconPickerHotkeyScope';
|
||||
import { DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset';
|
||||
|
||||
export type IconPickerProps = {
|
||||
disabled?: boolean;
|
||||
dropdownId?: string;
|
||||
@ -36,6 +38,10 @@ export type IconPickerProps = {
|
||||
variant?: IconButtonVariant;
|
||||
className?: string;
|
||||
size?: IconButtonSize;
|
||||
clickableComponent?: ReactNode;
|
||||
dropdownWidth?: number;
|
||||
dropdownOffset?: DropdownOffset;
|
||||
maxIconsVisible?: number;
|
||||
};
|
||||
|
||||
const StyledMenuIconItemsContainer = styled.div`
|
||||
@ -102,6 +108,10 @@ export const IconPicker = ({
|
||||
variant = 'secondary',
|
||||
className,
|
||||
size = 'medium',
|
||||
clickableComponent,
|
||||
dropdownWidth,
|
||||
dropdownOffset,
|
||||
maxIconsVisible = 25,
|
||||
}: IconPickerProps) => {
|
||||
const [searchString, setSearchString] = useState('');
|
||||
const {
|
||||
@ -171,9 +181,9 @@ export const IconPicker = ({
|
||||
...filteredAndSortedIconKeys.filter(
|
||||
(iconKey) => iconKey !== selectedIconKey,
|
||||
),
|
||||
].slice(0, 25)
|
||||
: filteredAndSortedIconKeys.slice(0, 25);
|
||||
}, [icons, searchString, selectedIconKey]);
|
||||
].slice(0, maxIconsVisible)
|
||||
: filteredAndSortedIconKeys.slice(0, maxIconsVisible);
|
||||
}, [icons, searchString, selectedIconKey, maxIconsVisible]);
|
||||
|
||||
const iconKeys2d = useMemo(
|
||||
() => arrayToChunks(matchingSearchIconKeys.slice(), 5),
|
||||
@ -186,21 +196,26 @@ export const IconPicker = ({
|
||||
<div className={className}>
|
||||
<Dropdown
|
||||
dropdownId={dropdownId}
|
||||
dropdownOffset={dropdownOffset}
|
||||
clickableComponent={
|
||||
<IconButton
|
||||
ariaLabel={`Click to select icon ${
|
||||
selectedIconKey
|
||||
? `(selected: ${selectedIconKey})`
|
||||
: `(no icon selected)`
|
||||
}`}
|
||||
disabled={disabled}
|
||||
Icon={icon}
|
||||
variant={variant}
|
||||
size={size}
|
||||
/>
|
||||
clickableComponent || (
|
||||
<IconButton
|
||||
ariaLabel={`Click to select icon ${
|
||||
selectedIconKey
|
||||
? `(selected: ${selectedIconKey})`
|
||||
: `(no icon selected)`
|
||||
}`}
|
||||
disabled={disabled}
|
||||
Icon={icon}
|
||||
variant={variant}
|
||||
size={size}
|
||||
/>
|
||||
)
|
||||
}
|
||||
dropdownComponents={
|
||||
<DropdownContent widthInPixels={ICON_PICKER_DROPDOWN_CONTENT_WIDTH}>
|
||||
<DropdownContent
|
||||
widthInPixels={dropdownWidth || ICON_PICKER_DROPDOWN_CONTENT_WIDTH}
|
||||
>
|
||||
<SelectableList
|
||||
selectableListInstanceId="icon-list"
|
||||
selectableItemIdMatrix={iconKeys2d}
|
||||
|
||||
@ -41,6 +41,7 @@ export type SelectProps<Value extends SelectValue> = {
|
||||
emptyOption?: SelectOption<Value>;
|
||||
fullWidth?: boolean;
|
||||
label?: string;
|
||||
description?: string;
|
||||
onChange?: (value: Value) => void;
|
||||
onBlur?: () => void;
|
||||
options: SelectOption<Value>[];
|
||||
@ -64,6 +65,11 @@ const StyledLabel = styled.span`
|
||||
margin-bottom: ${({ theme }) => theme.spacing(1)};
|
||||
`;
|
||||
|
||||
const StyledDescription = styled.span`
|
||||
color: ${({ theme }) => theme.font.color.light};
|
||||
font-size: ${({ theme }) => theme.font.size.sm};
|
||||
`;
|
||||
|
||||
export const Select = <Value extends SelectValue>({
|
||||
className,
|
||||
disabled: disabledFromProps,
|
||||
@ -74,6 +80,7 @@ export const Select = <Value extends SelectValue>({
|
||||
emptyOption,
|
||||
fullWidth,
|
||||
label,
|
||||
description,
|
||||
onChange,
|
||||
onBlur,
|
||||
options,
|
||||
@ -214,6 +221,7 @@ export const Select = <Value extends SelectValue>({
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{!!description && <StyledDescription>{description}</StyledDescription>}
|
||||
</StyledContainer>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user