Use SelectableList in RelationPicker, SingleEntitySelectBase and MultipleEntitySelect (#2949)

* 2747-fix: conditional updation of selectedItemId

* 2747-fix: bug in toggling

* 2747-feat: SingleEntitySelectBase list changed to SelectableList

* 2747-feat: MultipleEntitySelect use SelectableList

* Fix lint

* 2747-fix: onEnter property fix for SingleEntitySelectBase

* 2747-fix: onEnter property fix for MultipleEntitySelect

* yarn fix in twenty-front

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Kanav Arora
2023-12-14 16:40:58 +05:30
committed by GitHub
parent 4673a302c7
commit ed2cd408bf
10 changed files with 297 additions and 75 deletions

View File

@ -1,4 +1,4 @@
import { Meta, Story, StoryObj } from '@storybook/react';
import { Meta, StoryObj } from '@storybook/react';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';

View File

@ -16,8 +16,7 @@ export const useSelectableListHotKeys = (
selectedItemId?: string | null,
) => {
if (!selectedItemId) {
// If nothing is selected, return the default position
return { row: 0, col: 0 };
return { row: 0, col: -1 };
}
for (let row = 0; row < selectableItemIds.length; row++) {
@ -94,21 +93,23 @@ export const useSelectableListHotKeys = (
const nextId = computeNextId(direction);
if (nextId) {
const { isSelectedItemIdSelector } = getSelectableListScopedStates({
selectableListScopeId: scopeId,
itemId: nextId,
});
set(isSelectedItemIdSelector, true);
set(selectedItemIdState, nextId);
}
if (!selectedItemId || (selectedItemId && selectedItemId !== nextId)) {
if (nextId) {
const { isSelectedItemIdSelector } = getSelectableListScopedStates({
selectableListScopeId: scopeId,
itemId: nextId,
});
set(isSelectedItemIdSelector, true);
set(selectedItemIdState, nextId);
}
if (selectedItemId) {
const { isSelectedItemIdSelector } = getSelectableListScopedStates({
selectableListScopeId: scopeId,
itemId: selectedItemId,
});
set(isSelectedItemIdSelector, false);
if (selectedItemId) {
const { isSelectedItemIdSelector } = getSelectableListScopedStates({
selectableListScopeId: scopeId,
itemId: selectedItemId,
});
set(isSelectedItemIdSelector, false);
}
}
},
[scopeId],

View File

@ -19,6 +19,7 @@ const StyledLeftContentWithCheckboxContainer = styled.div`
type MenuItemMultiSelectAvatarProps = {
avatar?: ReactNode;
selected: boolean;
isKeySelected: boolean;
text: string;
className?: string;
onSelectChange?: (selected: boolean) => void;
@ -29,6 +30,7 @@ export const MenuItemMultiSelectAvatar = ({
text,
selected,
className,
isKeySelected,
onSelectChange,
}: MenuItemMultiSelectAvatarProps) => {
const handleOnClick = () => {
@ -36,7 +38,11 @@ export const MenuItemMultiSelectAvatar = ({
};
return (
<StyledMenuItemBase className={className} onClick={handleOnClick}>
<StyledMenuItemBase
className={className}
onClick={handleOnClick}
isKeySelected={isKeySelected}
>
<StyledLeftContentWithCheckboxContainer>
<Checkbox checked={selected} />
<StyledMenuItemLeftContent>

View File

@ -7,6 +7,7 @@ import { MenuItemAccent } from '../../types/MenuItemAccent';
export type MenuItemBaseProps = {
accent?: MenuItemAccent;
isKeySelected?: boolean;
};
export const StyledMenuItemBase = styled.li<MenuItemBaseProps>`
@ -15,8 +16,13 @@ export const StyledMenuItemBase = styled.li<MenuItemBaseProps>`
align-items: center;
background: ${({ isKeySelected, theme }) =>
isKeySelected
? theme.background.transparent.light
: theme.background.primary};
border-radius: ${({ theme }) => theme.border.radius.sm};
cursor: pointer;
display: flex;
flex-direction: row;
@ -26,8 +32,8 @@ export const StyledMenuItemBase = styled.li<MenuItemBaseProps>`
gap: ${({ theme }) => theme.spacing(2)};
height: calc(32px - 2 * var(--vertical-padding));
justify-content: space-between;
padding: var(--vertical-padding) var(--horizontal-padding);
${hoverBackground};