Migrate dropdown to scope map (#3338)
* Migrate dropdown to scope map * Run lintr * Move Dropdown Scope internally * Fix * Fix lint --------- Co-authored-by: Thomas Trompette <thomast@twenty.com> Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -4,7 +4,6 @@ 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';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
|
||||
type AttachmentDropdownProps = {
|
||||
@ -18,9 +17,9 @@ export const AttachmentDropdown = ({
|
||||
onDelete,
|
||||
scopeKey,
|
||||
}: AttachmentDropdownProps) => {
|
||||
const dropdownScopeId = `${scopeKey}-settings-field-active-action-dropdown`;
|
||||
const dropdownId = `${scopeKey}-settings-field-active-action-dropdown`;
|
||||
|
||||
const { closeDropdown } = useDropdown(dropdownScopeId);
|
||||
const { closeDropdown } = useDropdown(dropdownId);
|
||||
|
||||
const handleDownload = () => {
|
||||
onDownload();
|
||||
@ -33,8 +32,8 @@ export const AttachmentDropdown = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<DropdownScope dropdownScopeId={dropdownScopeId}>
|
||||
<Dropdown
|
||||
dropdownId={dropdownId}
|
||||
clickableComponent={
|
||||
<LightIconButton Icon={IconDotsVertical} accent="tertiary" />
|
||||
}
|
||||
@ -56,9 +55,8 @@ export const AttachmentDropdown = ({
|
||||
</DropdownMenu>
|
||||
}
|
||||
dropdownHotkeyScope={{
|
||||
scope: dropdownScopeId,
|
||||
scope: dropdownId,
|
||||
}}
|
||||
/>
|
||||
</DropdownScope>
|
||||
);
|
||||
};
|
||||
|
||||
@ -6,6 +6,7 @@ import {
|
||||
RecordBoardProps,
|
||||
} from '@/object-record/record-board/components/RecordBoard';
|
||||
import { RecordBoardEffect } from '@/object-record/record-board/components/RecordBoardEffect';
|
||||
import { BoardOptionsDropdownId } from '@/object-record/record-board/constants/BoardOptionsDropdownId';
|
||||
import { RecordBoardOptionsDropdown } from '@/object-record/record-board/options/components/RecordBoardOptionsDropdown';
|
||||
import { ViewBar } from '@/views/components/ViewBar';
|
||||
import { useViewFields } from '@/views/hooks/internal/useViewFields';
|
||||
@ -43,7 +44,7 @@ export const CompanyBoard = ({
|
||||
optionsDropdownButton={
|
||||
<RecordBoardOptionsDropdown recordBoardId={recordBoardId} />
|
||||
}
|
||||
optionsDropdownScopeId={recordBoardId}
|
||||
optionsDropdownScopeId={BoardOptionsDropdownId}
|
||||
/>
|
||||
|
||||
<HooksCompanyBoardEffect
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||
|
||||
import { ObjectFilterDropdownId } from '../constants/ObjectFilterDropdownId';
|
||||
@ -18,14 +17,13 @@ export const MultipleFiltersDropdownButton = ({
|
||||
const { resetFilter } = useFilterDropdown();
|
||||
|
||||
return (
|
||||
<DropdownScope dropdownScopeId={ObjectFilterDropdownId}>
|
||||
<Dropdown
|
||||
dropdownId={ObjectFilterDropdownId}
|
||||
onClose={resetFilter}
|
||||
clickableComponent={<MultipleFiltersButton />}
|
||||
dropdownComponents={<MultipleFiltersDropdownContent />}
|
||||
dropdownHotkeyScope={hotkeyScope}
|
||||
dropdownOffset={{ y: 8 }}
|
||||
/>
|
||||
</DropdownScope>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { ObjectFilterDropdownId } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
|
||||
export const MultipleFiltersDropdownFilterOnFilterChangedEffect = ({
|
||||
@ -7,7 +8,7 @@ export const MultipleFiltersDropdownFilterOnFilterChangedEffect = ({
|
||||
}: {
|
||||
filterDefinitionUsedInDropdownType: string | undefined;
|
||||
}) => {
|
||||
const { setDropdownWidth } = useDropdown();
|
||||
const { setDropdownWidth } = useDropdown(ObjectFilterDropdownId);
|
||||
|
||||
useEffect(() => {
|
||||
switch (filterDefinitionUsedInDropdownType) {
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { ObjectFilterDropdownId } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId';
|
||||
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
|
||||
import { EntitiesForMultipleEntitySelect } from '@/object-record/relation-picker/components/MultipleEntitySelect';
|
||||
import { SingleEntitySelectMenuItems } from '@/object-record/relation-picker/components/SingleEntitySelectMenuItems';
|
||||
@ -21,7 +22,7 @@ export const ObjectFilterDropdownEntitySearchSelect = ({
|
||||
selectFilter,
|
||||
} = useFilterDropdown();
|
||||
|
||||
const { closeDropdown } = useDropdown();
|
||||
const { closeDropdown } = useDropdown(ObjectFilterDropdownId);
|
||||
|
||||
const [isAllEntitySelected, setIsAllEntitySelected] = useState(false);
|
||||
|
||||
|
||||
@ -5,7 +5,6 @@ import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/
|
||||
import { IconChevronDown } from '@/ui/display/icon/index';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
|
||||
@ -42,8 +41,8 @@ export const SingleEntityObjectFilterDropdownButton = ({
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<DropdownScope dropdownScopeId="single-entity-filter-dropdown">
|
||||
<Dropdown
|
||||
dropdownId="single-entity-filter-dropdown"
|
||||
dropdownHotkeyScope={hotkeyScope}
|
||||
dropdownOffset={{ x: 0, y: -28 }}
|
||||
clickableComponent={
|
||||
@ -70,6 +69,5 @@ export const SingleEntityObjectFilterDropdownButton = ({
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</DropdownScope>
|
||||
);
|
||||
};
|
||||
|
||||
@ -10,7 +10,6 @@ import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenu
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||
|
||||
@ -70,8 +69,8 @@ export const ObjectSortDropdownButton = ({
|
||||
|
||||
return (
|
||||
<ObjectSortDropdownScope sortScopeId={sortDropdownId}>
|
||||
<DropdownScope dropdownScopeId={ObjectSortDropdownId}>
|
||||
<Dropdown
|
||||
dropdownId={ObjectSortDropdownId}
|
||||
dropdownHotkeyScope={hotkeyScope}
|
||||
dropdownOffset={{ y: 8 }}
|
||||
clickableComponent={
|
||||
@ -102,9 +101,7 @@ export const ObjectSortDropdownButton = ({
|
||||
EndIcon={IconChevronDown}
|
||||
onClick={() => setIsSortDirectionMenuUnfolded(true)}
|
||||
>
|
||||
{selectedSortDirection === 'asc'
|
||||
? 'Ascending'
|
||||
: 'Descending'}
|
||||
{selectedSortDirection === 'asc' ? 'Ascending' : 'Descending'}
|
||||
</DropdownMenuHeader>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItemsContainer>
|
||||
@ -126,7 +123,6 @@ export const ObjectSortDropdownButton = ({
|
||||
}
|
||||
onClose={handleDropdownButtonClose}
|
||||
/>
|
||||
</DropdownScope>
|
||||
</ObjectSortDropdownScope>
|
||||
);
|
||||
};
|
||||
|
||||
@ -0,0 +1 @@
|
||||
export const BoardOptionsDropdownId = 'board-options-dropdown-id';
|
||||
@ -1,8 +1,7 @@
|
||||
import { BoardOptionsDropdownId } from '@/object-record/record-board/constants/BoardOptionsDropdownId';
|
||||
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||
|
||||
import { Dropdown } from '../../../../ui/layout/dropdown/components/Dropdown';
|
||||
import { DropdownScope } from '../../../../ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { BoardOptionsDropdownId } from '../../components/constants/BoardOptionsDropdownId';
|
||||
import { BoardOptionsHotkeyScope } from '../../types/BoardOptionsHotkeyScope';
|
||||
|
||||
import { RecordBoardOptionsDropdownButton } from './RecordBoardOptionsDropdownButton';
|
||||
@ -23,8 +22,8 @@ export const RecordBoardOptionsDropdown = ({
|
||||
const { setViewEditMode } = useViewBar();
|
||||
|
||||
return (
|
||||
<DropdownScope dropdownScopeId={BoardOptionsDropdownId}>
|
||||
<Dropdown
|
||||
dropdownId={BoardOptionsDropdownId}
|
||||
clickableComponent={<RecordBoardOptionsDropdownButton />}
|
||||
dropdownComponents={
|
||||
<RecordBoardOptionsDropdownContent
|
||||
@ -36,6 +35,5 @@ export const RecordBoardOptionsDropdown = ({
|
||||
onClickOutside={() => setViewEditMode('none')}
|
||||
dropdownMenuWidth={170}
|
||||
/>
|
||||
</DropdownScope>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
import { BoardOptionsDropdownId } from '@/object-record/record-board/constants/BoardOptionsDropdownId';
|
||||
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
|
||||
export const RecordBoardOptionsDropdownButton = () => {
|
||||
const { isDropdownOpen, toggleDropdown } = useDropdown();
|
||||
const { isDropdownOpen, toggleDropdown } = useDropdown(
|
||||
BoardOptionsDropdownId,
|
||||
);
|
||||
|
||||
const handleClick = () => {
|
||||
toggleDropdown();
|
||||
|
||||
@ -4,6 +4,7 @@ import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { Key } from 'ts-key-enum';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { BoardOptionsDropdownId } from '@/object-record/record-board/constants/BoardOptionsDropdownId';
|
||||
import { useRecordBoardScopedStates } from '@/object-record/record-board/hooks/internal/useRecordBoardScopedStates';
|
||||
import {
|
||||
IconBaselineDensitySmall,
|
||||
@ -110,7 +111,7 @@ export const RecordBoardOptionsDropdownContent = ({
|
||||
recordBoardScopeId: recordBoardId,
|
||||
});
|
||||
|
||||
const { closeDropdown } = useDropdown();
|
||||
const { closeDropdown } = useDropdown(BoardOptionsDropdownId);
|
||||
|
||||
const handleReorderField: OnDragEndResponder = useCallback(
|
||||
(result) => {
|
||||
|
||||
@ -23,7 +23,6 @@ import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
|
||||
import { Card } from '@/ui/layout/card/components/Card';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
|
||||
const StyledAddDropdown = styled(Dropdown)`
|
||||
@ -129,9 +128,9 @@ export const RecordRelationFieldCardSection = () => {
|
||||
);
|
||||
}, [relationRecords, upsertRecordFromState]);
|
||||
|
||||
const dropdownScopeId = `record-field-card-relation-picker-${fieldDefinition.label}`;
|
||||
const dropdownId = `record-field-card-relation-picker-${fieldDefinition.label}`;
|
||||
|
||||
const { closeDropdown, isDropdownOpen } = useDropdown(dropdownScopeId);
|
||||
const { closeDropdown, isDropdownOpen } = useDropdown(dropdownId);
|
||||
|
||||
const {
|
||||
identifiersMapper,
|
||||
@ -196,8 +195,8 @@ export const RecordRelationFieldCardSection = () => {
|
||||
<Section>
|
||||
<StyledHeader isDropdownOpen={isDropdownOpen}>
|
||||
<StyledTitle>{fieldDefinition.label}</StyledTitle>
|
||||
<DropdownScope dropdownScopeId={dropdownScopeId}>
|
||||
<StyledAddDropdown
|
||||
dropdownId={dropdownId}
|
||||
dropdownPlacement="right-start"
|
||||
onClose={handleCloseRelationPickerDropdown}
|
||||
clickableComponent={
|
||||
@ -216,10 +215,9 @@ export const RecordRelationFieldCardSection = () => {
|
||||
/>
|
||||
}
|
||||
dropdownHotkeyScope={{
|
||||
scope: dropdownScopeId,
|
||||
scope: dropdownId,
|
||||
}}
|
||||
/>
|
||||
</DropdownScope>
|
||||
</StyledHeader>
|
||||
{!!relationRecords.length && (
|
||||
<Card>
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
|
||||
import { FieldMetadata } from '../../field/types/FieldMetadata';
|
||||
import { ColumnDefinition } from '../types/ColumnDefinition';
|
||||
@ -28,8 +27,8 @@ export const ColumnHeadWithDropdown = ({
|
||||
primaryColumnKey,
|
||||
}: ColumnHeadWithDropdownProps) => {
|
||||
return (
|
||||
<DropdownScope dropdownScopeId={column.fieldMetadataId + '-header'}>
|
||||
<StyledDropdown
|
||||
dropdownId={column.fieldMetadataId + '-header'}
|
||||
clickableComponent={<ColumnHead column={column} />}
|
||||
dropdownComponents={
|
||||
<RecordTableColumnDropdownMenu
|
||||
@ -43,6 +42,5 @@ export const ColumnHeadWithDropdown = ({
|
||||
dropdownPlacement="bottom-start"
|
||||
dropdownHotkeyScope={{ scope: column.fieldMetadataId + '-header' }}
|
||||
/>
|
||||
</DropdownScope>
|
||||
);
|
||||
};
|
||||
|
||||
@ -6,7 +6,6 @@ import { RecordTableHeaderCell } from '@/object-record/record-table/components/R
|
||||
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
|
||||
import { IconPlus } from '@/ui/display/icon';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { useScrollWrapperScopedRef } from '@/ui/utilities/scroll/hooks/useScrollWrapperScopedRef';
|
||||
|
||||
import { useRecordTableScopedStates } from '../hooks/internal/useRecordTableScopedStates';
|
||||
@ -48,7 +47,7 @@ const StyledPlusIconContainer = styled.div`
|
||||
width: 32px;
|
||||
`;
|
||||
|
||||
const HIDDEN_TABLE_COLUMN_DROPDOWN_SCOPE_ID =
|
||||
export const HIDDEN_TABLE_COLUMN_DROPDOWN_ID =
|
||||
'hidden-table-columns-dropdown-scope-id';
|
||||
|
||||
const HIDDEN_TABLE_COLUMN_DROPDOWN_HOTKEY_SCOPE_ID =
|
||||
@ -106,10 +105,8 @@ export const RecordTableHeader = ({
|
||||
isTableWiderThanScreen={isTableWiderThanScreen}
|
||||
>
|
||||
{hiddenTableColumns.length > 0 && (
|
||||
<DropdownScope
|
||||
dropdownScopeId={HIDDEN_TABLE_COLUMN_DROPDOWN_SCOPE_ID}
|
||||
>
|
||||
<Dropdown
|
||||
dropdownId={HIDDEN_TABLE_COLUMN_DROPDOWN_ID}
|
||||
clickableComponent={
|
||||
<StyledPlusIconContainer>
|
||||
<IconPlus size={theme.icon.size.md} />
|
||||
@ -121,7 +118,6 @@ export const RecordTableHeader = ({
|
||||
scope: HIDDEN_TABLE_COLUMN_DROPDOWN_HOTKEY_SCOPE_ID,
|
||||
}}
|
||||
/>
|
||||
</DropdownScope>
|
||||
)}
|
||||
</StyledPlusIconHeaderCell>
|
||||
</tr>
|
||||
|
||||
@ -1 +1 @@
|
||||
export const ColumnHeadDropdownId = 'table-head-options';
|
||||
export const ColumnHeadDropdownId = 'table-head-options-dropdown-id';
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
// We should either apply the constant all caps case or maybe define a more general enum to store those ids ?
|
||||
export const BoardOptionsDropdownId = 'board-options';
|
||||
export const TableHiddenFieldsDropdownId = 'table-hidden-fields-dropdown-id';
|
||||
@ -1,2 +1,2 @@
|
||||
// We should either apply the constant all caps case or maybe define a more general enum to store those ids ?
|
||||
export const TableOptionsDropdownId = 'table-options';
|
||||
export const TableOptionsDropdownId = 'table-options-dropdown-id';
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { useViewBar } from '@/views/hooks/useViewBar';
|
||||
|
||||
import { TableOptionsDropdownId } from '../../constants/TableOptionsDropdownId';
|
||||
@ -18,8 +17,8 @@ export const TableOptionsDropdown = ({
|
||||
const { setViewEditMode } = useViewBar();
|
||||
|
||||
return (
|
||||
<DropdownScope dropdownScopeId={TableOptionsDropdownId}>
|
||||
<Dropdown
|
||||
dropdownId={TableOptionsDropdownId}
|
||||
clickableComponent={<TableOptionsDropdownButton />}
|
||||
dropdownHotkeyScope={{ scope: TableOptionsHotkeyScope.Dropdown }}
|
||||
dropdownOffset={{ y: 8 }}
|
||||
@ -31,6 +30,5 @@ export const TableOptionsDropdown = ({
|
||||
}
|
||||
onClickOutside={() => setViewEditMode('none')}
|
||||
/>
|
||||
</DropdownScope>
|
||||
);
|
||||
};
|
||||
|
||||
@ -3,6 +3,7 @@ import { OnDragEndResponder } from '@hello-pangea/dnd';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { Key } from 'ts-key-enum';
|
||||
|
||||
import { TableOptionsDropdownId } from '@/object-record/record-table/constants/TableOptionsDropdownId';
|
||||
import { useRecordTableScopedStates } from '@/object-record/record-table/hooks/internal/useRecordTableScopedStates';
|
||||
import { getRecordTableScopeInjector } from '@/object-record/record-table/utils/getRecordTableScopeInjector';
|
||||
import { IconChevronLeft, IconFileImport, IconTag } from '@/ui/display/icon';
|
||||
@ -34,7 +35,7 @@ export const TableOptionsDropdownContent = ({
|
||||
|
||||
const viewEditMode = useRecoilValue(viewEditModeState);
|
||||
const currentView = useRecoilValue(currentViewSelector);
|
||||
const { closeDropdown } = useDropdown();
|
||||
const { closeDropdown } = useDropdown(TableOptionsDropdownId);
|
||||
|
||||
const [currentMenu, setCurrentMenu] = useState<TableOptionsMenu | undefined>(
|
||||
undefined,
|
||||
|
||||
@ -8,7 +8,6 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { IconButton } from '@/ui/input/button/components/IconButton';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { logError } from '~/utils/logError';
|
||||
|
||||
export const PipelineAddButton = () => {
|
||||
@ -48,8 +47,8 @@ export const PipelineAddButton = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<DropdownScope dropdownScopeId="add-pipeline-progress">
|
||||
<Dropdown
|
||||
dropdownId="add-pipeline-progress"
|
||||
clickableComponent={
|
||||
<IconButton
|
||||
Icon={IconPlus}
|
||||
@ -75,6 +74,5 @@ export const PipelineAddButton = () => {
|
||||
scope: RelationPickerHotkeyScope.RelationPicker,
|
||||
}}
|
||||
/>
|
||||
</DropdownScope>
|
||||
);
|
||||
};
|
||||
|
||||
@ -7,7 +7,6 @@ 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';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
|
||||
type SettingsAccountsRowDropdownMenuProps = {
|
||||
@ -21,17 +20,17 @@ export const SettingsAccountsRowDropdownMenu = ({
|
||||
className,
|
||||
onRemove,
|
||||
}: SettingsAccountsRowDropdownMenuProps) => {
|
||||
const dropdownScopeId = `settings-account-row-${account.id}`;
|
||||
const dropdownId = `settings-account-row-${account.id}`;
|
||||
|
||||
const navigate = useNavigate();
|
||||
const { closeDropdown } = useDropdown(dropdownScopeId);
|
||||
const { closeDropdown } = useDropdown(dropdownId);
|
||||
|
||||
return (
|
||||
<DropdownScope dropdownScopeId={dropdownScopeId}>
|
||||
<Dropdown
|
||||
dropdownId={dropdownId}
|
||||
className={className}
|
||||
dropdownPlacement="right-start"
|
||||
dropdownHotkeyScope={{ scope: dropdownScopeId }}
|
||||
dropdownHotkeyScope={{ scope: dropdownId }}
|
||||
clickableComponent={
|
||||
<LightIconButton Icon={IconDotsVertical} accent="tertiary" />
|
||||
}
|
||||
@ -61,6 +60,5 @@ export const SettingsAccountsRowDropdownMenu = ({
|
||||
</DropdownMenu>
|
||||
}
|
||||
/>
|
||||
</DropdownScope>
|
||||
);
|
||||
};
|
||||
|
||||
@ -105,7 +105,7 @@ export const SettingsObjectFieldRelationForm = ({
|
||||
<StyledInputsContainer>
|
||||
<IconPicker
|
||||
disabled={disableFieldEdition}
|
||||
dropdownScopeId="field-destination-icon-picker"
|
||||
dropdownId="field-destination-icon-picker"
|
||||
selectedIconKey={values.field.icon || undefined}
|
||||
onChange={(value) =>
|
||||
onChange({
|
||||
|
||||
@ -17,7 +17,6 @@ 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';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
import { MenuItemSelectColor } from '@/ui/navigation/menu-item/components/MenuItemSelectColor';
|
||||
import { mainColorNames } from '@/ui/theme/constants/colors';
|
||||
@ -63,16 +62,14 @@ export const SettingsObjectFieldSelectFormOptionRow = ({
|
||||
}: SettingsObjectFieldSelectFormOptionRowProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const dropdownScopeIds = useMemo(() => {
|
||||
const dropdownIds = useMemo(() => {
|
||||
const baseScopeId = `select-field-option-row-${v4()}`;
|
||||
return { color: `${baseScopeId}-color`, actions: `${baseScopeId}-actions` };
|
||||
}, []);
|
||||
|
||||
const { closeDropdown: closeColorDropdown } = useDropdown(
|
||||
dropdownScopeIds.color,
|
||||
);
|
||||
const { closeDropdown: closeColorDropdown } = useDropdown(dropdownIds.color);
|
||||
const { closeDropdown: closeActionsDropdown } = useDropdown(
|
||||
dropdownScopeIds.actions,
|
||||
dropdownIds.actions,
|
||||
);
|
||||
|
||||
return (
|
||||
@ -82,11 +79,11 @@ export const SettingsObjectFieldSelectFormOptionRow = ({
|
||||
stroke={theme.icon.stroke.sm}
|
||||
color={theme.font.color.extraLight}
|
||||
/>
|
||||
<DropdownScope dropdownScopeId={dropdownScopeIds.color}>
|
||||
<Dropdown
|
||||
dropdownId={dropdownIds.color}
|
||||
dropdownPlacement="bottom-start"
|
||||
dropdownHotkeyScope={{
|
||||
scope: dropdownScopeIds.color,
|
||||
scope: dropdownIds.color,
|
||||
}}
|
||||
clickableComponent={<StyledColorSample colorName={option.color} />}
|
||||
dropdownComponents={
|
||||
@ -107,17 +104,16 @@ export const SettingsObjectFieldSelectFormOptionRow = ({
|
||||
</DropdownMenu>
|
||||
}
|
||||
/>
|
||||
</DropdownScope>
|
||||
<StyledOptionInput
|
||||
value={option.label}
|
||||
onChange={(label) => onChange({ ...option, label })}
|
||||
RightIcon={isDefault ? IconCheck : undefined}
|
||||
/>
|
||||
<DropdownScope dropdownScopeId={dropdownScopeIds.actions}>
|
||||
<Dropdown
|
||||
dropdownId={dropdownIds.actions}
|
||||
dropdownPlacement="right-start"
|
||||
dropdownHotkeyScope={{
|
||||
scope: dropdownScopeIds.actions,
|
||||
scope: dropdownIds.actions,
|
||||
}}
|
||||
clickableComponent={<LightIconButton Icon={IconDotsVertical} />}
|
||||
dropdownComponents={
|
||||
@ -157,7 +153,6 @@ export const SettingsObjectFieldSelectFormOptionRow = ({
|
||||
</DropdownMenu>
|
||||
}
|
||||
/>
|
||||
</DropdownScope>
|
||||
</StyledRow>
|
||||
);
|
||||
};
|
||||
|
||||
@ -12,7 +12,6 @@ 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';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
|
||||
@ -44,7 +43,7 @@ const StyledTag = styled(Tag)`
|
||||
height: ${({ theme }) => theme.spacing(6)};
|
||||
`;
|
||||
|
||||
const dropdownScopeId = 'settings-object-edit-about-menu-dropdown';
|
||||
const dropdownId = 'settings-object-edit-about-menu-dropdown';
|
||||
|
||||
export const SettingsAboutSection = ({
|
||||
iconKey = '',
|
||||
@ -57,7 +56,7 @@ export const SettingsAboutSection = ({
|
||||
const { getIcon } = useIcons();
|
||||
const Icon = getIcon(iconKey);
|
||||
|
||||
const { closeDropdown } = useDropdown(dropdownScopeId);
|
||||
const { closeDropdown } = useDropdown(dropdownId);
|
||||
|
||||
const handleEdit = () => {
|
||||
onEdit();
|
||||
@ -83,8 +82,8 @@ export const SettingsAboutSection = ({
|
||||
) : (
|
||||
<StyledTag color="blue" text="Standard" weight="medium" />
|
||||
)}
|
||||
<DropdownScope dropdownScopeId={dropdownScopeId}>
|
||||
<Dropdown
|
||||
dropdownId={dropdownId}
|
||||
clickableComponent={
|
||||
<LightIconButton Icon={IconDotsVertical} accent="tertiary" />
|
||||
}
|
||||
@ -105,10 +104,9 @@ export const SettingsAboutSection = ({
|
||||
</DropdownMenu>
|
||||
}
|
||||
dropdownHotkeyScope={{
|
||||
scope: dropdownScopeId,
|
||||
scope: dropdownId,
|
||||
}}
|
||||
/>
|
||||
</DropdownScope>
|
||||
</StyledCardContent>
|
||||
</Card>
|
||||
</Section>
|
||||
|
||||
@ -9,7 +9,6 @@ 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';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
|
||||
type SettingsObjectFieldActiveActionDropdownProps = {
|
||||
@ -25,9 +24,9 @@ export const SettingsObjectFieldActiveActionDropdown = ({
|
||||
onEdit,
|
||||
scopeKey,
|
||||
}: SettingsObjectFieldActiveActionDropdownProps) => {
|
||||
const dropdownScopeId = `${scopeKey}-settings-field-active-action-dropdown`;
|
||||
const dropdownId = `${scopeKey}-settings-field-active-action-dropdown`;
|
||||
|
||||
const { closeDropdown } = useDropdown(dropdownScopeId);
|
||||
const { closeDropdown } = useDropdown(dropdownId);
|
||||
|
||||
const handleEdit = () => {
|
||||
onEdit();
|
||||
@ -40,8 +39,8 @@ export const SettingsObjectFieldActiveActionDropdown = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<DropdownScope dropdownScopeId={dropdownScopeId}>
|
||||
<Dropdown
|
||||
dropdownId={dropdownId}
|
||||
clickableComponent={
|
||||
<LightIconButton Icon={IconDotsVertical} accent="tertiary" />
|
||||
}
|
||||
@ -64,9 +63,8 @@ export const SettingsObjectFieldActiveActionDropdown = ({
|
||||
</DropdownMenu>
|
||||
}
|
||||
dropdownHotkeyScope={{
|
||||
scope: dropdownScopeId,
|
||||
scope: dropdownId,
|
||||
}}
|
||||
/>
|
||||
</DropdownScope>
|
||||
);
|
||||
};
|
||||
|
||||
@ -4,7 +4,6 @@ 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';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
|
||||
type SettingsObjectFieldDisabledActionDropdownProps = {
|
||||
@ -18,9 +17,9 @@ export const SettingsObjectFieldDisabledActionDropdown = ({
|
||||
onActivate,
|
||||
scopeKey,
|
||||
}: SettingsObjectFieldDisabledActionDropdownProps) => {
|
||||
const dropdownScopeId = `${scopeKey}-settings-field-disabled-action-dropdown`;
|
||||
const dropdownId = `${scopeKey}-settings-field-disabled-action-dropdown`;
|
||||
|
||||
const { closeDropdown } = useDropdown(dropdownScopeId);
|
||||
const { closeDropdown } = useDropdown(dropdownId);
|
||||
|
||||
const handleActivate = () => {
|
||||
onActivate();
|
||||
@ -33,8 +32,8 @@ export const SettingsObjectFieldDisabledActionDropdown = ({
|
||||
// };
|
||||
|
||||
return (
|
||||
<DropdownScope dropdownScopeId={dropdownScopeId}>
|
||||
<Dropdown
|
||||
dropdownId={dropdownId}
|
||||
clickableComponent={
|
||||
<LightIconButton Icon={IconDotsVertical} accent="tertiary" />
|
||||
}
|
||||
@ -58,9 +57,8 @@ export const SettingsObjectFieldDisabledActionDropdown = ({
|
||||
</DropdownMenu>
|
||||
}
|
||||
dropdownHotkeyScope={{
|
||||
scope: dropdownScopeId,
|
||||
scope: dropdownId,
|
||||
}}
|
||||
/>
|
||||
</DropdownScope>
|
||||
);
|
||||
};
|
||||
|
||||
@ -4,7 +4,6 @@ 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';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
|
||||
type SettingsObjectDisabledMenuDropDownProps = {
|
||||
@ -20,9 +19,9 @@ export const SettingsObjectDisabledMenuDropDown = ({
|
||||
onErase,
|
||||
isCustomObject,
|
||||
}: SettingsObjectDisabledMenuDropDownProps) => {
|
||||
const dropdownScopeId = `${scopeKey}-settings-object-disabled-menu-dropdown`;
|
||||
const dropdownId = `${scopeKey}-settings-object-disabled-menu-dropdown`;
|
||||
|
||||
const { closeDropdown } = useDropdown(dropdownScopeId);
|
||||
const { closeDropdown } = useDropdown(dropdownId);
|
||||
|
||||
const handleActivate = () => {
|
||||
onActivate();
|
||||
@ -35,8 +34,8 @@ export const SettingsObjectDisabledMenuDropDown = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<DropdownScope dropdownScopeId={dropdownScopeId}>
|
||||
<Dropdown
|
||||
dropdownId={dropdownId}
|
||||
clickableComponent={
|
||||
<LightIconButton Icon={IconDotsVertical} accent="tertiary" />
|
||||
}
|
||||
@ -60,9 +59,8 @@ export const SettingsObjectDisabledMenuDropDown = ({
|
||||
</DropdownMenu>
|
||||
}
|
||||
dropdownHotkeyScope={{
|
||||
scope: dropdownScopeId,
|
||||
scope: dropdownId,
|
||||
}}
|
||||
/>
|
||||
</DropdownScope>
|
||||
);
|
||||
};
|
||||
|
||||
@ -11,7 +11,6 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
|
||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||
import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectableList';
|
||||
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||
@ -23,7 +22,7 @@ import { IconPickerHotkeyScope } from '../types/IconPickerHotkeyScope';
|
||||
|
||||
type IconPickerProps = {
|
||||
disabled?: boolean;
|
||||
dropdownScopeId?: string;
|
||||
dropdownId?: string;
|
||||
onChange: (params: { iconKey: string; Icon: IconComponent }) => void;
|
||||
selectedIconKey?: string;
|
||||
onClickOutside?: () => void;
|
||||
@ -80,7 +79,7 @@ const IconPickerIcon = ({
|
||||
|
||||
export const IconPicker = ({
|
||||
disabled,
|
||||
dropdownScopeId = 'icon-picker',
|
||||
dropdownId = 'icon-picker',
|
||||
onChange,
|
||||
selectedIconKey,
|
||||
onClickOutside,
|
||||
@ -95,7 +94,7 @@ export const IconPicker = ({
|
||||
setHotkeyScopeAndMemorizePreviousScope,
|
||||
} = usePreviousHotkeyScope();
|
||||
|
||||
const { closeDropdown } = useDropdown(dropdownScopeId);
|
||||
const { closeDropdown } = useDropdown(dropdownId);
|
||||
|
||||
const { getIcons, getIcon } = useIcons();
|
||||
const icons = getIcons();
|
||||
@ -126,9 +125,9 @@ export const IconPicker = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<DropdownScope dropdownScopeId={dropdownScopeId}>
|
||||
<div className={className}>
|
||||
<Dropdown
|
||||
dropdownId={dropdownId}
|
||||
dropdownHotkeyScope={{ scope: IconPickerHotkeyScope.IconPicker }}
|
||||
clickableComponent={
|
||||
<IconButton
|
||||
@ -191,6 +190,5 @@ export const IconPicker = ({
|
||||
onOpen={onOpen}
|
||||
/>
|
||||
</div>
|
||||
</DropdownScope>
|
||||
);
|
||||
};
|
||||
|
||||
@ -6,7 +6,6 @@ import { IconComponent } from '@/ui/display/icon/types/IconComponent';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
|
||||
import { SelectHotkeyScope } from '../types/SelectHotkeyScope';
|
||||
@ -98,10 +97,10 @@ export const Select = <Value extends string | number | null>({
|
||||
{selectControl}
|
||||
</div>
|
||||
) : (
|
||||
<DropdownScope dropdownScopeId={dropdownScopeId}>
|
||||
<div className={className}>
|
||||
{!!label && <StyledLabel>{label}</StyledLabel>}
|
||||
<Dropdown
|
||||
dropdownId="select"
|
||||
dropdownMenuWidth={176}
|
||||
dropdownPlacement="bottom-start"
|
||||
clickableComponent={selectControl}
|
||||
@ -123,6 +122,5 @@ export const Select = <Value extends string | number | null>({
|
||||
dropdownHotkeyScope={{ scope: SelectHotkeyScope.Select }}
|
||||
/>
|
||||
</div>
|
||||
</DropdownScope>
|
||||
);
|
||||
};
|
||||
|
||||
@ -9,7 +9,6 @@ import { CountryCallingCode } from 'libphonenumber-js';
|
||||
import { IconChevronDown, IconWorld } from '@/ui/display/icon';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
|
||||
import { CountryPickerHotkeyScope } from '../types/CountryPickerHotkeyScope';
|
||||
|
||||
@ -119,8 +118,8 @@ export const CountryPickerDropdownButton = ({
|
||||
}, [countries, value]);
|
||||
|
||||
return (
|
||||
<DropdownScope dropdownScopeId="country-picker">
|
||||
<Dropdown
|
||||
dropdownId="country-picker-dropdown-id"
|
||||
dropdownHotkeyScope={{ scope: CountryPickerHotkeyScope.CountryPicker }}
|
||||
clickableComponent={
|
||||
<StyledDropdownButtonContainer isUnfolded={isDropdownOpen}>
|
||||
@ -140,6 +139,5 @@ export const CountryPickerDropdownButton = ({
|
||||
dropdownPlacement="bottom-start"
|
||||
dropdownOffset={{ x: 0, y: 4 }}
|
||||
/>
|
||||
</DropdownScope>
|
||||
);
|
||||
};
|
||||
|
||||
@ -9,6 +9,7 @@ import {
|
||||
} from '@floating-ui/react';
|
||||
import { Key } from 'ts-key-enum';
|
||||
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { HotkeyEffect } from '@/ui/utilities/hotkey/components/HotkeyEffect';
|
||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||
@ -29,6 +30,7 @@ type DropdownProps = {
|
||||
scope: string;
|
||||
};
|
||||
dropdownHotkeyScope: HotkeyScope;
|
||||
dropdownId: string;
|
||||
dropdownPlacement?: Placement;
|
||||
dropdownMenuWidth?: number;
|
||||
dropdownOffset?: { x?: number; y?: number };
|
||||
@ -43,6 +45,7 @@ export const Dropdown = ({
|
||||
dropdownComponents,
|
||||
dropdownMenuWidth,
|
||||
hotkey,
|
||||
dropdownId,
|
||||
dropdownHotkeyScope,
|
||||
dropdownPlacement = 'bottom-end',
|
||||
dropdownOffset = { x: 0, y: 0 },
|
||||
@ -53,8 +56,7 @@ export const Dropdown = ({
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const { isDropdownOpen, toggleDropdown, closeDropdown, dropdownWidth } =
|
||||
useDropdown();
|
||||
|
||||
useDropdown(dropdownId);
|
||||
const offsetMiddlewares = [];
|
||||
|
||||
if (dropdownOffset.x) {
|
||||
@ -87,6 +89,7 @@ export const Dropdown = ({
|
||||
});
|
||||
|
||||
useInternalHotkeyScopeManagement({
|
||||
dropdownScopeId: `${dropdownId}-scope`,
|
||||
dropdownHotkeyScopeFromParent: dropdownHotkeyScope,
|
||||
});
|
||||
|
||||
@ -100,6 +103,7 @@ export const Dropdown = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<DropdownScope dropdownScopeId={`${dropdownId}-scope`}>
|
||||
<div ref={containerRef} className={className}>
|
||||
{clickableComponent && (
|
||||
<div
|
||||
@ -131,5 +135,6 @@ export const Dropdown = ({
|
||||
onDropdownOpen={onOpen}
|
||||
/>
|
||||
</div>
|
||||
</DropdownScope>
|
||||
);
|
||||
};
|
||||
|
||||
@ -12,7 +12,6 @@ import { MenuItemSelectAvatar } from '@/ui/navigation/menu-item/components/MenuI
|
||||
import { Avatar } from '@/users/components/Avatar';
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
|
||||
import { DropdownScope } from '../../scopes/DropdownScope';
|
||||
import { Dropdown } from '../Dropdown';
|
||||
import { DropdownMenuHeader } from '../DropdownMenuHeader';
|
||||
import { DropdownMenuInput } from '../DropdownMenuInput';
|
||||
@ -25,18 +24,12 @@ const meta: Meta<typeof Dropdown> = {
|
||||
title: 'UI/Layout/Dropdown/Dropdown',
|
||||
component: Dropdown,
|
||||
|
||||
decorators: [
|
||||
ComponentDecorator,
|
||||
(Story) => (
|
||||
<DropdownScope dropdownScopeId="testDropdownMenu">
|
||||
<Story />
|
||||
</DropdownScope>
|
||||
),
|
||||
],
|
||||
decorators: [ComponentDecorator, (Story) => <Story />],
|
||||
args: {
|
||||
clickableComponent: <Button title="Open Dropdown" />,
|
||||
dropdownHotkeyScope: { scope: 'testDropdownMenu' },
|
||||
dropdownOffset: { x: 0, y: 8 },
|
||||
dropdownId: 'test-dropdown-id',
|
||||
},
|
||||
argTypes: {
|
||||
clickableComponent: { control: false },
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
import { DropdownScopeInternalContext } from '@/ui/layout/dropdown/scopes/scope-internal-context/DropdownScopeInternalContext';
|
||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||
import { useScopedState } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useScopedState';
|
||||
|
||||
type UseDropdownScopedStatesProps = {
|
||||
dropdownScopeId?: string;
|
||||
};
|
||||
|
||||
export const useDropdownScopedStates = ({
|
||||
dropdownScopeId,
|
||||
}: UseDropdownScopedStatesProps) => {
|
||||
const scopeId = useAvailableScopeIdOrThrow(
|
||||
DropdownScopeInternalContext,
|
||||
dropdownScopeId,
|
||||
);
|
||||
|
||||
const {
|
||||
getScopedState,
|
||||
getScopedFamilyState,
|
||||
getScopedSnapshotValue,
|
||||
getScopedFamilySnapshotValue,
|
||||
} = useScopedState(scopeId);
|
||||
|
||||
return {
|
||||
scopeId,
|
||||
injectStateWithDropdownScopeId: getScopedState,
|
||||
injectFamilyStateWithDropdownScopeId: getScopedFamilyState,
|
||||
injectSnapshotValueWithDropdownScopeId: getScopedSnapshotValue,
|
||||
injectFamilySnapshotValueWithDropdownScopeId: getScopedFamilySnapshotValue,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,26 @@
|
||||
import { DropdownScopeInternalContext } from '@/ui/layout/dropdown/scopes/scope-internal-context/DropdownScopeInternalContext';
|
||||
import { dropdownHotkeyStateScopeMap } from '@/ui/layout/dropdown/states/dropdownHotkeyStateScopeMap';
|
||||
import { dropdownWidthStateScopeMap } from '@/ui/layout/dropdown/states/dropdownWidthStateScopeMap';
|
||||
import { isDropdownOpenStateScopeMap } from '@/ui/layout/dropdown/states/isDropdownOpenStateScopeMap';
|
||||
import { useAvailableScopeIdOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useAvailableScopeId';
|
||||
import { getState } from '@/ui/utilities/recoil-scope/utils/getState';
|
||||
|
||||
type UseDropdownStatesProps = {
|
||||
dropdownScopeId?: string;
|
||||
};
|
||||
|
||||
export const useDropdownStates = ({
|
||||
dropdownScopeId,
|
||||
}: UseDropdownStatesProps) => {
|
||||
const scopeId = useAvailableScopeIdOrThrow(
|
||||
DropdownScopeInternalContext,
|
||||
dropdownScopeId,
|
||||
);
|
||||
|
||||
return {
|
||||
scopeId,
|
||||
dropdownHotkeyScopeState: getState(dropdownHotkeyStateScopeMap, scopeId),
|
||||
dropdownWidthState: getState(dropdownWidthStateScopeMap, scopeId),
|
||||
isDropdownOpenState: getState(isDropdownOpenStateScopeMap, scopeId),
|
||||
};
|
||||
};
|
||||
@ -1,36 +1,29 @@
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { useDropdownScopedStates } from '@/ui/layout/dropdown/hooks/internal/useDropdownScopedStates';
|
||||
import { getDropdownScopeInjectors } from '@/ui/layout/dropdown/utils/internal/getDropdownScopeInjectors';
|
||||
import { useDropdownStates } from '@/ui/layout/dropdown/hooks/internal/useDropdownStates';
|
||||
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||
|
||||
export const useDropdown = (dropdownId?: string) => {
|
||||
const { injectStateWithDropdownScopeId, scopeId } = useDropdownScopedStates({
|
||||
dropdownScopeId: dropdownId,
|
||||
});
|
||||
|
||||
const {
|
||||
dropdownHotkeyScopeScopeInjector,
|
||||
dropdownWidthScopeInjector,
|
||||
isDropdownOpenScopeInjector,
|
||||
} = getDropdownScopeInjectors();
|
||||
scopeId,
|
||||
dropdownHotkeyScopeState,
|
||||
dropdownWidthState,
|
||||
isDropdownOpenState,
|
||||
} = useDropdownStates({
|
||||
dropdownScopeId: `${dropdownId}-scope`,
|
||||
});
|
||||
|
||||
const {
|
||||
setHotkeyScopeAndMemorizePreviousScope,
|
||||
goBackToPreviousHotkeyScope,
|
||||
} = usePreviousHotkeyScope();
|
||||
|
||||
const [dropdownHotkeyScope, setDropdownHotkeyScope] = useRecoilState(
|
||||
injectStateWithDropdownScopeId(dropdownHotkeyScopeScopeInjector),
|
||||
);
|
||||
const [dropdownHotkeyScope] = useRecoilState(dropdownHotkeyScopeState);
|
||||
|
||||
const [dropdownWidth, setDropdownWidth] = useRecoilState(
|
||||
injectStateWithDropdownScopeId(dropdownWidthScopeInjector),
|
||||
);
|
||||
const [dropdownWidth, setDropdownWidth] = useRecoilState(dropdownWidthState);
|
||||
|
||||
const [isDropdownOpen, setIsDropdownOpen] = useRecoilState(
|
||||
injectStateWithDropdownScopeId(isDropdownOpenScopeInjector),
|
||||
);
|
||||
const [isDropdownOpen, setIsDropdownOpen] =
|
||||
useRecoilState(isDropdownOpenState);
|
||||
|
||||
const closeDropdown = () => {
|
||||
goBackToPreviousHotkeyScope();
|
||||
@ -61,8 +54,6 @@ export const useDropdown = (dropdownId?: string) => {
|
||||
closeDropdown,
|
||||
toggleDropdown,
|
||||
openDropdown,
|
||||
dropdownHotkeyScope,
|
||||
setDropdownHotkeyScope,
|
||||
dropdownWidth,
|
||||
setDropdownWidth,
|
||||
};
|
||||
|
||||
@ -1,16 +1,22 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { useDropdownStates } from '@/ui/layout/dropdown/hooks/internal/useDropdownStates';
|
||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
|
||||
import { useDropdown } from './useDropdown';
|
||||
|
||||
export const useInternalHotkeyScopeManagement = ({
|
||||
dropdownScopeId,
|
||||
dropdownHotkeyScopeFromParent,
|
||||
}: {
|
||||
dropdownScopeId: string;
|
||||
dropdownHotkeyScopeFromParent?: HotkeyScope;
|
||||
}) => {
|
||||
const { dropdownHotkeyScope, setDropdownHotkeyScope } = useDropdown();
|
||||
const { dropdownHotkeyScopeState } = useDropdownStates({ dropdownScopeId });
|
||||
|
||||
const [dropdownHotkeyScope, setDropdownHotkeyScope] = useRecoilState(
|
||||
dropdownHotkeyScopeState,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isDeeplyEqual(dropdownHotkeyScopeFromParent, dropdownHotkeyScope)) {
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||
|
||||
export const dropdownHotkeyScopeScopedState = createStateScopeMap<
|
||||
export const dropdownHotkeyStateScopeMap = createStateScopeMap<
|
||||
HotkeyScope | null | undefined
|
||||
>({
|
||||
key: 'dropdownHotkeyScopeScopedState',
|
||||
key: 'dropdownHotkeyStateScopeMap',
|
||||
defaultValue: null,
|
||||
});
|
||||
@ -1,8 +0,0 @@
|
||||
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||
|
||||
export const dropdownWidthScopedState = createStateScopeMap<number | undefined>(
|
||||
{
|
||||
key: 'dropdownWidthScopedState',
|
||||
defaultValue: 160,
|
||||
},
|
||||
);
|
||||
@ -0,0 +1,8 @@
|
||||
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||
|
||||
export const dropdownWidthStateScopeMap = createStateScopeMap<
|
||||
number | undefined
|
||||
>({
|
||||
key: 'dropdownWidthStateScopeMap',
|
||||
defaultValue: 160,
|
||||
});
|
||||
@ -1,6 +1,6 @@
|
||||
import { createStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createStateScopeMap';
|
||||
|
||||
export const isDropdownOpenScopedState = createStateScopeMap<boolean>({
|
||||
key: 'isDropdownOpenScopedState',
|
||||
export const isDropdownOpenStateScopeMap = createStateScopeMap<boolean>({
|
||||
key: 'isDropdownOpenStateScopeMap',
|
||||
defaultValue: false,
|
||||
});
|
||||
@ -1,22 +0,0 @@
|
||||
import { dropdownHotkeyScopeScopedState } from '@/ui/layout/dropdown/states/dropdownHotkeyScopeScopedState';
|
||||
import { dropdownWidthScopedState } from '@/ui/layout/dropdown/states/dropdownWidthScopedState';
|
||||
import { isDropdownOpenScopedState } from '@/ui/layout/dropdown/states/isDropdownOpenScopedState';
|
||||
import { getScopeInjector } from '@/ui/utilities/recoil-scope/utils/getScopeInjector';
|
||||
|
||||
export const getDropdownScopeInjectors = () => {
|
||||
const dropdownHotkeyScopeScopeInjector = getScopeInjector(
|
||||
dropdownHotkeyScopeScopedState,
|
||||
);
|
||||
|
||||
const dropdownWidthScopeInjector = getScopeInjector(dropdownWidthScopedState);
|
||||
|
||||
const isDropdownOpenScopeInjector = getScopeInjector(
|
||||
isDropdownOpenScopedState,
|
||||
);
|
||||
|
||||
return {
|
||||
dropdownHotkeyScopeScopeInjector,
|
||||
dropdownWidthScopeInjector,
|
||||
isDropdownOpenScopeInjector,
|
||||
};
|
||||
};
|
||||
@ -12,7 +12,6 @@ import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
|
||||
import { Dropdown } from '../../dropdown/components/Dropdown';
|
||||
import { DropdownMenu } from '../../dropdown/components/DropdownMenu';
|
||||
import { DropdownScope } from '../../dropdown/scopes/DropdownScope';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
z-index: 1;
|
||||
@ -33,8 +32,8 @@ export const ShowPageAddButton = ({
|
||||
|
||||
return (
|
||||
<StyledContainer>
|
||||
<DropdownScope dropdownScopeId="add-show-page">
|
||||
<Dropdown
|
||||
dropdownId="show-page-add-button-dropdown-id"
|
||||
clickableComponent={
|
||||
<IconButton
|
||||
Icon={IconPlus}
|
||||
@ -67,7 +66,6 @@ export const ShowPageAddButton = ({
|
||||
scope: PageHotkeyScope.ShowPage,
|
||||
}}
|
||||
/>
|
||||
</DropdownScope>
|
||||
</StyledContainer>
|
||||
);
|
||||
};
|
||||
|
||||
@ -13,7 +13,6 @@ import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMe
|
||||
|
||||
import { Dropdown } from '../../dropdown/components/Dropdown';
|
||||
import { DropdownMenu } from '../../dropdown/components/DropdownMenu';
|
||||
import { DropdownScope } from '../../dropdown/scopes/DropdownScope';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
z-index: 1;
|
||||
@ -42,8 +41,8 @@ export const ShowPageMoreButton = ({
|
||||
|
||||
return (
|
||||
<StyledContainer>
|
||||
<DropdownScope dropdownScopeId="more-show-page">
|
||||
<Dropdown
|
||||
dropdownId="more-show-page"
|
||||
clickableComponent={
|
||||
<IconButton
|
||||
Icon={IconDotsVertical}
|
||||
@ -70,7 +69,6 @@ export const ShowPageMoreButton = ({
|
||||
scope: PageHotkeyScope.ShowPage,
|
||||
}}
|
||||
/>
|
||||
</DropdownScope>
|
||||
</StyledContainer>
|
||||
);
|
||||
};
|
||||
|
||||
@ -68,6 +68,7 @@ export const EditableFilterDropdownButton = ({
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
dropdownId={viewFilter.fieldMetadataId}
|
||||
clickableComponent={
|
||||
<EditableFilterChip viewFilter={viewFilter} onRemove={handleRemove} />
|
||||
}
|
||||
|
||||
@ -7,7 +7,6 @@ import { Button } from '@/ui/input/button/components/Button';
|
||||
import { ButtonGroup } from '@/ui/input/button/components/ButtonGroup';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||
import { UpdateViewDropdownId } from '@/views/constants/UpdateViewDropdownId';
|
||||
@ -58,8 +57,8 @@ export const UpdateViewButtonGroup = ({
|
||||
<StyledContainer>
|
||||
<ButtonGroup size="small" accent="blue">
|
||||
<Button title="Update view" onClick={handleViewSubmit} />
|
||||
<DropdownScope dropdownScopeId={UpdateViewDropdownId}>
|
||||
<Dropdown
|
||||
dropdownId={UpdateViewDropdownId}
|
||||
dropdownHotkeyScope={hotkeyScope}
|
||||
clickableComponent={
|
||||
<Button size="small" accent="blue" Icon={IconChevronDown} />
|
||||
@ -76,7 +75,6 @@ export const UpdateViewButtonGroup = ({
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</DropdownScope>
|
||||
</ButtonGroup>
|
||||
</StyledContainer>
|
||||
);
|
||||
|
||||
@ -5,7 +5,6 @@ import { useRecoilValue } from 'recoil';
|
||||
import { AddObjectFilterFromDetailsButton } from '@/object-record/object-filter-dropdown/components/AddObjectFilterFromDetailsButton';
|
||||
import { ObjectFilterDropdownScope } from '@/object-record/object-filter-dropdown/scopes/ObjectFilterDropdownScope';
|
||||
import { FiltersHotkeyScope } from '@/object-record/object-filter-dropdown/types/FiltersHotkeyScope';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { EditableFilterDropdownButton } from '@/views/components/EditableFilterDropdownButton';
|
||||
import { EditableSortChip } from '@/views/components/EditableSortChip';
|
||||
import { ViewBarFilterEffect } from '@/views/components/ViewBarFilterEffect';
|
||||
@ -146,7 +145,6 @@ export const ViewBarDetails = ({
|
||||
<ObjectFilterDropdownScope
|
||||
filterScopeId={viewFilter.fieldMetadataId}
|
||||
>
|
||||
<DropdownScope dropdownScopeId={viewFilter.fieldMetadataId}>
|
||||
<ViewBarFilterEffect
|
||||
filterDropdownId={viewFilter.fieldMetadataId}
|
||||
onFilterSelect={upsertViewFilter}
|
||||
@ -158,7 +156,6 @@ export const ViewBarDetails = ({
|
||||
}}
|
||||
viewFilterDropdownId={viewFilter.fieldMetadataId}
|
||||
/>
|
||||
</DropdownScope>
|
||||
</ObjectFilterDropdownScope>
|
||||
);
|
||||
})}
|
||||
|
||||
@ -15,7 +15,6 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
|
||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||
import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
import { MOBILE_VIEWPORT } from '@/ui/theme/constants/theme';
|
||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||
@ -130,8 +129,8 @@ export const ViewsDropdownButton = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<DropdownScope dropdownScopeId={ViewsDropdownId}>
|
||||
<Dropdown
|
||||
dropdownId={ViewsDropdownId}
|
||||
dropdownHotkeyScope={hotkeyScope}
|
||||
clickableComponent={
|
||||
<StyledDropdownButtonContainer isUnfolded={isViewsDropdownOpen}>
|
||||
@ -180,6 +179,5 @@ export const ViewsDropdownButton = ({
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</DropdownScope>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user