Migrate to a monorepo structure (#2909)
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
import React, { useRef } from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { actionBarEntriesState } from '@/ui/navigation/action-bar/states/actionBarEntriesState';
|
||||
import { contextMenuIsOpenState } from '@/ui/navigation/context-menu/states/contextMenuIsOpenState';
|
||||
|
||||
import { actionBarOpenState } from '../states/actionBarIsOpenState';
|
||||
|
||||
import { ActionBarItem } from './ActionBarItem';
|
||||
|
||||
type ActionBarProps = {
|
||||
selectedIds: string[];
|
||||
};
|
||||
|
||||
const StyledContainerActionBar = styled.div`
|
||||
align-items: center;
|
||||
background: ${({ theme }) => theme.background.secondary};
|
||||
border: 1px solid ${({ theme }) => theme.border.color.medium};
|
||||
border-radius: ${({ theme }) => theme.border.radius.md};
|
||||
bottom: 38px;
|
||||
box-shadow: ${({ theme }) => theme.boxShadow.strong};
|
||||
display: flex;
|
||||
height: 48px;
|
||||
|
||||
left: 50%;
|
||||
padding-left: ${({ theme }) => theme.spacing(2)};
|
||||
padding-right: ${({ theme }) => theme.spacing(2)};
|
||||
position: absolute;
|
||||
top: auto;
|
||||
|
||||
transform: translateX(-50%);
|
||||
z-index: 1;
|
||||
`;
|
||||
|
||||
export const ActionBar = ({ selectedIds }: ActionBarProps) => {
|
||||
const actionBarOpen = useRecoilValue(actionBarOpenState);
|
||||
const contextMenuIsOpen = useRecoilValue(contextMenuIsOpenState);
|
||||
const actionBarEntries = useRecoilValue(actionBarEntriesState);
|
||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
if (selectedIds.length === 0 || !actionBarOpen || contextMenuIsOpen) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<StyledContainerActionBar
|
||||
data-select-disable
|
||||
className="action-bar"
|
||||
ref={wrapperRef}
|
||||
>
|
||||
{actionBarEntries.map((item) => (
|
||||
<ActionBarItem
|
||||
Icon={item.Icon}
|
||||
accent={item.accent}
|
||||
label={item.label}
|
||||
onClick={item.onClick}
|
||||
key={item.label}
|
||||
/>
|
||||
))}
|
||||
</StyledContainerActionBar>
|
||||
);
|
||||
};
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
|
||||
|
||||
import { ActionBarItemAccent } from '../types/ActionBarItemAccent';
|
||||
|
||||
type ActionBarItemProps = {
|
||||
Icon: IconComponent;
|
||||
label: string;
|
||||
accent?: ActionBarItemAccent;
|
||||
onClick: () => void;
|
||||
};
|
||||
|
||||
const StyledButton = styled.div<{ accent: ActionBarItemAccent }>`
|
||||
border-radius: ${({ theme }) => theme.border.radius.sm};
|
||||
color: ${(props) =>
|
||||
props.accent === 'danger'
|
||||
? props.theme.color.red
|
||||
: props.theme.font.color.secondary};
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
padding: ${({ theme }) => theme.spacing(2)};
|
||||
transition: background 0.1s ease;
|
||||
user-select: none;
|
||||
|
||||
&:hover {
|
||||
background: ${({ theme, accent }) =>
|
||||
accent === 'danger'
|
||||
? theme.background.danger
|
||||
: theme.background.tertiary};
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledButtonLabel = styled.div`
|
||||
font-weight: ${({ theme }) => theme.font.weight.medium};
|
||||
margin-left: ${({ theme }) => theme.spacing(1)};
|
||||
`;
|
||||
|
||||
export const ActionBarItem = ({
|
||||
label,
|
||||
Icon,
|
||||
accent = 'standard',
|
||||
onClick,
|
||||
}: ActionBarItemProps) => {
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<StyledButton accent={accent} onClick={onClick}>
|
||||
{Icon && <Icon size={theme.icon.size.md} />}
|
||||
<StyledButtonLabel>{label}</StyledButtonLabel>
|
||||
</StyledButton>
|
||||
);
|
||||
};
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
|
||||
import { RecordTableScope } from '@/object-record/record-table/scopes/RecordTableScope';
|
||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
||||
|
||||
import { actionBarOpenState } from '../../states/actionBarIsOpenState';
|
||||
import { ActionBar } from '../ActionBar';
|
||||
|
||||
const FilledActionBar = (props: { selectedIds: string[] }) => {
|
||||
const setActionBarOpenState = useSetRecoilState(actionBarOpenState);
|
||||
setActionBarOpenState(true);
|
||||
return <ActionBar selectedIds={props.selectedIds} />;
|
||||
};
|
||||
|
||||
const meta: Meta<typeof ActionBar> = {
|
||||
title: 'UI/Navigation/ActionBar/ActionBar',
|
||||
component: FilledActionBar,
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<RecordTableScope
|
||||
recordTableScopeId="companies"
|
||||
onColumnsChange={() => {}}
|
||||
>
|
||||
<MemoryRouter>
|
||||
<Story />
|
||||
</MemoryRouter>
|
||||
</RecordTableScope>
|
||||
),
|
||||
ComponentDecorator,
|
||||
],
|
||||
args: { selectedIds: ['TestId'] },
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof ActionBar>;
|
||||
|
||||
export const Default: Story = {};
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
import { atom } from 'recoil';
|
||||
|
||||
import { ActionBarEntry } from '../types/ActionBarEntry';
|
||||
|
||||
export const actionBarEntriesState = atom<ActionBarEntry[]>({
|
||||
key: 'actionBarEntriesState',
|
||||
default: [],
|
||||
});
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import { atom } from 'recoil';
|
||||
|
||||
export const actionBarOpenState = atom<boolean>({
|
||||
key: 'actionBarOpenState',
|
||||
default: false,
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
|
||||
|
||||
import { ActionBarItemAccent } from './ActionBarItemAccent';
|
||||
|
||||
export type ActionBarEntry = {
|
||||
label: string;
|
||||
Icon: IconComponent;
|
||||
accent?: ActionBarItemAccent;
|
||||
onClick: () => void;
|
||||
};
|
||||
+1
@@ -0,0 +1 @@
|
||||
export type ActionBarItemAccent = 'standard' | 'danger';
|
||||
Reference in New Issue
Block a user