Scrollable fixed dropdowns container minor refactor (#9159)

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
nitin 2024-12-20 15:13:48 +05:30 committed by GitHub
parent 94136d953e
commit 54c4d64ae8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 101 additions and 128 deletions

View File

@ -1,8 +1,3 @@
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { PositionType } from '../types/PositionType';
import { actionMenuEntriesComponentSelector } from '@/action-menu/states/actionMenuEntriesComponentSelector';
import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext';
import { recordIndexActionMenuDropdownPositionComponentState } from '@/action-menu/states/recordIndexActionMenuDropdownPositionComponentState';
@ -13,7 +8,10 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { MenuItem } from 'twenty-ui';
import { PositionType } from '../types/PositionType';
type StyledContainerProps = {
position: PositionType;

View File

@ -99,6 +99,7 @@ export const FavoriteFolderPicker = ({
toggleFolderSelection={toggleFolderSelection}
/>
</DropdownMenuItemsContainer>
<DropdownMenuSeparator />
<FavoriteFolderPickerFooter dropdownId={dropdownId} />
</DropdownMenu>
);

View File

@ -4,16 +4,9 @@ import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { useNavigationSection } from '@/ui/navigation/navigation-drawer/hooks/useNavigationSection';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useRecoilState, useSetRecoilState } from 'recoil';
import { IconPlus, MenuItem } from 'twenty-ui';
const StyledFooter = styled.div`
border-bottom-left-radius: ${({ theme }) => theme.border.radius.md};
border-bottom-right-radius: ${({ theme }) => theme.border.radius.md};
border-top: 1px solid ${({ theme }) => theme.border.color.light};
`;
export const FavoriteFolderPickerFooter = ({
dropdownId,
}: {
@ -30,20 +23,18 @@ export const FavoriteFolderPickerFooter = ({
const { closeDropdown } = useDropdown(dropdownId);
return (
<StyledFooter>
<DropdownMenuItemsContainer>
<MenuItem
className="add-folder"
onClick={() => {
setIsNavigationDrawerExpanded(true);
openNavigationSection();
setIsFavoriteFolderCreating(true);
closeDropdown();
}}
text="Add folder"
LeftIcon={() => <IconPlus size={theme.icon.size.md} />}
/>
</DropdownMenuItemsContainer>
</StyledFooter>
<DropdownMenuItemsContainer scrollable={false}>
<MenuItem
className="add-folder"
onClick={() => {
setIsNavigationDrawerExpanded(true);
openNavigationSection();
setIsFavoriteFolderCreating(true);
closeDropdown();
}}
text="Add folder"
LeftIcon={() => <IconPlus size={theme.icon.size.md} />}
/>
</DropdownMenuItemsContainer>
);
};

View File

@ -62,7 +62,7 @@ export const ObjectOptionsDropdownFieldsContent = () => {
showDragGrip={true}
/>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer withoutScrollWrapper>
<DropdownMenuItemsContainer scrollable={false}>
<MenuItemNavigate
onClick={() => onContentChange('hiddenFields')}
LeftIcon={IconEyeOff}

View File

@ -87,7 +87,7 @@ export const ObjectOptionsDropdownHiddenFieldsContent = () => {
closeDropdown();
}}
>
<DropdownMenuItemsContainer withoutScrollWrapper>
<DropdownMenuItemsContainer scrollable={false}>
<MenuItem LeftIcon={IconSettings} text="Edit Fields" />
</DropdownMenuItemsContainer>
</UndecoratedLink>

View File

@ -98,7 +98,7 @@ export const ObjectOptionsDropdownMenuContent = () => {
{/** TODO: Should be removed when view settings contains more options */}
{viewType === ViewType.Kanban && (
<>
<DropdownMenuItemsContainer withoutScrollWrapper>
<DropdownMenuItemsContainer scrollable={false}>
<MenuItem
onClick={() => onContentChange('viewSettings')}
LeftIcon={IconLayout}
@ -109,7 +109,7 @@ export const ObjectOptionsDropdownMenuContent = () => {
<DropdownMenuSeparator />
</>
)}
<DropdownMenuItemsContainer withoutScrollWrapper>
<DropdownMenuItemsContainer scrollable={false}>
<MenuItem
onClick={() => onContentChange('fields')}
LeftIcon={IconTag}

View File

@ -53,7 +53,7 @@ export const RecordTableHeaderPlusButtonContent = () => {
))}
</DropdownMenuItemsContainer>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer withoutScrollWrapper>
<DropdownMenuItemsContainer scrollable={false}>
<UndecoratedLink
fullWidth
to={`/settings/objects/${getObjectSlug(objectMetadataItem)}`}

View File

@ -144,7 +144,7 @@ export const MultiRecordSelect = ({
{dropdownPlacement?.includes('end') && (
<>
{isDefined(onCreate) && (
<DropdownMenuItemsContainer>
<DropdownMenuItemsContainer scrollable={false}>
{createNewButton}
</DropdownMenuItemsContainer>
)}
@ -181,7 +181,7 @@ export const MultiRecordSelect = ({
<DropdownMenuSeparator />
)}
{isDefined(onCreate) && (
<DropdownMenuItemsContainer withoutScrollWrapper>
<DropdownMenuItemsContainer scrollable={false}>
{createNewButton}
</DropdownMenuItemsContainer>
)}

View File

@ -69,7 +69,7 @@ export const SingleRecordSelectMenuItemsWithSearch = ({
<>
{dropdownPlacement?.includes('end') && (
<>
<DropdownMenuItemsContainer>
<DropdownMenuItemsContainer scrollable={false}>
{createNewButton}
</DropdownMenuItemsContainer>
{records.recordsToSelect.length > 0 && <DropdownMenuSeparator />}
@ -117,7 +117,7 @@ export const SingleRecordSelectMenuItemsWithSearch = ({
<DropdownMenuSeparator />
)}
{isDefined(onCreate) && (
<DropdownMenuItemsContainer>
<DropdownMenuItemsContainer scrollable={false}>
{createNewButton}
</DropdownMenuItemsContainer>
)}

View File

@ -8,7 +8,6 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useMemo } from 'react';
import {
ColorSample,
IconCheck,
@ -21,7 +20,6 @@ import {
MenuItem,
MenuItemSelectColor,
} from 'twenty-ui';
import { v4 } from 'uuid';
import { computeOptionValueFromLabel } from '~/pages/settings/data-model/utils/compute-option-value-from-label.utils';
type SettingsDataModelFieldSelectFormOptionRowProps = {
@ -81,17 +79,14 @@ export const SettingsDataModelFieldSelectFormOptionRow = ({
}: SettingsDataModelFieldSelectFormOptionRowProps) => {
const theme = useTheme();
const dropdownIds = useMemo(() => {
const baseScopeId = `select-field-option-row-${v4()}`;
return {
color: `${baseScopeId}-color`,
actions: `${baseScopeId}-actions`,
};
}, []);
const SELECT_COLOR_DROPDOWN_ID = 'select-color-dropdown';
const SELECT_ACTIONS_DROPDOWN_ID = 'select-actions-dropdown';
const { closeDropdown: closeColorDropdown } = useDropdown(dropdownIds.color);
const { closeDropdown: closeColorDropdown } = useDropdown(
SELECT_COLOR_DROPDOWN_ID,
);
const { closeDropdown: closeActionsDropdown } = useDropdown(
dropdownIds.actions,
SELECT_ACTIONS_DROPDOWN_ID,
);
const handleInputEnter = () => {
@ -120,28 +115,26 @@ export const SettingsDataModelFieldSelectFormOptionRow = ({
/>
</AdvancedSettingsWrapper>
<Dropdown
dropdownId={dropdownIds.color}
dropdownId={SELECT_COLOR_DROPDOWN_ID}
dropdownPlacement="bottom-start"
dropdownHotkeyScope={{
scope: dropdownIds.color,
scope: SELECT_COLOR_DROPDOWN_ID,
}}
clickableComponent={<StyledColorSample colorName={option.color} />}
dropdownComponents={
<DropdownMenu>
<DropdownMenuItemsContainer>
{MAIN_COLOR_NAMES.map((colorName) => (
<MenuItemSelectColor
key={colorName}
onClick={() => {
onChange({ ...option, color: colorName });
closeColorDropdown();
}}
color={colorName}
selected={colorName === option.color}
/>
))}
</DropdownMenuItemsContainer>
</DropdownMenu>
<DropdownMenuItemsContainer>
{MAIN_COLOR_NAMES.map((colorName) => (
<MenuItemSelectColor
key={colorName}
onClick={() => {
onChange({ ...option, color: colorName });
closeColorDropdown();
}}
color={colorName}
selected={colorName === option.color}
/>
))}
</DropdownMenuItemsContainer>
}
/>
<StyledOptionInput
@ -165,10 +158,10 @@ export const SettingsDataModelFieldSelectFormOptionRow = ({
autoSelectOnMount={isNewRow}
/>
<Dropdown
dropdownId={dropdownIds.actions}
dropdownId={SELECT_ACTIONS_DROPDOWN_ID}
dropdownPlacement="right-start"
dropdownHotkeyScope={{
scope: dropdownIds.actions,
scope: SELECT_ACTIONS_DROPDOWN_ID,
}}
clickableComponent={
<StyledLightIconButton accent="tertiary" Icon={IconDotsVertical} />

View File

@ -16,7 +16,6 @@ import { SettingsSummaryCard } from '@/settings/components/SettingsSummaryCard';
import { SettingsDataModelObjectTypeTag } from '@/settings/data-model/objects/components/SettingsDataModelObjectTypeTag';
import { getObjectTypeLabel } from '@/settings/data-model/utils/getObjectTypeLabel';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
@ -86,21 +85,20 @@ export const SettingsObjectSummaryCard = ({
accent="tertiary"
/>
}
dropdownMenuWidth={160}
dropdownComponents={
<DropdownMenu width="160px">
<DropdownMenuItemsContainer>
<MenuItem
text="Edit"
LeftIcon={IconPencil}
onClick={handleEdit}
/>
<MenuItem
text="Deactivate"
LeftIcon={IconArchive}
onClick={handleDeactivate}
/>
</DropdownMenuItemsContainer>
</DropdownMenu>
<DropdownMenuItemsContainer>
<MenuItem
text="Edit"
LeftIcon={IconPencil}
onClick={handleEdit}
/>
<MenuItem
text="Deactivate"
LeftIcon={IconArchive}
onClick={handleDeactivate}
/>
</DropdownMenuItemsContainer>
}
dropdownHotkeyScope={{
scope: dropdownId,

View File

@ -1,7 +1,6 @@
import { SettingsSummaryCard } from '@/settings/components/SettingsSummaryCard';
import { SettingsIntegrationDatabaseConnectionSyncStatus } from '@/settings/integrations/database-connection/components/SettingsIntegrationDatabaseConnectionSyncStatus';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import styled from '@emotion/styled';
import {
@ -64,18 +63,16 @@ export const SettingsIntegrationDatabaseConnectionSummaryCard = ({
<LightIconButton Icon={IconDotsVertical} accent="tertiary" />
}
dropdownComponents={
<DropdownMenu>
<DropdownMenuItemsContainer>
<MenuItem
LeftIcon={IconTrash}
text="Remove"
onClick={onRemove}
/>
<UndecoratedLink to="./edit">
<MenuItem LeftIcon={IconPencil} text="Edit" />
</UndecoratedLink>
</DropdownMenuItemsContainer>
</DropdownMenu>
<DropdownMenuItemsContainer>
<MenuItem
LeftIcon={IconTrash}
text="Remove"
onClick={onRemove}
/>
<UndecoratedLink to="./edit">
<MenuItem LeftIcon={IconPencil} text="Edit" />
</UndecoratedLink>
</DropdownMenuItemsContainer>
}
/>
</>

View File

@ -165,7 +165,7 @@ export const Select = <Value extends SelectValue>({
<DropdownMenuSeparator />
)}
{!!callToActionButton && (
<DropdownMenuItemsContainer hasMaxHeight withoutScrollWrapper>
<DropdownMenuItemsContainer hasMaxHeight scrollable={false}>
<MenuItem
onClick={callToActionButton.onClick}
LeftIcon={callToActionButton.Icon}

View File

@ -38,16 +38,16 @@ export const DropdownMenuItemsContainer = ({
children,
hasMaxHeight,
className,
withoutScrollWrapper,
scrollable = true,
}: {
children: React.ReactNode;
hasMaxHeight?: boolean;
className?: string;
withoutScrollWrapper?: boolean;
scrollable?: boolean;
}) => {
const id = useId();
return withoutScrollWrapper === true ? (
return scrollable !== true ? (
<StyledDropdownMenuItemsExternalContainer
hasMaxHeight={hasMaxHeight}
className={className}

View File

@ -19,7 +19,6 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi
import { isWorkflowSubObjectMetadata } from '@/object-metadata/utils/isWorkflowSubObjectMetadata';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { Dropdown } from '../../dropdown/components/Dropdown';
import { DropdownMenu } from '../../dropdown/components/DropdownMenu';
const StyledContainer = styled.div`
z-index: 1;
@ -93,22 +92,20 @@ export const ShowPageAddButton = ({
)
}
dropdownComponents={
<DropdownMenu>
<DropdownMenuItemsContainer>
<MenuItem
onClick={() => handleSelect(CoreObjectNameSingular.Note)}
accent="default"
LeftIcon={IconNotes}
text="Note"
/>
<MenuItem
onClick={() => handleSelect(CoreObjectNameSingular.Task)}
accent="default"
LeftIcon={IconCheckbox}
text="Task"
/>
</DropdownMenuItemsContainer>
</DropdownMenu>
<DropdownMenuItemsContainer>
<MenuItem
onClick={() => handleSelect(CoreObjectNameSingular.Note)}
accent="default"
LeftIcon={IconNotes}
text="Note"
/>
<MenuItem
onClick={() => handleSelect(CoreObjectNameSingular.Task)}
accent="default"
LeftIcon={IconCheckbox}
text="Task"
/>
</DropdownMenuItemsContainer>
}
dropdownHotkeyScope={{
scope: PageHotkeyScope.ShowPage,

View File

@ -7,13 +7,13 @@ import { SummaryCard } from '@/object-record/record-show/components/SummaryCard'
import { RecordLayout } from '@/object-record/record-show/types/RecordLayout';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { RightDrawerFooter } from '@/ui/layout/right-drawer/components/RightDrawerFooter';
import { ShowPageLeftContainer } from '@/ui/layout/show-page/components/ShowPageLeftContainer';
import { SingleTabProps, TabList } from '@/ui/layout/tab/components/TabList';
import { useTabList } from '@/ui/layout/tab/hooks/useTabList';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import styled from '@emotion/styled';
import { useRecoilState, useRecoilValue } from 'recoil';
import { RightDrawerFooter } from '@/ui/layout/right-drawer/components/RightDrawerFooter';
const StyledShowPageRightContainer = styled.div<{ isMobile: boolean }>`
display: flex;

View File

@ -112,15 +112,13 @@ export const UpdateViewButtonGroup = ({
/>
}
dropdownComponents={
<>
<DropdownMenuItemsContainer>
<MenuItem
onClick={handleCreateViewClick}
LeftIcon={IconPlus}
text="Create view"
/>
</DropdownMenuItemsContainer>
</>
<DropdownMenuItemsContainer>
<MenuItem
onClick={handleCreateViewClick}
LeftIcon={IconPlus}
text="Create view"
/>
</DropdownMenuItemsContainer>
}
/>
</ButtonGroup>

View File

@ -190,7 +190,7 @@ export const ViewPickerContentCreateMode = () => {
)}
</DropdownMenuItemsContainer>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer>
<DropdownMenuItemsContainer scrollable={false}>
<ViewPickerSaveButtonContainer>
<ViewPickerCreateButton />
</ViewPickerSaveButtonContainer>

View File

@ -89,7 +89,7 @@ export const ViewPickerContentEditMode = () => {
</ViewPickerIconAndNameContainer>
</DropdownMenuItemsContainer>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer>
<DropdownMenuItemsContainer scrollable={false}>
<ViewPickerSaveButtonContainer>
<ViewPickerEditButton />
</ViewPickerSaveButtonContainer>

View File

@ -97,7 +97,7 @@ export const ViewPickerListContent = () => {
/>
</DropdownMenuItemsContainer>
<DropdownMenuSeparator />
<StyledBoldDropdownMenuItemsContainer>
<StyledBoldDropdownMenuItemsContainer scrollable={false}>
<MenuItem
onClick={handleAddViewButtonClick}
LeftIcon={IconPlus}