feat: add DropdownMenuInput and use as view name input in board (#1680)

Closes #1510
This commit is contained in:
Thaïs
2023-09-20 21:53:35 +02:00
committed by GitHub
parent 78b666f457
commit 772d54d29f
16 changed files with 284 additions and 249 deletions

View File

@ -3,7 +3,7 @@ import { useRecoilState } from 'recoil';
import { currentPipelineState } from '@/pipeline/states/currentPipelineState';
import { DropdownMenuHeader } from '@/ui/dropdown/components/DropdownMenuHeader';
import { DropdownMenuInput } from '@/ui/dropdown/components/DropdownMenuInput';
import { DropdownMenuSearchInput } from '@/ui/dropdown/components/DropdownMenuSearchInput';
import { StyledDropdownMenu } from '@/ui/dropdown/components/StyledDropdownMenu';
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
import { StyledDropdownMenuSeparator } from '@/ui/dropdown/components/StyledDropdownMenuSeparator';
@ -106,7 +106,7 @@ export const CompanyProgressPicker = ({
{selectedPipelineStage?.name}
</DropdownMenuHeader>
<StyledDropdownMenuSeparator />
<DropdownMenuInput
<DropdownMenuSearchInput
value={searchFilter}
onChange={handleSearchFilterChange}
autoFocus

View File

@ -13,7 +13,7 @@ import debounce from 'lodash.debounce';
import { ReadonlyDeep } from 'type-fest';
import type { SelectOption } from '@/spreadsheet-import/types';
import { DropdownMenuInput } from '@/ui/dropdown/components/DropdownMenuInput';
import { DropdownMenuSearchInput } from '@/ui/dropdown/components/DropdownMenuSearchInput';
import { StyledDropdownMenu } from '@/ui/dropdown/components/StyledDropdownMenu';
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
import { StyledDropdownMenuSeparator } from '@/ui/dropdown/components/StyledDropdownMenuSeparator';
@ -120,7 +120,7 @@ export const MatchColumnSelect = ({
ref={dropdownContainerRef}
width={refs.domReference.current?.clientWidth}
>
<DropdownMenuInput
<DropdownMenuSearchInput
value={searchFilter}
onChange={handleFilterChange}
autoFocus

View File

@ -1,4 +1,7 @@
import { useResetRecoilState } from 'recoil';
import { DropdownButton } from '@/ui/dropdown/components/DropdownButton';
import { viewEditModeState } from '@/ui/view-bar/states/viewEditModeState';
import { BoardOptionsDropdownKey } from '../types/BoardOptionsDropdownKey';
@ -17,6 +20,8 @@ export const BoardOptionsDropdown = ({
customHotkeyScope,
onStageAdd,
}: BoardOptionsDropdownProps) => {
const resetViewEditMode = useResetRecoilState(viewEditModeState);
return (
<DropdownButton
buttonComponents={<BoardOptionsDropdownButton />}
@ -28,6 +33,7 @@ export const BoardOptionsDropdown = ({
}
dropdownHotkeyScope={customHotkeyScope}
dropdownId={BoardOptionsDropdownKey}
onClickOutside={resetViewEditMode}
/>
);
};

View File

@ -1,13 +1,18 @@
import { useContext, useRef, useState } from 'react';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useRecoilCallback, useRecoilState, useRecoilValue } from 'recoil';
import {
useRecoilCallback,
useRecoilState,
useRecoilValue,
useResetRecoilState,
} from 'recoil';
import { Key } from 'ts-key-enum';
import { v4 } from 'uuid';
import { BoardContext } from '@/companies/states/contexts/BoardContext';
import { DropdownMenuHeader } from '@/ui/dropdown/components/DropdownMenuHeader';
import { DropdownMenuInput } from '@/ui/dropdown/components/DropdownMenuInput';
import { DropdownMenuInputContainer } from '@/ui/dropdown/components/DropdownMenuInputContainer';
import { DropdownMenuSearchInput } from '@/ui/dropdown/components/DropdownMenuSearchInput';
import { StyledDropdownMenu } from '@/ui/dropdown/components/StyledDropdownMenu';
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
import { StyledDropdownMenuSeparator } from '@/ui/dropdown/components/StyledDropdownMenuSeparator';
@ -16,7 +21,6 @@ import {
IconChevronLeft,
IconLayoutKanban,
IconPlus,
IconSettings,
IconTag,
} from '@/ui/icon';
import { MenuItem } from '@/ui/menu-item/components/MenuItem';
@ -28,6 +32,7 @@ import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoi
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
import { ViewFieldsVisibilityDropdownSection } from '@/ui/view-bar/components/ViewFieldsVisibilityDropdownSection';
import { useUpsertView } from '@/ui/view-bar/hooks/useUpsertView';
import { currentViewScopedSelector } from '@/ui/view-bar/states/selectors/currentViewScopedSelector';
import { viewsByIdScopedSelector } from '@/ui/view-bar/states/selectors/viewsByIdScopedSelector';
import { viewEditModeState } from '@/ui/view-bar/states/viewEditModeState';
@ -45,10 +50,6 @@ export type BoardOptionsDropdownContentProps = {
onStageAdd?: (boardColumn: BoardColumnDefinition) => void;
};
const StyledIconSettings = styled(IconSettings)`
margin-right: ${({ theme }) => theme.spacing(1)};
`;
type BoardOptionsMenu = 'fields' | 'stage-creation' | 'stages';
type ColumnForCreate = {
@ -62,10 +63,7 @@ export const BoardOptionsDropdownContent = ({
customHotkeyScope,
onStageAdd,
}: BoardOptionsDropdownContentProps) => {
const theme = useTheme();
const BoardRecoilScopeContext =
useContext(BoardContext).BoardRecoilScopeContext;
const { BoardRecoilScopeContext } = useContext(BoardContext);
const boardRecoilScopeId = useRecoilScopeId(BoardRecoilScopeContext);
@ -93,7 +91,12 @@ export const BoardOptionsDropdownContent = ({
viewsByIdScopedSelector,
BoardRecoilScopeContext, // TODO: replace with ViewBarRecoilScopeContext
);
const currentView = useRecoilScopedValue(
currentViewScopedSelector,
BoardRecoilScopeContext,
);
const viewEditMode = useRecoilValue(viewEditModeState);
const resetViewEditMode = useResetRecoilState(viewEditModeState);
const handleStageSubmit = () => {
if (currentMenu !== 'stage-creation' || !stageInputRef?.current?.value)
@ -148,6 +151,7 @@ export const BoardOptionsDropdownContent = ({
useScopedHotkeys(
Key.Escape,
() => {
resetViewEditMode();
closeDropdownButton();
},
customHotkeyScope.scope,
@ -158,6 +162,7 @@ export const BoardOptionsDropdownContent = ({
() => {
handleStageSubmit();
handleViewNameSubmit();
resetViewEditMode();
closeDropdownButton();
},
customHotkeyScope.scope,
@ -167,25 +172,24 @@ export const BoardOptionsDropdownContent = ({
<StyledDropdownMenu>
{!currentMenu && (
<>
{!!viewEditMode.mode ? (
<DropdownMenuInputContainer>
<DropdownMenuInput
ref={viewEditInputRef}
autoFocus
autoFocus={
viewEditMode.mode === 'create' || !!viewEditMode.viewId
}
placeholder={
viewEditMode.mode === 'create' ? 'New view' : 'View name'
}
defaultValue={
viewEditMode.viewId
viewEditMode.mode === 'create'
? ''
: viewEditMode.viewId
? viewsById[viewEditMode.viewId]?.name
: undefined
: currentView?.name
}
/>
) : (
<DropdownMenuHeader>
<StyledIconSettings size={theme.icon.size.md} />
Settings
</DropdownMenuHeader>
)}
</DropdownMenuInputContainer>
<StyledDropdownMenuSeparator />
<StyledDropdownMenuItemsContainer>
<MenuItemNavigate
@ -217,7 +221,7 @@ export const BoardOptionsDropdownContent = ({
</>
)}
{currentMenu === 'stage-creation' && (
<DropdownMenuInput
<DropdownMenuSearchInput
autoFocus
placeholder="New stage"
ref={stageInputRef}

View File

@ -0,0 +1,57 @@
import type { Meta, StoryObj } from '@storybook/react';
import { userEvent, within } from '@storybook/testing-library';
import { BoardContext } from '@/companies/states/contexts/BoardContext';
import { CompanyBoardRecoilScopeContext } from '@/companies/states/recoil-scope-contexts/CompanyBoardRecoilScopeContext';
import { DropdownRecoilScopeContext } from '@/ui/dropdown/states/recoil-scope-contexts/DropdownRecoilScopeContext';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { ViewBarContext } from '@/ui/view-bar/contexts/ViewBarContext';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { ComponentWithRecoilScopeDecorator } from '~/testing/decorators/ComponentWithRecoilScopeDecorator';
import { BoardOptionsDropdown } from '../BoardOptionsDropdown';
const meta: Meta<typeof BoardOptionsDropdown> = {
title: 'UI/Board/Options/BoardOptionsDropdown',
component: BoardOptionsDropdown,
decorators: [
(Story, { parameters }) => (
<BoardContext.Provider
value={{
BoardRecoilScopeContext: parameters.customRecoilScopeContext,
}}
>
<ViewBarContext.Provider
value={{
ViewBarRecoilScopeContext: parameters.customRecoilScopeContext,
}}
>
<RecoilScope CustomRecoilScopeContext={DropdownRecoilScopeContext}>
<Story />
</RecoilScope>
</ViewBarContext.Provider>
</BoardContext.Provider>
),
ComponentWithRecoilScopeDecorator,
ComponentDecorator,
],
parameters: {
customRecoilScopeContext: CompanyBoardRecoilScopeContext,
},
args: {
customHotkeyScope: { scope: 'scope' },
},
};
export default meta;
type Story = StoryObj<typeof BoardOptionsDropdown>;
export const Default: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const dropdownButton = canvas.getByText('Options');
await userEvent.click(dropdownButton);
},
};

View File

@ -1,43 +1,23 @@
import { forwardRef, InputHTMLAttributes } from 'react';
import styled from '@emotion/styled';
import { rgba } from '@/ui/theme/constants/colors';
import { textInputStyle } from '@/ui/theme/constants/effects';
const StyledDropdownMenuInputContainer = styled.div`
--vertical-padding: ${({ theme }) => theme.spacing(1)};
align-items: center;
display: flex;
flex-direction: row;
height: calc(36px - 2 * var(--vertical-padding));
padding: var(--vertical-padding) 0;
width: 100%;
`;
const StyledInput = styled.input`
const StyledViewNameInput = styled.input`
${textInputStyle}
font-size: ${({ theme }) => theme.font.size.sm};
border: 1px solid ${({ theme }) => theme.border.color.medium};
border-radius: ${({ theme }) => theme.border.radius.sm};
box-sizing: border-box;
font-weight: ${({ theme }) => theme.font.weight.medium};
height: 32px;
position: relative;
width: 100%;
&[type='number']::-webkit-outer-spin-button,
&[type='number']::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
&[type='number'] {
-moz-appearance: textfield;
&:focus {
border-color: ${({ theme }) => theme.color.blue};
box-shadow: 0px 0px 0px 3px ${({ theme }) => rgba(theme.color.blue, 0.1)};
}
`;
export const DropdownMenuInput = forwardRef<
HTMLInputElement,
InputHTMLAttributes<HTMLInputElement>
>((props, ref) => (
<StyledDropdownMenuInputContainer>
<StyledInput autoComplete="off" placeholder="Search" {...props} ref={ref} />
</StyledDropdownMenuInputContainer>
));
export { StyledViewNameInput as DropdownMenuInput };

View File

@ -0,0 +1,9 @@
import styled from '@emotion/styled';
const StyledInputContainer = styled.div`
box-sizing: border-box;
padding: ${({ theme }) => theme.spacing(1)};
width: 100%;
`;
export { StyledInputContainer as DropdownMenuInputContainer };

View File

@ -0,0 +1,43 @@
import { forwardRef, InputHTMLAttributes } from 'react';
import styled from '@emotion/styled';
import { textInputStyle } from '@/ui/theme/constants/effects';
const StyledDropdownMenuSearchInputContainer = styled.div`
--vertical-padding: ${({ theme }) => theme.spacing(1)};
align-items: center;
display: flex;
flex-direction: row;
height: calc(36px - 2 * var(--vertical-padding));
padding: var(--vertical-padding) 0;
width: 100%;
`;
const StyledInput = styled.input`
${textInputStyle}
font-size: ${({ theme }) => theme.font.size.sm};
width: 100%;
&[type='number']::-webkit-outer-spin-button,
&[type='number']::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
&[type='number'] {
-moz-appearance: textfield;
}
`;
export const DropdownMenuSearchInput = forwardRef<
HTMLInputElement,
InputHTMLAttributes<HTMLInputElement>
>((props, ref) => (
<StyledDropdownMenuSearchInputContainer>
<StyledInput autoComplete="off" placeholder="Search" {...props} ref={ref} />
</StyledDropdownMenuSearchInputContainer>
));

View File

@ -1,8 +1,7 @@
import { useState } from 'react';
import styled from '@emotion/styled';
import type { Meta, StoryObj } from '@storybook/react';
import type { Decorator, Meta, StoryObj } from '@storybook/react';
import { IconPlus, IconUser } from '@/ui/icon';
import { DropdownMenuSkeletonItem } from '@/ui/input/relation-picker/components/skeletons/DropdownMenuSkeletonItem';
import { MenuItem } from '@/ui/menu-item/components/MenuItem';
import { MenuItemMultiSelectAvatar } from '@/ui/menu-item/components/MenuItemMultiSelectAvatar';
@ -12,6 +11,8 @@ import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { DropdownMenuHeader } from '../DropdownMenuHeader';
import { DropdownMenuInput } from '../DropdownMenuInput';
import { DropdownMenuInputContainer } from '../DropdownMenuInputContainer';
import { DropdownMenuSearchInput } from '../DropdownMenuSearchInput';
import { StyledDropdownMenu } from '../StyledDropdownMenu';
import { StyledDropdownMenuItemsContainer } from '../StyledDropdownMenuItemsContainer';
import { StyledDropdownMenuSeparator } from '../StyledDropdownMenuSeparator';
@ -23,7 +24,9 @@ const meta: Meta<typeof StyledDropdownMenu> = {
decorators: [ComponentDecorator],
argTypes: {
as: { table: { disable: true } },
children: { control: false },
theme: { table: { disable: true } },
width: { type: 'number', defaultValue: undefined },
},
};
@ -122,21 +125,22 @@ const FakeSelectableMenuItemList = ({ hasAvatar }: { hasAvatar?: boolean }) => {
};
const FakeCheckableMenuItemList = ({ hasAvatar }: { hasAvatar?: boolean }) => {
const [selectedItems, setSelectedItems] = useState<string[]>([]);
const [selectedItemsById, setSelectedItemsById] = useState<
Record<string, boolean>
>({});
return (
<>
{mockSelectArray.map((item) => (
<MenuItemMultiSelectAvatar
key={item.id}
selected={selectedItems.includes(item.id)}
onSelectChange={(checked) => {
if (checked) {
setSelectedItems([...selectedItems, item.id]);
} else {
setSelectedItems(selectedItems.filter((id) => id !== item.id));
}
}}
selected={selectedItemsById[item.id]}
onSelectChange={(checked) =>
setSelectedItemsById((previous) => ({
...previous,
[item.id]: checked,
}))
}
avatar={
hasAvatar ? (
<Avatar
@ -154,165 +158,96 @@ const FakeCheckableMenuItemList = ({ hasAvatar }: { hasAvatar?: boolean }) => {
);
};
const WithContentBelowDecorator: Decorator = (Story) => (
<StyledFakeBelowContainer>
<FakeContentBelow />
<StyledMenuAbsolutePositionWrapper>
<Story />
</StyledMenuAbsolutePositionWrapper>
</StyledFakeBelowContainer>
);
export const Empty: Story = {
render: (args) => (
<StyledDropdownMenu {...args}>
<StyledFakeMenuContent />
</StyledDropdownMenu>
),
};
export const WithContentBelow: Story = {
...Empty,
decorators: [
(Story) => (
<StyledFakeBelowContainer>
<FakeContentBelow />
<StyledMenuAbsolutePositionWrapper>
<Story />
</StyledMenuAbsolutePositionWrapper>
</StyledFakeBelowContainer>
),
],
};
export const SimpleMenuItem: Story = {
...WithContentBelow,
render: (args) => (
<StyledDropdownMenu {...args}>
<StyledDropdownMenuItemsContainer hasMaxHeight>
{mockSelectArray.map(({ name }) => (
<MenuItem text={name} />
))}
</StyledDropdownMenuItemsContainer>
</StyledDropdownMenu>
),
args: { children: <StyledFakeMenuContent /> },
};
export const WithHeaders: Story = {
...WithContentBelow,
render: (args) => (
<StyledDropdownMenu {...args}>
<DropdownMenuHeader>Header</DropdownMenuHeader>
<StyledDropdownMenuSeparator />
<StyledDropdownMenuSubheader>Subheader 1</StyledDropdownMenuSubheader>
<StyledDropdownMenuItemsContainer>
{mockSelectArray.slice(0, 3).map(({ name }) => (
<MenuItem text={name} />
))}
</StyledDropdownMenuItemsContainer>
<StyledDropdownMenuSeparator />
<StyledDropdownMenuSubheader>Subheader 2</StyledDropdownMenuSubheader>
<StyledDropdownMenuItemsContainer>
{mockSelectArray.slice(3).map(({ name }) => (
<MenuItem text={name} />
))}
</StyledDropdownMenuItemsContainer>
</StyledDropdownMenu>
),
};
export const WithIcons: Story = {
...WithContentBelow,
render: (args) => (
<StyledDropdownMenu {...args}>
<StyledDropdownMenuItemsContainer hasMaxHeight>
{mockSelectArray.map(({ name }) => (
<MenuItem text={name} LeftIcon={IconUser} />
))}
</StyledDropdownMenuItemsContainer>
</StyledDropdownMenu>
),
};
export const WithActions: Story = {
...WithContentBelow,
render: (args) => (
<StyledDropdownMenu {...args}>
<StyledDropdownMenuItemsContainer hasMaxHeight>
{mockSelectArray.map(({ name }, index) => (
<MenuItem
className={index === 0 ? 'hover' : undefined}
iconButtons={[{ Icon: IconUser }, { Icon: IconPlus }]}
text={name}
/>
))}
</StyledDropdownMenuItemsContainer>
</StyledDropdownMenu>
),
parameters: {
pseudo: { hover: ['.hover'] },
decorators: [WithContentBelowDecorator],
args: {
children: (
<>
<DropdownMenuHeader>Header</DropdownMenuHeader>
<StyledDropdownMenuSeparator />
<StyledDropdownMenuSubheader>Subheader 1</StyledDropdownMenuSubheader>
<StyledDropdownMenuItemsContainer>
{mockSelectArray.slice(0, 3).map(({ name }) => (
<MenuItem text={name} />
))}
</StyledDropdownMenuItemsContainer>
<StyledDropdownMenuSeparator />
<StyledDropdownMenuSubheader>Subheader 2</StyledDropdownMenuSubheader>
<StyledDropdownMenuItemsContainer>
{mockSelectArray.slice(3).map(({ name }) => (
<MenuItem text={name} />
))}
</StyledDropdownMenuItemsContainer>
</>
),
},
};
export const LoadingMenu: Story = {
...WithContentBelow,
render: () => (
<StyledDropdownMenu>
<DropdownMenuInput value={'query'} autoFocus />
<StyledDropdownMenuSeparator />
<StyledDropdownMenuItemsContainer hasMaxHeight>
<DropdownMenuSkeletonItem />
</StyledDropdownMenuItemsContainer>
</StyledDropdownMenu>
),
export const SearchWithLoadingMenu: Story = {
decorators: [WithContentBelowDecorator],
args: {
children: (
<>
<DropdownMenuSearchInput value="query" autoFocus />
<StyledDropdownMenuSeparator />
<StyledDropdownMenuItemsContainer hasMaxHeight>
<DropdownMenuSkeletonItem />
</StyledDropdownMenuItemsContainer>
</>
),
},
};
export const Search: Story = {
...WithContentBelow,
render: (args) => (
<StyledDropdownMenu {...args}>
<DropdownMenuInput />
<StyledDropdownMenuSeparator />
<StyledDropdownMenuItemsContainer hasMaxHeight>
{mockSelectArray.map(({ name }) => (
<MenuItem text={name} />
))}
</StyledDropdownMenuItemsContainer>
</StyledDropdownMenu>
),
};
export const SelectableMenuItem: Story = {
...WithContentBelow,
render: (args) => (
<StyledDropdownMenu {...args}>
<StyledDropdownMenuItemsContainer hasMaxHeight>
<FakeSelectableMenuItemList />
</StyledDropdownMenuItemsContainer>
</StyledDropdownMenu>
),
export const WithInput: Story = {
decorators: [WithContentBelowDecorator],
args: {
children: (
<>
<DropdownMenuInputContainer>
<DropdownMenuInput defaultValue="Lorem ipsum" autoFocus />
</DropdownMenuInputContainer>
<StyledDropdownMenuSeparator />
<StyledDropdownMenuItemsContainer hasMaxHeight>
{mockSelectArray.map(({ name }) => (
<MenuItem text={name} />
))}
</StyledDropdownMenuItemsContainer>
</>
),
},
};
export const SelectableMenuItemWithAvatar: Story = {
...WithContentBelow,
render: (args) => (
<StyledDropdownMenu {...args}>
decorators: [WithContentBelowDecorator],
args: {
children: (
<StyledDropdownMenuItemsContainer hasMaxHeight>
<FakeSelectableMenuItemList hasAvatar />
</StyledDropdownMenuItemsContainer>
</StyledDropdownMenu>
),
};
export const CheckableMenuItem: Story = {
...WithContentBelow,
render: (args) => (
<StyledDropdownMenu {...args}>
<StyledDropdownMenuItemsContainer hasMaxHeight>
<FakeCheckableMenuItemList />
</StyledDropdownMenuItemsContainer>
</StyledDropdownMenu>
),
),
},
};
export const CheckableMenuItemWithAvatar: Story = {
...WithContentBelow,
render: (args) => (
<StyledDropdownMenu {...args}>
decorators: [WithContentBelowDecorator],
args: {
children: (
<StyledDropdownMenuItemsContainer hasMaxHeight>
<FakeCheckableMenuItemList hasAvatar />
</StyledDropdownMenuItemsContainer>
</StyledDropdownMenu>
),
),
},
};

View File

@ -0,0 +1,25 @@
import type { Meta, StoryObj } from '@storybook/react';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { DropdownMenuInput } from '../DropdownMenuInput';
const meta: Meta<typeof DropdownMenuInput> = {
title: 'UI/Dropdown/DropdownMenuInput',
component: DropdownMenuInput,
decorators: [ComponentDecorator],
args: { defaultValue: 'Lorem ipsum' },
argTypes: {
as: { table: { disable: true } },
theme: { table: { disable: true } },
},
};
export default meta;
type Story = StoryObj<typeof DropdownMenuInput>;
export const Default: Story = {};
export const Focused: Story = {
args: { autoFocus: true },
};

View File

@ -1,7 +1,7 @@
import { useRef } from 'react';
import debounce from 'lodash.debounce';
import { DropdownMenuInput } from '@/ui/dropdown/components/DropdownMenuInput';
import { DropdownMenuSearchInput } from '@/ui/dropdown/components/DropdownMenuSearchInput';
import { StyledDropdownMenu } from '@/ui/dropdown/components/StyledDropdownMenu';
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
import { StyledDropdownMenuSeparator } from '@/ui/dropdown/components/StyledDropdownMenuSeparator';
@ -73,7 +73,7 @@ export const MultipleEntitySelect = <
return (
<StyledDropdownMenu ref={containerRef}>
<DropdownMenuInput
<DropdownMenuSearchInput
value={searchFilter}
onChange={handleFilterChange}
autoFocus

View File

@ -1,6 +1,6 @@
import { useRef } from 'react';
import { DropdownMenuInput } from '@/ui/dropdown/components/DropdownMenuInput';
import { DropdownMenuSearchInput } from '@/ui/dropdown/components/DropdownMenuSearchInput';
import { StyledDropdownMenu } from '@/ui/dropdown/components/StyledDropdownMenu';
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
import { StyledDropdownMenuSeparator } from '@/ui/dropdown/components/StyledDropdownMenuSeparator';
@ -65,7 +65,7 @@ export const SingleEntitySelect = <
ref={containerRef}
width={width}
>
<DropdownMenuInput
<DropdownMenuSearchInput
value={searchFilter}
onChange={handleSearchFilterChange}
autoFocus

View File

@ -1,18 +1,17 @@
import { useCallback, useContext, useRef, useState } from 'react';
import styled from '@emotion/styled';
import { OnDragEndResponder } from '@hello-pangea/dnd';
import { useRecoilCallback, useRecoilValue, useResetRecoilState } from 'recoil';
import { Key } from 'ts-key-enum';
import { DropdownMenuHeader } from '@/ui/dropdown/components/DropdownMenuHeader';
import { DropdownMenuInput } from '@/ui/dropdown/components/DropdownMenuInput';
import { DropdownMenuInputContainer } from '@/ui/dropdown/components/DropdownMenuInputContainer';
import { StyledDropdownMenu } from '@/ui/dropdown/components/StyledDropdownMenu';
import { StyledDropdownMenuItemsContainer } from '@/ui/dropdown/components/StyledDropdownMenuItemsContainer';
import { StyledDropdownMenuSeparator } from '@/ui/dropdown/components/StyledDropdownMenuSeparator';
import { useDropdownButton } from '@/ui/dropdown/hooks/useDropdownButton';
import { IconChevronLeft, IconFileImport, IconTag } from '@/ui/icon';
import { MenuItem } from '@/ui/menu-item/components/MenuItem';
import { rgba } from '@/ui/theme/constants/colors';
import { textInputStyle } from '@/ui/theme/constants/effects';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { useRecoilScopeId } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopeId';
@ -34,29 +33,6 @@ import { TableOptionsHotkeyScope } from '../../types/TableOptionsHotkeyScope';
type TableOptionsMenu = 'fields';
const StyledInputContainer = styled.div`
box-sizing: border-box;
padding: ${({ theme }) => theme.spacing(1)};
width: 100%;
`;
const StyledViewNameInput = styled.input`
${textInputStyle}
border: 1px solid ${({ theme }) => theme.border.color.medium};
border-radius: ${({ theme }) => theme.border.radius.sm};
box-sizing: border-box;
font-weight: ${({ theme }) => theme.font.weight.medium};
height: 32px;
position: relative;
width: 100%;
&:focus {
border-color: ${({ theme }) => theme.color.blue};
box-shadow: 0px 0px 0px 3px ${({ theme }) => rgba(theme.color.blue, 0.1)};
}
`;
export const TableOptionsDropdownContent = () => {
const scopeId = useRecoilScopeId(TableRecoilScopeContext);
@ -158,8 +134,8 @@ export const TableOptionsDropdownContent = () => {
<StyledDropdownMenu>
{!currentMenu && (
<>
<StyledInputContainer>
<StyledViewNameInput
<DropdownMenuInputContainer>
<DropdownMenuInput
ref={viewEditInputRef}
autoFocus={
viewEditMode.mode === 'create' || !!viewEditMode.viewId
@ -175,7 +151,7 @@ export const TableOptionsDropdownContent = () => {
: currentView?.name
}
/>
</StyledInputContainer>
</DropdownMenuInputContainer>
<StyledDropdownMenuSeparator />
<StyledDropdownMenuItemsContainer>
<MenuItem

View File

@ -1,6 +1,6 @@
import { ChangeEvent } from 'react';
import { DropdownMenuInput } from '@/ui/dropdown/components/DropdownMenuInput';
import { DropdownMenuSearchInput } from '@/ui/dropdown/components/DropdownMenuSearchInput';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { filterDefinitionUsedInDropdownScopedState } from '@/ui/view-bar/states/filterDefinitionUsedInDropdownScopedState';
import { filterDropdownSearchInputScopedState } from '@/ui/view-bar/states/filterDropdownSearchInputScopedState';
@ -30,7 +30,7 @@ export const FilterDropdownEntitySearchInput = () => {
return (
filterDefinitionUsedInDropdown &&
selectedOperandInDropdown && (
<DropdownMenuInput
<DropdownMenuSearchInput
type="text"
value={filterDropdownSearchInput}
placeholder={filterDefinitionUsedInDropdown.label}

View File

@ -1,6 +1,6 @@
import { ChangeEvent } from 'react';
import { DropdownMenuInput } from '@/ui/dropdown/components/DropdownMenuInput';
import { DropdownMenuSearchInput } from '@/ui/dropdown/components/DropdownMenuSearchInput';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useRemoveFilter } from '../hooks/useRemoveFilter';
@ -28,7 +28,7 @@ export const FilterDropdownNumberSearchInput = () => {
return (
filterDefinitionUsedInDropdown &&
selectedOperandInDropdown && (
<DropdownMenuInput
<DropdownMenuSearchInput
type="number"
placeholder={filterDefinitionUsedInDropdown.label}
onChange={(event: ChangeEvent<HTMLInputElement>) => {

View File

@ -1,6 +1,6 @@
import { ChangeEvent } from 'react';
import { DropdownMenuInput } from '@/ui/dropdown/components/DropdownMenuInput';
import { DropdownMenuSearchInput } from '@/ui/dropdown/components/DropdownMenuSearchInput';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useFilterCurrentlyEdited } from '../hooks/useFilterCurrentlyEdited';
@ -38,7 +38,7 @@ export const FilterDropdownTextSearchInput = () => {
return (
filterDefinitionUsedInDropdown &&
selectedOperandInDropdown && (
<DropdownMenuInput
<DropdownMenuSearchInput
type="text"
placeholder={filterDefinitionUsedInDropdown.label}
value={filterCurrentlyEdited?.value ?? filterDropdownSearchInput}