Refactor UI folder (#2016)
* Added Overview page * Revised Getting Started page * Minor revision * Edited readme, minor modifications to docs * Removed sweep.yaml, .devcontainer, .ergomake * Moved security.md to .github, added contributing.md * changes as per code review * updated contributing.md * fixed broken links & added missing links in doc, improved structure * fixed link in wsl setup * fixed server link, added https cloning in yarn-setup * removed package-lock.json * added doc card, admonitions * removed underline from nav buttons * refactoring modules/ui * refactoring modules/ui * Change folder case * Fix theme location * Fix case 2 * Fix storybook --------- Co-authored-by: Nimra Ahmed <nimra1408@gmail.com> Co-authored-by: Nimra Ahmed <50912134+nimraahmed@users.noreply.github.com>
This commit is contained in:
@ -0,0 +1,91 @@
|
||||
import React, { useRef } from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { StyledDropdownMenu } from '@/ui/layout/dropdown/components/StyledDropdownMenu';
|
||||
import { actionBarOpenState } from '@/ui/navigation/action-bar/states/actionBarIsOpenState';
|
||||
import { contextMenuPositionState } from '@/ui/navigation/context-menu/states/contextMenuPositionState';
|
||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||
|
||||
import { contextMenuEntriesState } from '../states/contextMenuEntriesState';
|
||||
import { contextMenuIsOpenState } from '../states/contextMenuIsOpenState';
|
||||
import { PositionType } from '../types/PositionType';
|
||||
|
||||
import { ContextMenuItem } from './ContextMenuItem';
|
||||
|
||||
type ContextMenuProps = {
|
||||
selectedIds: string[];
|
||||
};
|
||||
|
||||
type StyledContainerProps = {
|
||||
position: PositionType;
|
||||
};
|
||||
|
||||
const StyledContainerContextMenu = styled.div<StyledContainerProps>`
|
||||
align-items: flex-start;
|
||||
background: ${({ theme }) => theme.background.secondary};
|
||||
border: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
border-radius: ${({ theme }) => theme.border.radius.md};
|
||||
box-shadow: ${({ theme }) => theme.boxShadow.strong};
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1px;
|
||||
|
||||
left: ${(props) => `${props.position.x}px`};
|
||||
position: fixed;
|
||||
top: ${(props) => `${props.position.y}px`};
|
||||
|
||||
transform: translateX(-50%);
|
||||
width: auto;
|
||||
z-index: 1;
|
||||
`;
|
||||
|
||||
export const ContextMenu = ({ selectedIds }: ContextMenuProps) => {
|
||||
const contextMenuPosition = useRecoilValue(contextMenuPositionState);
|
||||
const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState);
|
||||
const contextMenuEntries = useRecoilValue(contextMenuEntriesState);
|
||||
const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState);
|
||||
const setActionBarOpenState = useSetRecoilState(actionBarOpenState);
|
||||
const wrapperRef = useRef(null);
|
||||
|
||||
useListenClickOutside({
|
||||
refs: [wrapperRef],
|
||||
callback: () => {
|
||||
setContextMenuOpenState(false);
|
||||
setActionBarOpenState(true);
|
||||
},
|
||||
});
|
||||
|
||||
if (selectedIds.length === 0 || !contextMenuIsOpen) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const width = contextMenuEntries.some(
|
||||
(contextMenuEntry) => contextMenuEntry.label === 'Remove from favorites',
|
||||
)
|
||||
? 200
|
||||
: undefined;
|
||||
|
||||
return (
|
||||
<StyledContainerContextMenu
|
||||
className="context-menu"
|
||||
ref={wrapperRef}
|
||||
position={contextMenuPosition}
|
||||
>
|
||||
<StyledDropdownMenu data-select-disable width={width}>
|
||||
<DropdownMenuItemsContainer>
|
||||
{contextMenuEntries.map((item) => (
|
||||
<ContextMenuItem
|
||||
Icon={item.Icon}
|
||||
label={item.label}
|
||||
accent={item.accent}
|
||||
onClick={item.onClick}
|
||||
key={item.label}
|
||||
/>
|
||||
))}
|
||||
</DropdownMenuItemsContainer>
|
||||
</StyledDropdownMenu>
|
||||
</StyledContainerContextMenu>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,20 @@
|
||||
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
|
||||
import { ContextMenuItemAccent } from '../types/ContextMenuItemAccent';
|
||||
|
||||
type ContextMenuItemProps = {
|
||||
Icon: IconComponent;
|
||||
label: string;
|
||||
accent?: ContextMenuItemAccent;
|
||||
onClick: () => void;
|
||||
};
|
||||
|
||||
export const ContextMenuItem = ({
|
||||
label,
|
||||
Icon,
|
||||
accent = 'default',
|
||||
onClick,
|
||||
}: ContextMenuItemProps) => (
|
||||
<MenuItem LeftIcon={Icon} onClick={onClick} accent={accent} text={label} />
|
||||
);
|
||||
@ -0,0 +1,48 @@
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
|
||||
import { useCompanyTableContextMenuEntries } from '@/companies/hooks/useCompanyTableContextMenuEntries';
|
||||
import { CompanyTableMockMode } from '@/companies/table/components/CompanyTableMockMode';
|
||||
import { TableRecoilScopeContext } from '@/ui/data/data-table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
|
||||
import { contextMenuIsOpenState } from '../../states/contextMenuIsOpenState';
|
||||
import { contextMenuPositionState } from '../../states/contextMenuPositionState';
|
||||
import { ContextMenu } from '../ContextMenu';
|
||||
|
||||
const FilledContextMenu = (props: { selectedIds: string[] }) => {
|
||||
const { setContextMenuEntries } = useCompanyTableContextMenuEntries();
|
||||
setContextMenuEntries();
|
||||
const setContextMenuPosition = useSetRecoilState(contextMenuPositionState);
|
||||
setContextMenuPosition({
|
||||
x: 100,
|
||||
y: 10,
|
||||
});
|
||||
const setContextMenuOpenState = useSetRecoilState(contextMenuIsOpenState);
|
||||
setContextMenuOpenState(true);
|
||||
return <ContextMenu selectedIds={props.selectedIds} />;
|
||||
};
|
||||
|
||||
const meta: Meta<typeof ContextMenu> = {
|
||||
title: 'UI/ContextMenu/ContextMenu',
|
||||
component: FilledContextMenu,
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<RecoilScope CustomRecoilScopeContext={TableRecoilScopeContext}>
|
||||
<MemoryRouter>
|
||||
<CompanyTableMockMode></CompanyTableMockMode>
|
||||
<Story />
|
||||
</MemoryRouter>
|
||||
</RecoilScope>
|
||||
),
|
||||
ComponentDecorator,
|
||||
],
|
||||
args: { selectedIds: ['TestId'] },
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof ContextMenu>;
|
||||
|
||||
export const Default: Story = {};
|
||||
@ -0,0 +1,8 @@
|
||||
import { atom } from 'recoil';
|
||||
|
||||
import { ContextMenuEntry } from '../types/ContextMenuEntry';
|
||||
|
||||
export const contextMenuEntriesState = atom<ContextMenuEntry[]>({
|
||||
key: 'contextMenuEntriesState',
|
||||
default: [],
|
||||
});
|
||||
@ -0,0 +1,6 @@
|
||||
import { atom } from 'recoil';
|
||||
|
||||
export const contextMenuIsOpenState = atom<boolean>({
|
||||
key: 'contextMenuIsOpenState',
|
||||
default: false,
|
||||
});
|
||||
@ -0,0 +1,11 @@
|
||||
import { atom } from 'recoil';
|
||||
|
||||
import { PositionType } from '@/ui/navigation/context-menu/types/PositionType';
|
||||
|
||||
export const contextMenuPositionState = atom<PositionType>({
|
||||
key: 'contextMenuPositionState',
|
||||
default: {
|
||||
x: null,
|
||||
y: null,
|
||||
},
|
||||
});
|
||||
@ -0,0 +1,10 @@
|
||||
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
|
||||
|
||||
import { ContextMenuItemAccent } from './ContextMenuItemAccent';
|
||||
|
||||
export type ContextMenuEntry = {
|
||||
label: string;
|
||||
Icon: IconComponent;
|
||||
accent?: ContextMenuItemAccent;
|
||||
onClick: () => void;
|
||||
};
|
||||
@ -0,0 +1 @@
|
||||
export type ContextMenuItemAccent = 'default' | 'danger';
|
||||
@ -0,0 +1,4 @@
|
||||
export type PositionType = {
|
||||
x: number | null;
|
||||
y: number | null;
|
||||
};
|
||||
Reference in New Issue
Block a user