Refactor icons passed as props with the new way (#1492)
* Refactor icons passed as props with the new way Co-authored-by: v1b3m <vibenjamin6@gmail.com> Co-authored-by: Matheus <matheus_benini@hotmail.com> * Update more files Co-authored-by: v1b3m <vibenjamin6@gmail.com> Co-authored-by: Matheus <matheus_benini@hotmail.com> * Fix according to review * Fix according to review * Fix according to review * Fix chromatic regressions --------- Co-authored-by: v1b3m <vibenjamin6@gmail.com> Co-authored-by: Matheus <matheus_benini@hotmail.com> Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -1,5 +1,4 @@
|
|||||||
import { useLocation, useNavigate } from 'react-router-dom';
|
import { useLocation, useNavigate } from 'react-router-dom';
|
||||||
import { useTheme } from '@emotion/react';
|
|
||||||
|
|
||||||
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
import { useCommandMenu } from '@/command-menu/hooks/useCommandMenu';
|
||||||
import { Favorites } from '@/favorites/components/Favorites';
|
import { Favorites } from '@/favorites/components/Favorites';
|
||||||
@ -21,7 +20,6 @@ import NavTitle from '@/ui/navbar/components/NavTitle';
|
|||||||
import { measureTotalFrameLoad } from './utils/measureTotalFrameLoad';
|
import { measureTotalFrameLoad } from './utils/measureTotalFrameLoad';
|
||||||
|
|
||||||
export function AppNavbar() {
|
export function AppNavbar() {
|
||||||
const theme = useTheme();
|
|
||||||
const currentPath = useLocation().pathname;
|
const currentPath = useLocation().pathname;
|
||||||
const { openCommandMenu } = useCommandMenu();
|
const { openCommandMenu } = useCommandMenu();
|
||||||
|
|
||||||
@ -35,7 +33,7 @@ export function AppNavbar() {
|
|||||||
<MainNavbar>
|
<MainNavbar>
|
||||||
<NavItem
|
<NavItem
|
||||||
label="Search"
|
label="Search"
|
||||||
icon={<IconSearch size={theme.icon.size.md} />}
|
Icon={IconSearch}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
openCommandMenu();
|
openCommandMenu();
|
||||||
}}
|
}}
|
||||||
@ -43,26 +41,26 @@ export function AppNavbar() {
|
|||||||
<NavItem
|
<NavItem
|
||||||
label="Notifications"
|
label="Notifications"
|
||||||
to="/inbox"
|
to="/inbox"
|
||||||
icon={<IconBell size={theme.icon.size.md} />}
|
Icon={IconBell}
|
||||||
soon={true}
|
soon={true}
|
||||||
/>
|
/>
|
||||||
<NavItem
|
<NavItem
|
||||||
label="Settings"
|
label="Settings"
|
||||||
to="/settings/profile"
|
to="/settings/profile"
|
||||||
icon={<IconSettings size={theme.icon.size.md} />}
|
Icon={IconSettings}
|
||||||
/>
|
/>
|
||||||
<NavItem
|
<NavItem
|
||||||
label="Tasks"
|
label="Tasks"
|
||||||
to="/tasks"
|
to="/tasks"
|
||||||
active={currentPath === '/tasks'}
|
active={currentPath === '/tasks'}
|
||||||
icon={<IconCheckbox size={theme.icon.size.md} />}
|
Icon={IconCheckbox}
|
||||||
/>
|
/>
|
||||||
<Favorites />
|
<Favorites />
|
||||||
<NavTitle label="Workspace" />
|
<NavTitle label="Workspace" />
|
||||||
<NavItem
|
<NavItem
|
||||||
label="Companies"
|
label="Companies"
|
||||||
to="/companies"
|
to="/companies"
|
||||||
icon={<IconBuildingSkyscraper size={theme.icon.size.md} />}
|
Icon={IconBuildingSkyscraper}
|
||||||
active={currentPath === '/companies'}
|
active={currentPath === '/companies'}
|
||||||
/>
|
/>
|
||||||
<NavItem
|
<NavItem
|
||||||
@ -73,7 +71,7 @@ export function AppNavbar() {
|
|||||||
|
|
||||||
navigate('/people');
|
navigate('/people');
|
||||||
}}
|
}}
|
||||||
icon={<IconUser size={theme.icon.size.md} />}
|
Icon={IconUser}
|
||||||
active={currentPath === '/people'}
|
active={currentPath === '/people'}
|
||||||
/>
|
/>
|
||||||
<NavItem
|
<NavItem
|
||||||
@ -84,7 +82,7 @@ export function AppNavbar() {
|
|||||||
|
|
||||||
navigate('/opportunities');
|
navigate('/opportunities');
|
||||||
}}
|
}}
|
||||||
icon={<IconTargetArrow size={theme.icon.size.md} />}
|
Icon={IconTargetArrow}
|
||||||
active={currentPath === '/opportunities'}
|
active={currentPath === '/opportunities'}
|
||||||
/>
|
/>
|
||||||
</MainNavbar>
|
</MainNavbar>
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
import { useTheme } from '@emotion/react';
|
|
||||||
|
|
||||||
import { Button } from '@/ui/button/components/Button';
|
import { Button } from '@/ui/button/components/Button';
|
||||||
import { ButtonGroup } from '@/ui/button/components/ButtonGroup';
|
import { ButtonGroup } from '@/ui/button/components/ButtonGroup';
|
||||||
import { IconCheckbox, IconNotes, IconTimelineEvent } from '@/ui/icon/index';
|
import { IconCheckbox, IconNotes, IconTimelineEvent } from '@/ui/icon/index';
|
||||||
@ -15,21 +13,12 @@ export function ActivityCreateButton({
|
|||||||
onTaskClick,
|
onTaskClick,
|
||||||
onActivityClick,
|
onActivityClick,
|
||||||
}: ActivityCreateButtonProps) {
|
}: ActivityCreateButtonProps) {
|
||||||
const theme = useTheme();
|
|
||||||
return (
|
return (
|
||||||
<ButtonGroup variant={'secondary'}>
|
<ButtonGroup variant={'secondary'}>
|
||||||
|
<Button Icon={IconNotes} title="Note" onClick={onNoteClick} />
|
||||||
|
<Button Icon={IconCheckbox} title="Task" onClick={onTaskClick} />
|
||||||
<Button
|
<Button
|
||||||
icon={<IconNotes size={theme.icon.size.sm} />}
|
Icon={IconTimelineEvent}
|
||||||
title="Note"
|
|
||||||
onClick={onNoteClick}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
icon={<IconCheckbox size={theme.icon.size.sm} />}
|
|
||||||
title="Task"
|
|
||||||
onClick={onTaskClick}
|
|
||||||
/>
|
|
||||||
<Button
|
|
||||||
icon={<IconTimelineEvent size={theme.icon.size.sm} />}
|
|
||||||
title="Activity"
|
title="Activity"
|
||||||
soon={true}
|
soon={true}
|
||||||
onClick={onActivityClick}
|
onClick={onActivityClick}
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { useTheme } from '@emotion/react';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
|
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
|
||||||
@ -48,7 +47,6 @@ const StyledNotesContainer = styled.div`
|
|||||||
|
|
||||||
export function Notes({ entity }: { entity: ActivityTargetableEntity }) {
|
export function Notes({ entity }: { entity: ActivityTargetableEntity }) {
|
||||||
const { notes } = useNotes(entity);
|
const { notes } = useNotes(entity);
|
||||||
const theme = useTheme();
|
|
||||||
|
|
||||||
const openCreateActivity = useOpenCreateActivityDrawer();
|
const openCreateActivity = useOpenCreateActivityDrawer();
|
||||||
|
|
||||||
@ -58,7 +56,7 @@ export function Notes({ entity }: { entity: ActivityTargetableEntity }) {
|
|||||||
<StyledEmptyTaskGroupTitle>No note yet</StyledEmptyTaskGroupTitle>
|
<StyledEmptyTaskGroupTitle>No note yet</StyledEmptyTaskGroupTitle>
|
||||||
<StyledEmptyTaskGroupSubTitle>Create one:</StyledEmptyTaskGroupSubTitle>
|
<StyledEmptyTaskGroupSubTitle>Create one:</StyledEmptyTaskGroupSubTitle>
|
||||||
<Button
|
<Button
|
||||||
icon={<IconNotes size={theme.icon.size.sm} />}
|
Icon={IconNotes}
|
||||||
title="New note"
|
title="New note"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
onClick={() => openCreateActivity(ActivityType.Note, [entity])}
|
onClick={() => openCreateActivity(ActivityType.Note, [entity])}
|
||||||
@ -74,7 +72,7 @@ export function Notes({ entity }: { entity: ActivityTargetableEntity }) {
|
|||||||
notes={notes ?? []}
|
notes={notes ?? []}
|
||||||
button={
|
button={
|
||||||
<Button
|
<Button
|
||||||
icon={<IconNotes size={theme.icon.size.md} />}
|
Icon={IconNotes}
|
||||||
size="small"
|
size="small"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
title="Add note"
|
title="Add note"
|
||||||
|
|||||||
@ -33,7 +33,7 @@ export function ActivityActionBar({ activityId }: OwnProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<LightIconButton
|
<LightIconButton
|
||||||
icon={<IconTrash />}
|
Icon={IconTrash}
|
||||||
onClick={deleteActivity}
|
onClick={deleteActivity}
|
||||||
accent="tertiary"
|
accent="tertiary"
|
||||||
size="medium"
|
size="medium"
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
import { useTheme } from '@emotion/react';
|
|
||||||
|
|
||||||
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
|
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
|
||||||
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
|
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
|
||||||
import { Button } from '@/ui/button/components/Button';
|
import { Button } from '@/ui/button/components/Button';
|
||||||
@ -11,7 +9,6 @@ export function AddTaskButton({
|
|||||||
}: {
|
}: {
|
||||||
entity?: ActivityTargetableEntity;
|
entity?: ActivityTargetableEntity;
|
||||||
}) {
|
}) {
|
||||||
const theme = useTheme();
|
|
||||||
const openCreateActivity = useOpenCreateActivityDrawer();
|
const openCreateActivity = useOpenCreateActivityDrawer();
|
||||||
|
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
@ -20,7 +17,7 @@ export function AddTaskButton({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
icon={<IconPlus size={theme.icon.size.md} />}
|
Icon={IconPlus}
|
||||||
size="small"
|
size="small"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
title="Add task"
|
title="Add task"
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { useTheme } from '@emotion/react';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
|
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
|
||||||
@ -60,7 +59,6 @@ export function TaskGroups({ entity, showAddButton }: OwnProps) {
|
|||||||
unscheduledTasks,
|
unscheduledTasks,
|
||||||
completedTasks,
|
completedTasks,
|
||||||
} = useTasks(entity);
|
} = useTasks(entity);
|
||||||
const theme = useTheme();
|
|
||||||
|
|
||||||
const openCreateActivity = useOpenCreateActivityDrawer();
|
const openCreateActivity = useOpenCreateActivityDrawer();
|
||||||
|
|
||||||
@ -81,7 +79,7 @@ export function TaskGroups({ entity, showAddButton }: OwnProps) {
|
|||||||
<StyledEmptyTaskGroupTitle>No task yet</StyledEmptyTaskGroupTitle>
|
<StyledEmptyTaskGroupTitle>No task yet</StyledEmptyTaskGroupTitle>
|
||||||
<StyledEmptyTaskGroupSubTitle>Create one:</StyledEmptyTaskGroupSubTitle>
|
<StyledEmptyTaskGroupSubTitle>Create one:</StyledEmptyTaskGroupSubTitle>
|
||||||
<Button
|
<Button
|
||||||
icon={<IconCheckbox size={theme.icon.size.sm} />}
|
Icon={IconCheckbox}
|
||||||
title="New task"
|
title="New task"
|
||||||
variant={'secondary'}
|
variant={'secondary'}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
|
|||||||
@ -60,7 +60,6 @@ export function SignInUpForm() {
|
|||||||
},
|
},
|
||||||
workspace,
|
workspace,
|
||||||
} = useSignInUp();
|
} = useSignInUp();
|
||||||
const theme = useTheme();
|
|
||||||
|
|
||||||
const buttonTitle = useMemo(() => {
|
const buttonTitle = useMemo(() => {
|
||||||
if (signInUpStep === SignInUpStep.Init) {
|
if (signInUpStep === SignInUpStep.Init) {
|
||||||
@ -84,6 +83,8 @@ export function SignInUpForm() {
|
|||||||
: 'Sign up to Twenty';
|
: 'Sign up to Twenty';
|
||||||
}, [signInUpMode, workspace?.displayName]);
|
}, [signInUpMode, workspace?.displayName]);
|
||||||
|
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<AnimatedEaseIn>
|
<AnimatedEaseIn>
|
||||||
@ -94,7 +95,12 @@ export function SignInUpForm() {
|
|||||||
{authProviders.google && (
|
{authProviders.google && (
|
||||||
<>
|
<>
|
||||||
<MainButton
|
<MainButton
|
||||||
icon={<IconBrandGoogle size={theme.icon.size.sm} stroke={4} />}
|
Icon={() => (
|
||||||
|
<IconBrandGoogle
|
||||||
|
size={theme.icon.size.md}
|
||||||
|
stroke={theme.icon.stroke.lg}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
title="Continue with Google"
|
title="Continue with Google"
|
||||||
onClick={signInWithGoogle}
|
onClick={signInWithGoogle}
|
||||||
fullWidth
|
fullWidth
|
||||||
|
|||||||
@ -119,7 +119,7 @@ export function CommandMenu() {
|
|||||||
key={cmd.label}
|
key={cmd.label}
|
||||||
to={cmd.to}
|
to={cmd.to}
|
||||||
label={cmd.label}
|
label={cmd.label}
|
||||||
icon={cmd.icon}
|
Icon={cmd.Icon}
|
||||||
shortcuts={cmd.shortcuts || []}
|
shortcuts={cmd.shortcuts || []}
|
||||||
onClick={cmd.onCommandClick}
|
onClick={cmd.onCommandClick}
|
||||||
/>
|
/>
|
||||||
@ -132,7 +132,7 @@ export function CommandMenu() {
|
|||||||
key={matchingCreateCommand.label}
|
key={matchingCreateCommand.label}
|
||||||
to={matchingCreateCommand.to}
|
to={matchingCreateCommand.to}
|
||||||
label={matchingCreateCommand.label}
|
label={matchingCreateCommand.label}
|
||||||
icon={matchingCreateCommand.icon}
|
Icon={matchingCreateCommand.Icon}
|
||||||
shortcuts={matchingCreateCommand.shortcuts || []}
|
shortcuts={matchingCreateCommand.shortcuts || []}
|
||||||
onClick={matchingCreateCommand.onCommandClick}
|
onClick={matchingCreateCommand.onCommandClick}
|
||||||
/>
|
/>
|
||||||
@ -155,14 +155,14 @@ export function CommandMenu() {
|
|||||||
to={`person/${person.id}`}
|
to={`person/${person.id}`}
|
||||||
label={person.displayName}
|
label={person.displayName}
|
||||||
key={person.id}
|
key={person.id}
|
||||||
icon={
|
Icon={() => (
|
||||||
<Avatar
|
<Avatar
|
||||||
avatarUrl={null}
|
avatarUrl={null}
|
||||||
size="sm"
|
|
||||||
colorId={person.id}
|
|
||||||
placeholder={person.displayName}
|
placeholder={person.displayName}
|
||||||
|
colorId={person.id}
|
||||||
|
type="rounded"
|
||||||
/>
|
/>
|
||||||
}
|
)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</StyledGroup>
|
</StyledGroup>
|
||||||
@ -174,14 +174,13 @@ export function CommandMenu() {
|
|||||||
to={`companies/${company.id}`}
|
to={`companies/${company.id}`}
|
||||||
label={company.name}
|
label={company.name}
|
||||||
key={company.id}
|
key={company.id}
|
||||||
icon={
|
Icon={() => (
|
||||||
<Avatar
|
<Avatar
|
||||||
avatarUrl={getLogoUrlFromDomainName(company.domainName)}
|
avatarUrl={getLogoUrlFromDomainName(company.domainName)}
|
||||||
size="sm"
|
|
||||||
colorId={company.id}
|
colorId={company.id}
|
||||||
placeholder={company.name}
|
placeholder={company.name}
|
||||||
/>
|
/>
|
||||||
}
|
)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</StyledGroup>
|
</StyledGroup>
|
||||||
@ -193,7 +192,7 @@ export function CommandMenu() {
|
|||||||
onClick={() => openActivityRightDrawer(activity.id)}
|
onClick={() => openActivityRightDrawer(activity.id)}
|
||||||
label={activity.title ?? ''}
|
label={activity.title ?? ''}
|
||||||
key={activity.id}
|
key={activity.id}
|
||||||
icon={<IconNotes />}
|
Icon={IconNotes}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</StyledGroup>
|
</StyledGroup>
|
||||||
|
|||||||
@ -1,25 +1,18 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { ReactNode } from 'react';
|
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { IconArrowUpRight } from '@/ui/icon';
|
import { IconArrowUpRight } from '@/ui/icon';
|
||||||
|
import { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
|
import { MenuItemCommand } from '@/ui/menu-item/components/MenuItemCommand';
|
||||||
|
|
||||||
import { useCommandMenu } from '../hooks/useCommandMenu';
|
import { useCommandMenu } from '../hooks/useCommandMenu';
|
||||||
|
|
||||||
import {
|
export type CommandMenuItemProps = {
|
||||||
StyledIconAndLabelContainer,
|
|
||||||
StyledIconContainer,
|
|
||||||
StyledMenuItem,
|
|
||||||
StyledShortCut,
|
|
||||||
StyledShortcutsContainer,
|
|
||||||
} from './CommandMenuStyles';
|
|
||||||
|
|
||||||
export type OwnProps = {
|
|
||||||
label: string;
|
label: string;
|
||||||
to?: string;
|
to?: string;
|
||||||
key: string;
|
key: string;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
icon?: ReactNode;
|
Icon?: IconComponent;
|
||||||
shortcuts?: Array<string>;
|
shortcuts?: Array<string>;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -27,14 +20,14 @@ export function CommandMenuItem({
|
|||||||
label,
|
label,
|
||||||
to,
|
to,
|
||||||
onClick,
|
onClick,
|
||||||
icon,
|
Icon,
|
||||||
shortcuts,
|
shortcuts,
|
||||||
}: OwnProps) {
|
}: CommandMenuItemProps) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { closeCommandMenu } = useCommandMenu();
|
const { closeCommandMenu } = useCommandMenu();
|
||||||
|
|
||||||
if (to && !icon) {
|
if (to && !Icon) {
|
||||||
icon = <IconArrowUpRight />;
|
Icon = IconArrowUpRight;
|
||||||
}
|
}
|
||||||
|
|
||||||
const onItemClick = () => {
|
const onItemClick = () => {
|
||||||
@ -51,23 +44,11 @@ export function CommandMenuItem({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledMenuItem onSelect={onItemClick}>
|
<MenuItemCommand
|
||||||
<StyledIconAndLabelContainer>
|
LeftIcon={Icon}
|
||||||
<StyledIconContainer>{icon}</StyledIconContainer>
|
text={label}
|
||||||
{label}
|
command={shortcuts ? shortcuts.join(' then ') : ''}
|
||||||
</StyledIconAndLabelContainer>
|
onClick={onItemClick}
|
||||||
<StyledShortcutsContainer>
|
/>
|
||||||
{shortcuts &&
|
|
||||||
shortcuts.map((shortcut, index) => {
|
|
||||||
const prefix = index > 0 ? 'then' : '';
|
|
||||||
return (
|
|
||||||
<React.Fragment key={index}>
|
|
||||||
{prefix}
|
|
||||||
<StyledShortCut>{shortcut}</StyledShortCut>
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</StyledShortcutsContainer>
|
|
||||||
</StyledMenuItem>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
|
|
||||||
export enum CommandType {
|
export enum CommandType {
|
||||||
Navigate = 'Navigate',
|
Navigate = 'Navigate',
|
||||||
Create = 'Create',
|
Create = 'Create',
|
||||||
@ -7,7 +9,7 @@ export type Command = {
|
|||||||
to: string;
|
to: string;
|
||||||
label: string;
|
label: string;
|
||||||
type: CommandType.Navigate | CommandType.Create;
|
type: CommandType.Navigate | CommandType.Create;
|
||||||
icon?: JSX.Element;
|
Icon?: IconComponent;
|
||||||
shortcuts?: string[];
|
shortcuts?: string[];
|
||||||
onCommandClick?: () => void;
|
onCommandClick?: () => void;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -123,7 +123,7 @@ export function AddPersonToCompany({
|
|||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<div ref={refs.setReference}>
|
<div ref={refs.setReference}>
|
||||||
<LightIconButton
|
<LightIconButton
|
||||||
icon={<IconPlus />}
|
Icon={IconPlus}
|
||||||
onClick={handleOpenPicker}
|
onClick={handleOpenPicker}
|
||||||
size="small"
|
size="small"
|
||||||
accent="tertiary"
|
accent="tertiary"
|
||||||
|
|||||||
@ -25,19 +25,19 @@ export function useCompanyTableActionBarEntries() {
|
|||||||
setActionBarEntries([
|
setActionBarEntries([
|
||||||
<ActionBarEntry
|
<ActionBarEntry
|
||||||
label="Note"
|
label="Note"
|
||||||
icon={<IconNotes size={16} />}
|
Icon={IconNotes}
|
||||||
onClick={() => handleActivityClick(ActivityType.Note)}
|
onClick={() => handleActivityClick(ActivityType.Note)}
|
||||||
key="note"
|
key="note"
|
||||||
/>,
|
/>,
|
||||||
<ActionBarEntry
|
<ActionBarEntry
|
||||||
label="Task"
|
label="Task"
|
||||||
icon={<IconCheckbox size={16} />}
|
Icon={IconCheckbox}
|
||||||
onClick={() => handleActivityClick(ActivityType.Task)}
|
onClick={() => handleActivityClick(ActivityType.Task)}
|
||||||
key="task"
|
key="task"
|
||||||
/>,
|
/>,
|
||||||
<ActionBarEntry
|
<ActionBarEntry
|
||||||
label="Delete"
|
label="Delete"
|
||||||
icon={<IconTrash size={16} />}
|
Icon={IconTrash}
|
||||||
type="danger"
|
type="danger"
|
||||||
onClick={() => deleteSelectedCompanies()}
|
onClick={() => deleteSelectedCompanies()}
|
||||||
key="delete"
|
key="delete"
|
||||||
|
|||||||
@ -28,32 +28,28 @@ export function Favorites() {
|
|||||||
<NavItem
|
<NavItem
|
||||||
key={id}
|
key={id}
|
||||||
label={`${person.firstName} ${person.lastName}`}
|
label={`${person.firstName} ${person.lastName}`}
|
||||||
icon={
|
Icon={() => (
|
||||||
<Avatar
|
<Avatar
|
||||||
key={id}
|
|
||||||
colorId={person.id}
|
colorId={person.id}
|
||||||
avatarUrl={person.avatarUrl ?? ''}
|
avatarUrl={person.avatarUrl ?? ''}
|
||||||
type="rounded"
|
type="rounded"
|
||||||
placeholder={`${person.firstName} ${person.lastName}`}
|
placeholder={`${person.firstName} ${person.lastName}`}
|
||||||
size="md"
|
|
||||||
/>
|
/>
|
||||||
}
|
)}
|
||||||
to={`/person/${person.id}`}
|
to={`/person/${person.id}`}
|
||||||
/>
|
/>
|
||||||
)) ||
|
)) ??
|
||||||
(company && (
|
(company && (
|
||||||
<NavItem
|
<NavItem
|
||||||
key={id}
|
key={id}
|
||||||
label={company.name}
|
label={company.name}
|
||||||
icon={
|
Icon={() => (
|
||||||
<Avatar
|
<Avatar
|
||||||
key={id}
|
|
||||||
avatarUrl={getLogoUrlFromDomainName(company.domainName) ?? ''}
|
avatarUrl={getLogoUrlFromDomainName(company.domainName) ?? ''}
|
||||||
type="squared"
|
type="squared"
|
||||||
placeholder={company.name}
|
placeholder={company.name}
|
||||||
size="md"
|
|
||||||
/>
|
/>
|
||||||
}
|
)}
|
||||||
to={`/companies/${company.id}`}
|
to={`/companies/${company.id}`}
|
||||||
/>
|
/>
|
||||||
)),
|
)),
|
||||||
|
|||||||
@ -161,7 +161,7 @@ export function PeopleCard({
|
|||||||
<FloatingIconButton
|
<FloatingIconButton
|
||||||
onClick={handleToggleOptions}
|
onClick={handleToggleOptions}
|
||||||
size="small"
|
size="small"
|
||||||
icon={<IconDotsVertical />}
|
Icon={IconDotsVertical}
|
||||||
/>
|
/>
|
||||||
{isOptionsOpen && (
|
{isOptionsOpen && (
|
||||||
<StyledDropdownMenu ref={refs.setFloating} style={floatingStyles}>
|
<StyledDropdownMenu ref={refs.setFloating} style={floatingStyles}>
|
||||||
|
|||||||
@ -64,19 +64,19 @@ export function usePersonTableActionBarEntries() {
|
|||||||
setActionBarEntries([
|
setActionBarEntries([
|
||||||
<ActionBarEntry
|
<ActionBarEntry
|
||||||
label="Note"
|
label="Note"
|
||||||
icon={<IconNotes size={16} />}
|
Icon={IconNotes}
|
||||||
onClick={() => handleActivityClick(ActivityType.Note)}
|
onClick={() => handleActivityClick(ActivityType.Note)}
|
||||||
key="note"
|
key="note"
|
||||||
/>,
|
/>,
|
||||||
<ActionBarEntry
|
<ActionBarEntry
|
||||||
label="Task"
|
label="Task"
|
||||||
icon={<IconCheckbox size={16} />}
|
Icon={IconCheckbox}
|
||||||
onClick={() => handleActivityClick(ActivityType.Task)}
|
onClick={() => handleActivityClick(ActivityType.Task)}
|
||||||
key="task"
|
key="task"
|
||||||
/>,
|
/>,
|
||||||
<ActionBarEntry
|
<ActionBarEntry
|
||||||
label="Delete"
|
label="Delete"
|
||||||
icon={<IconTrash size={16} />}
|
Icon={IconTrash}
|
||||||
type="danger"
|
type="danger"
|
||||||
onClick={handleDeleteClick}
|
onClick={handleDeleteClick}
|
||||||
key="delete"
|
key="delete"
|
||||||
|
|||||||
@ -56,7 +56,7 @@ export function PipelineAddButton() {
|
|||||||
dropdownKey="add-pipeline-progress"
|
dropdownKey="add-pipeline-progress"
|
||||||
buttonComponents={
|
buttonComponents={
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<IconPlus size={16} />}
|
Icon={IconPlus}
|
||||||
size="medium"
|
size="medium"
|
||||||
dataTestId="add-company-progress-button"
|
dataTestId="add-company-progress-button"
|
||||||
accent="default"
|
accent="default"
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useMatch, useNavigate, useResolvedPath } from 'react-router-dom';
|
import { useMatch, useNavigate, useResolvedPath } from 'react-router-dom';
|
||||||
import { useTheme } from '@emotion/react';
|
|
||||||
|
|
||||||
import { useAuth } from '@/auth/hooks/useAuth';
|
import { useAuth } from '@/auth/hooks/useAuth';
|
||||||
import { AppPath } from '@/types/AppPath';
|
import { AppPath } from '@/types/AppPath';
|
||||||
@ -16,7 +15,6 @@ import NavTitle from '@/ui/navbar/components/NavTitle';
|
|||||||
import SubMenuNavbar from '@/ui/navbar/components/SubMenuNavbar';
|
import SubMenuNavbar from '@/ui/navbar/components/SubMenuNavbar';
|
||||||
|
|
||||||
export function SettingsNavbar() {
|
export function SettingsNavbar() {
|
||||||
const theme = useTheme();
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const { signOut } = useAuth();
|
const { signOut } = useAuth();
|
||||||
@ -32,7 +30,7 @@ export function SettingsNavbar() {
|
|||||||
<NavItem
|
<NavItem
|
||||||
label="Profile"
|
label="Profile"
|
||||||
to="/settings/profile"
|
to="/settings/profile"
|
||||||
icon={<IconUserCircle size={theme.icon.size.md} />}
|
Icon={IconUserCircle}
|
||||||
active={
|
active={
|
||||||
!!useMatch({
|
!!useMatch({
|
||||||
path: useResolvedPath('/settings/profile').pathname,
|
path: useResolvedPath('/settings/profile').pathname,
|
||||||
@ -43,7 +41,7 @@ export function SettingsNavbar() {
|
|||||||
<NavItem
|
<NavItem
|
||||||
label="Experience"
|
label="Experience"
|
||||||
to="/settings/profile/experience"
|
to="/settings/profile/experience"
|
||||||
icon={<IconColorSwatch size={theme.icon.size.md} />}
|
Icon={IconColorSwatch}
|
||||||
active={
|
active={
|
||||||
!!useMatch({
|
!!useMatch({
|
||||||
path: useResolvedPath('/settings/profile/experience').pathname,
|
path: useResolvedPath('/settings/profile/experience').pathname,
|
||||||
@ -55,7 +53,7 @@ export function SettingsNavbar() {
|
|||||||
<NavItem
|
<NavItem
|
||||||
label="General"
|
label="General"
|
||||||
to="/settings/workspace"
|
to="/settings/workspace"
|
||||||
icon={<IconSettings size={theme.icon.size.md} />}
|
Icon={IconSettings}
|
||||||
active={
|
active={
|
||||||
!!useMatch({
|
!!useMatch({
|
||||||
path: useResolvedPath('/settings/workspace').pathname,
|
path: useResolvedPath('/settings/workspace').pathname,
|
||||||
@ -66,7 +64,7 @@ export function SettingsNavbar() {
|
|||||||
<NavItem
|
<NavItem
|
||||||
label="Members"
|
label="Members"
|
||||||
to="/settings/workspace-members"
|
to="/settings/workspace-members"
|
||||||
icon={<IconUsers size={theme.icon.size.md} />}
|
Icon={IconUsers}
|
||||||
active={
|
active={
|
||||||
!!useMatch({
|
!!useMatch({
|
||||||
path: useResolvedPath('/settings/workspace-members').pathname,
|
path: useResolvedPath('/settings/workspace-members').pathname,
|
||||||
@ -75,11 +73,7 @@ export function SettingsNavbar() {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<NavTitle label="Other" />
|
<NavTitle label="Other" />
|
||||||
<NavItem
|
<NavItem label="Logout" onClick={handleLogout} Icon={IconLogout} />
|
||||||
label="Logout"
|
|
||||||
onClick={handleLogout}
|
|
||||||
icon={<IconLogout size={theme.icon.size.md} />}
|
|
||||||
/>
|
|
||||||
</SubMenuNavbar>
|
</SubMenuNavbar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,7 @@ export const ContinueButton = ({
|
|||||||
}: ContinueButtonProps) => (
|
}: ContinueButtonProps) => (
|
||||||
<StyledFooter>
|
<StyledFooter>
|
||||||
<StyledButton
|
<StyledButton
|
||||||
icon={isLoading && <CircularProgressBar size={16} barWidth={2} />}
|
Icon={isLoading ? CircularProgressBar : undefined}
|
||||||
title={title}
|
title={title}
|
||||||
onClick={!isLoading ? onContinue : undefined}
|
onClick={!isLoading ? onContinue : undefined}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -52,7 +52,7 @@ export const ModalCloseButton = ({ onClose }: ModalCloseButtonProps) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledCloseButtonContainer>
|
<StyledCloseButtonContainer>
|
||||||
<IconButton icon={<IconX />} onClick={handleClose} />
|
<IconButton Icon={IconX} onClick={handleClose} />
|
||||||
</StyledCloseButtonContainer>
|
</StyledCloseButtonContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -205,7 +205,7 @@ export const ValidationStep = <T extends string>({
|
|||||||
</StyledErrorToggleDescription>
|
</StyledErrorToggleDescription>
|
||||||
</StyledErrorToggle>
|
</StyledErrorToggle>
|
||||||
<Button
|
<Button
|
||||||
icon={<IconTrash />}
|
Icon={IconTrash}
|
||||||
title="Remove"
|
title="Remove"
|
||||||
accent="danger"
|
accent="danger"
|
||||||
onClick={deleteSelectedRows}
|
onClick={deleteSelectedRows}
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
import { ReactNode } from 'react';
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
icon: ReactNode;
|
Icon: IconComponent;
|
||||||
label: string;
|
label: string;
|
||||||
type?: 'standard' | 'danger';
|
type?: 'standard' | 'danger';
|
||||||
onClick: () => void;
|
onClick: () => void;
|
||||||
@ -39,13 +41,14 @@ const StyledButtonLabel = styled.div`
|
|||||||
|
|
||||||
export function ActionBarEntry({
|
export function ActionBarEntry({
|
||||||
label,
|
label,
|
||||||
icon,
|
Icon,
|
||||||
type = 'standard',
|
type = 'standard',
|
||||||
onClick,
|
onClick,
|
||||||
}: OwnProps) {
|
}: OwnProps) {
|
||||||
|
const theme = useTheme();
|
||||||
return (
|
return (
|
||||||
<StyledButton type={type} onClick={onClick}>
|
<StyledButton type={type} onClick={onClick}>
|
||||||
{icon}
|
{Icon && <Icon size={theme.icon.size.md} />}
|
||||||
<StyledButtonLabel>{label}</StyledButtonLabel>
|
<StyledButtonLabel>{label}</StyledButtonLabel>
|
||||||
</StyledButton>
|
</StyledButton>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -16,7 +16,7 @@ export function useBoardActionBarEntries() {
|
|||||||
setActionBarEntries([
|
setActionBarEntries([
|
||||||
<ActionBarEntry
|
<ActionBarEntry
|
||||||
label="Delete"
|
label="Delete"
|
||||||
icon={<IconTrash size={16} />}
|
Icon={IconTrash}
|
||||||
type="danger"
|
type="danger"
|
||||||
onClick={deleteSelectedBoardCards}
|
onClick={deleteSelectedBoardCards}
|
||||||
key="delete"
|
key="delete"
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React from 'react';
|
||||||
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { TablerIconsProps } from '@/ui/icon';
|
import { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
import { SoonPill } from '@/ui/pill/components/SoonPill';
|
import { SoonPill } from '@/ui/pill/components/SoonPill';
|
||||||
|
|
||||||
export type ButtonSize = 'medium' | 'small';
|
export type ButtonSize = 'medium' | 'small';
|
||||||
@ -11,7 +12,7 @@ export type ButtonAccent = 'default' | 'blue' | 'danger';
|
|||||||
|
|
||||||
export type ButtonProps = {
|
export type ButtonProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
icon?: React.ReactNode;
|
Icon?: IconComponent;
|
||||||
title?: string;
|
title?: string;
|
||||||
fullWidth?: boolean;
|
fullWidth?: boolean;
|
||||||
variant?: ButtonVariant;
|
variant?: ButtonVariant;
|
||||||
@ -278,7 +279,7 @@ const StyledButton = styled.button<
|
|||||||
|
|
||||||
export function Button({
|
export function Button({
|
||||||
className,
|
className,
|
||||||
icon: initialIcon,
|
Icon,
|
||||||
title,
|
title,
|
||||||
fullWidth = false,
|
fullWidth = false,
|
||||||
variant = 'primary',
|
variant = 'primary',
|
||||||
@ -290,15 +291,7 @@ export function Button({
|
|||||||
focus = false,
|
focus = false,
|
||||||
onClick,
|
onClick,
|
||||||
}: ButtonProps) {
|
}: ButtonProps) {
|
||||||
const icon = useMemo(() => {
|
const theme = useTheme();
|
||||||
if (!initialIcon || !React.isValidElement(initialIcon)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return React.cloneElement<TablerIconsProps>(initialIcon as any, {
|
|
||||||
size: 14,
|
|
||||||
});
|
|
||||||
}, [initialIcon]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledButton
|
<StyledButton
|
||||||
@ -312,7 +305,7 @@ export function Button({
|
|||||||
className={className}
|
className={className}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
{icon}
|
{Icon && <Icon size={theme.icon.size.sm} />}
|
||||||
{title}
|
{title}
|
||||||
{soon && <SoonPill />}
|
{soon && <SoonPill />}
|
||||||
</StyledButton>
|
</StyledButton>
|
||||||
|
|||||||
@ -1,14 +1,15 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React from 'react';
|
||||||
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { TablerIconsProps } from '@/ui/icon';
|
import { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
|
|
||||||
export type FloatingButtonSize = 'small' | 'medium';
|
export type FloatingButtonSize = 'small' | 'medium';
|
||||||
export type FloatingButtonPosition = 'standalone' | 'left' | 'middle' | 'right';
|
export type FloatingButtonPosition = 'standalone' | 'left' | 'middle' | 'right';
|
||||||
|
|
||||||
export type FloatingButtonProps = {
|
export type FloatingButtonProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
icon?: React.ReactNode;
|
Icon?: IconComponent;
|
||||||
title?: string;
|
title?: string;
|
||||||
size?: FloatingButtonSize;
|
size?: FloatingButtonSize;
|
||||||
position?: FloatingButtonPosition;
|
position?: FloatingButtonPosition;
|
||||||
@ -80,7 +81,7 @@ const StyledButton = styled.button<
|
|||||||
|
|
||||||
export function FloatingButton({
|
export function FloatingButton({
|
||||||
className,
|
className,
|
||||||
icon: initialIcon,
|
Icon,
|
||||||
title,
|
title,
|
||||||
size = 'small',
|
size = 'small',
|
||||||
applyBlur = true,
|
applyBlur = true,
|
||||||
@ -88,16 +89,7 @@ export function FloatingButton({
|
|||||||
disabled = false,
|
disabled = false,
|
||||||
focus = false,
|
focus = false,
|
||||||
}: FloatingButtonProps) {
|
}: FloatingButtonProps) {
|
||||||
const icon = useMemo(() => {
|
const theme = useTheme();
|
||||||
if (!initialIcon || !React.isValidElement(initialIcon)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return React.cloneElement<TablerIconsProps>(initialIcon as any, {
|
|
||||||
size: 14,
|
|
||||||
});
|
|
||||||
}, [initialIcon]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledButton
|
<StyledButton
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
@ -107,7 +99,7 @@ export function FloatingButton({
|
|||||||
applyShadow={applyShadow}
|
applyShadow={applyShadow}
|
||||||
className={className}
|
className={className}
|
||||||
>
|
>
|
||||||
{icon}
|
{Icon && <Icon size={theme.icon.size.sm} />}
|
||||||
{title}
|
{title}
|
||||||
</StyledButton>
|
</StyledButton>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React from 'react';
|
||||||
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { TablerIconsProps } from '@/ui/icon';
|
import { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
|
|
||||||
export type FloatingIconButtonSize = 'small' | 'medium';
|
export type FloatingIconButtonSize = 'small' | 'medium';
|
||||||
export type FloatingIconButtonPosition =
|
export type FloatingIconButtonPosition =
|
||||||
@ -12,7 +13,7 @@ export type FloatingIconButtonPosition =
|
|||||||
|
|
||||||
export type FloatingIconButtonProps = {
|
export type FloatingIconButtonProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
icon?: React.ReactNode;
|
Icon?: IconComponent;
|
||||||
size?: FloatingIconButtonSize;
|
size?: FloatingIconButtonSize;
|
||||||
position?: FloatingIconButtonPosition;
|
position?: FloatingIconButtonPosition;
|
||||||
applyShadow?: boolean;
|
applyShadow?: boolean;
|
||||||
@ -100,7 +101,7 @@ const StyledButton = styled.button<
|
|||||||
|
|
||||||
export function FloatingIconButton({
|
export function FloatingIconButton({
|
||||||
className,
|
className,
|
||||||
icon: initialIcon,
|
Icon,
|
||||||
size = 'small',
|
size = 'small',
|
||||||
position = 'standalone',
|
position = 'standalone',
|
||||||
applyShadow = true,
|
applyShadow = true,
|
||||||
@ -109,16 +110,7 @@ export function FloatingIconButton({
|
|||||||
focus = false,
|
focus = false,
|
||||||
onClick,
|
onClick,
|
||||||
}: FloatingIconButtonProps) {
|
}: FloatingIconButtonProps) {
|
||||||
const icon = useMemo(() => {
|
const theme = useTheme();
|
||||||
if (!initialIcon || !React.isValidElement(initialIcon)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return React.cloneElement<TablerIconsProps>(initialIcon as any, {
|
|
||||||
size: 16,
|
|
||||||
});
|
|
||||||
}, [initialIcon]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledButton
|
<StyledButton
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
@ -130,7 +122,7 @@ export function FloatingIconButton({
|
|||||||
position={position}
|
position={position}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
{icon}
|
{Icon && <Icon size={theme.icon.size.md} />}
|
||||||
</StyledButton>
|
</StyledButton>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import type { MouseEvent } from 'react';
|
import type { MouseEvent } from 'react';
|
||||||
import { useTheme } from '@emotion/react';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import type { IconComponent } from '@/ui/icon/types/IconComponent';
|
import type { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
@ -34,8 +33,6 @@ export function FloatingIconButtonGroup({
|
|||||||
iconButtons,
|
iconButtons,
|
||||||
size,
|
size,
|
||||||
}: FloatingIconButtonGroupProps) {
|
}: FloatingIconButtonGroupProps) {
|
||||||
const theme = useTheme();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledFloatingIconButtonGroupContainer>
|
<StyledFloatingIconButtonGroupContainer>
|
||||||
{iconButtons.map(({ Icon, onClick }, index) => {
|
{iconButtons.map(({ Icon, onClick }, index) => {
|
||||||
@ -50,7 +47,7 @@ export function FloatingIconButtonGroup({
|
|||||||
<FloatingIconButton
|
<FloatingIconButton
|
||||||
applyBlur={false}
|
applyBlur={false}
|
||||||
applyShadow={false}
|
applyShadow={false}
|
||||||
icon={<Icon size={theme.icon.size.sm} />}
|
Icon={Icon}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
position={position}
|
position={position}
|
||||||
size={size}
|
size={size}
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import React, { useMemo } from 'react';
|
import React from 'react';
|
||||||
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { TablerIconsProps } from '@/ui/icon';
|
import { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
|
|
||||||
export type IconButtonSize = 'medium' | 'small';
|
export type IconButtonSize = 'medium' | 'small';
|
||||||
export type IconButtonPosition = 'standalone' | 'left' | 'middle' | 'right';
|
export type IconButtonPosition = 'standalone' | 'left' | 'middle' | 'right';
|
||||||
@ -10,7 +11,7 @@ export type IconButtonAccent = 'default' | 'blue' | 'danger';
|
|||||||
|
|
||||||
export type IconButtonProps = {
|
export type IconButtonProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
icon?: React.ReactNode;
|
Icon?: IconComponent;
|
||||||
variant?: IconButtonVariant;
|
variant?: IconButtonVariant;
|
||||||
size?: IconButtonSize;
|
size?: IconButtonSize;
|
||||||
position?: IconButtonPosition;
|
position?: IconButtonPosition;
|
||||||
@ -270,7 +271,7 @@ const StyledButton = styled.button<
|
|||||||
|
|
||||||
export function IconButton({
|
export function IconButton({
|
||||||
className,
|
className,
|
||||||
icon: initialIcon,
|
Icon,
|
||||||
variant = 'primary',
|
variant = 'primary',
|
||||||
size = 'medium',
|
size = 'medium',
|
||||||
accent = 'default',
|
accent = 'default',
|
||||||
@ -280,16 +281,7 @@ export function IconButton({
|
|||||||
dataTestId,
|
dataTestId,
|
||||||
onClick,
|
onClick,
|
||||||
}: IconButtonProps) {
|
}: IconButtonProps) {
|
||||||
const icon = useMemo(() => {
|
const theme = useTheme();
|
||||||
if (!initialIcon || !React.isValidElement(initialIcon)) {
|
|
||||||
return <></>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return React.cloneElement<TablerIconsProps>(initialIcon as any, {
|
|
||||||
size: 16,
|
|
||||||
});
|
|
||||||
}, [initialIcon]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledButton
|
<StyledButton
|
||||||
data-testid={dataTestId}
|
data-testid={dataTestId}
|
||||||
@ -302,7 +294,7 @@ export function IconButton({
|
|||||||
className={className}
|
className={className}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
{icon}
|
{Icon && <Icon size={theme.icon.size.md} />}
|
||||||
</StyledButton>
|
</StyledButton>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,13 @@
|
|||||||
import type { MouseEvent } from 'react';
|
import type { MouseEvent } from 'react';
|
||||||
import { useTheme } from '@emotion/react';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import type { IconComponent } from '@/ui/icon/types/IconComponent';
|
import type { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
|
|
||||||
import { Button } from './Button';
|
import {
|
||||||
import { IconButtonPosition, type IconButtonProps } from './IconButton';
|
IconButton,
|
||||||
|
IconButtonPosition,
|
||||||
|
type IconButtonProps,
|
||||||
|
} from './IconButton';
|
||||||
|
|
||||||
const StyledIconButtonGroupContainer = styled.div`
|
const StyledIconButtonGroupContainer = styled.div`
|
||||||
border-radius: ${({ theme }) => theme.border.radius.md};
|
border-radius: ${({ theme }) => theme.border.radius.md};
|
||||||
@ -28,8 +30,6 @@ export function IconButtonGroup({
|
|||||||
size,
|
size,
|
||||||
variant,
|
variant,
|
||||||
}: IconButtonGroupProps) {
|
}: IconButtonGroupProps) {
|
||||||
const theme = useTheme();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledIconButtonGroupContainer>
|
<StyledIconButtonGroupContainer>
|
||||||
{iconButtons.map(({ Icon, onClick }, index) => {
|
{iconButtons.map(({ Icon, onClick }, index) => {
|
||||||
@ -41,9 +41,9 @@ export function IconButtonGroup({
|
|||||||
: 'middle';
|
: 'middle';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<IconButton
|
||||||
accent={accent}
|
accent={accent}
|
||||||
icon={<Icon size={theme.icon.size.sm} />}
|
Icon={Icon}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
position={position}
|
position={position}
|
||||||
size={size}
|
size={size}
|
||||||
|
|||||||
@ -1,14 +1,15 @@
|
|||||||
import React, { MouseEvent, useMemo } from 'react';
|
import React, { MouseEvent } from 'react';
|
||||||
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { TablerIconsProps } from '@/ui/icon';
|
import { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
|
|
||||||
export type LightIconButtonAccent = 'secondary' | 'tertiary';
|
export type LightIconButtonAccent = 'secondary' | 'tertiary';
|
||||||
export type LightIconButtonSize = 'small' | 'medium';
|
export type LightIconButtonSize = 'small' | 'medium';
|
||||||
|
|
||||||
export type LightIconButtonProps = {
|
export type LightIconButtonProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
icon?: React.ReactNode;
|
Icon?: IconComponent;
|
||||||
title?: string;
|
title?: string;
|
||||||
size?: LightIconButtonSize;
|
size?: LightIconButtonSize;
|
||||||
accent?: LightIconButtonAccent;
|
accent?: LightIconButtonAccent;
|
||||||
@ -79,7 +80,7 @@ const StyledButton = styled.button<
|
|||||||
|
|
||||||
export function LightIconButton({
|
export function LightIconButton({
|
||||||
className,
|
className,
|
||||||
icon: initialIcon,
|
Icon,
|
||||||
active = false,
|
active = false,
|
||||||
size = 'small',
|
size = 'small',
|
||||||
accent = 'secondary',
|
accent = 'secondary',
|
||||||
@ -87,16 +88,7 @@ export function LightIconButton({
|
|||||||
focus = false,
|
focus = false,
|
||||||
onClick,
|
onClick,
|
||||||
}: LightIconButtonProps) {
|
}: LightIconButtonProps) {
|
||||||
const icon = useMemo(() => {
|
const theme = useTheme();
|
||||||
if (!initialIcon || !React.isValidElement(initialIcon)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return React.cloneElement<TablerIconsProps>(initialIcon as any, {
|
|
||||||
size: 16,
|
|
||||||
});
|
|
||||||
}, [initialIcon]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledButton
|
<StyledButton
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
@ -107,7 +99,7 @@ export function LightIconButton({
|
|||||||
size={size}
|
size={size}
|
||||||
active={active}
|
active={active}
|
||||||
>
|
>
|
||||||
{icon}
|
{Icon && <Icon size={theme.icon.size.md} />}
|
||||||
</StyledButton>
|
</StyledButton>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
|
|
||||||
type Variant = 'primary' | 'secondary';
|
type Variant = 'primary' | 'secondary';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
icon?: React.ReactNode;
|
|
||||||
title: string;
|
title: string;
|
||||||
fullWidth?: boolean;
|
fullWidth?: boolean;
|
||||||
variant?: Variant;
|
variant?: Variant;
|
||||||
@ -85,16 +87,21 @@ const StyledButton = styled.button<Pick<Props, 'fullWidth' | 'variant'>>`
|
|||||||
}};
|
}};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
type MainButtonProps = Props & {
|
||||||
|
Icon?: IconComponent;
|
||||||
|
};
|
||||||
|
|
||||||
export function MainButton({
|
export function MainButton({
|
||||||
icon,
|
Icon,
|
||||||
title,
|
title,
|
||||||
fullWidth = false,
|
fullWidth = false,
|
||||||
variant = 'primary',
|
variant = 'primary',
|
||||||
...props
|
...props
|
||||||
}: Props) {
|
}: MainButtonProps) {
|
||||||
|
const theme = useTheme();
|
||||||
return (
|
return (
|
||||||
<StyledButton fullWidth={fullWidth} variant={variant} {...props}>
|
<StyledButton fullWidth={fullWidth} variant={variant} {...props}>
|
||||||
{icon}
|
{Icon && <Icon size={theme.icon.size.sm} />}
|
||||||
{title}
|
{title}
|
||||||
</StyledButton>
|
</StyledButton>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
|
|
||||||
const StyledIconButton = styled.button`
|
const StyledIconButton = styled.button`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background: ${({ theme }) => theme.color.blue};
|
background: ${({ theme }) => theme.color.blue};
|
||||||
@ -26,9 +29,16 @@ const StyledIconButton = styled.button`
|
|||||||
width: 20px;
|
width: 20px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export function RoundedIconButton({
|
type RoundedIconButtonProps = {
|
||||||
icon,
|
Icon: IconComponent;
|
||||||
...props
|
} & React.ButtonHTMLAttributes<HTMLButtonElement>;
|
||||||
}: { icon: React.ReactNode } & React.ButtonHTMLAttributes<HTMLButtonElement>) {
|
|
||||||
return <StyledIconButton {...props}>{icon}</StyledIconButton>;
|
export function RoundedIconButton({ Icon, ...props }: RoundedIconButtonProps) {
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledIconButton {...props}>
|
||||||
|
{<Icon size={theme.icon.size.md} />}
|
||||||
|
</StyledIconButton>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,14 +31,14 @@ export const Default: Story = {
|
|||||||
fullWidth: false,
|
fullWidth: false,
|
||||||
soon: false,
|
soon: false,
|
||||||
position: 'standalone',
|
position: 'standalone',
|
||||||
icon: <IconSearch />,
|
Icon: IconSearch,
|
||||||
className: '',
|
className: '',
|
||||||
},
|
},
|
||||||
decorators: [ComponentDecorator],
|
decorators: [ComponentDecorator],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Catalog: Story = {
|
export const Catalog: Story = {
|
||||||
args: { title: 'Filter', icon: <IconSearch /> },
|
args: { title: 'Filter', Icon: IconSearch },
|
||||||
argTypes: {
|
argTypes: {
|
||||||
size: { control: false },
|
size: { control: false },
|
||||||
variant: { control: false },
|
variant: { control: false },
|
||||||
@ -110,7 +110,7 @@ export const Catalog: Story = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const SoonCatalog: Story = {
|
export const SoonCatalog: Story = {
|
||||||
args: { title: 'Filter', icon: <IconSearch />, soon: true },
|
args: { title: 'Filter', Icon: IconSearch, soon: true },
|
||||||
argTypes: {
|
argTypes: {
|
||||||
size: { control: false },
|
size: { control: false },
|
||||||
variant: { control: false },
|
variant: { control: false },
|
||||||
@ -182,7 +182,7 @@ export const SoonCatalog: Story = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const PositionCatalog: Story = {
|
export const PositionCatalog: Story = {
|
||||||
args: { title: 'Filter', icon: <IconSearch /> },
|
args: { title: 'Filter', Icon: IconSearch },
|
||||||
argTypes: {
|
argTypes: {
|
||||||
size: { control: false },
|
size: { control: false },
|
||||||
variant: { control: false },
|
variant: { control: false },
|
||||||
@ -258,7 +258,7 @@ export const PositionCatalog: Story = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const FullWidth: Story = {
|
export const FullWidth: Story = {
|
||||||
args: { title: 'Filter', icon: <IconSearch />, fullWidth: true },
|
args: { title: 'Filter', Icon: IconSearch, fullWidth: true },
|
||||||
argTypes: {
|
argTypes: {
|
||||||
size: { control: false },
|
size: { control: false },
|
||||||
variant: { control: false },
|
variant: { control: false },
|
||||||
@ -269,7 +269,7 @@ export const FullWidth: Story = {
|
|||||||
soon: { control: false },
|
soon: { control: false },
|
||||||
position: { control: false },
|
position: { control: false },
|
||||||
className: { control: false },
|
className: { control: false },
|
||||||
icon: { control: false },
|
Icon: { control: false },
|
||||||
},
|
},
|
||||||
decorators: [ComponentDecorator],
|
decorators: [ComponentDecorator],
|
||||||
};
|
};
|
||||||
|
|||||||
@ -21,9 +21,9 @@ export const Default: Story = {
|
|||||||
variant: 'primary',
|
variant: 'primary',
|
||||||
accent: 'danger',
|
accent: 'danger',
|
||||||
children: [
|
children: [
|
||||||
<Button icon={<IconNotes />} title="Note" />,
|
<Button Icon={IconNotes} title="Note" />,
|
||||||
<Button icon={<IconCheckbox />} title="Task" />,
|
<Button Icon={IconCheckbox} title="Task" />,
|
||||||
<Button icon={<IconTimelineEvent />} title="Activity" />,
|
<Button Icon={IconTimelineEvent} title="Activity" />,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
argTypes: {
|
argTypes: {
|
||||||
@ -35,9 +35,9 @@ export const Default: Story = {
|
|||||||
export const Catalog: Story = {
|
export const Catalog: Story = {
|
||||||
args: {
|
args: {
|
||||||
children: [
|
children: [
|
||||||
<Button icon={<IconNotes />} title="Note" />,
|
<Button Icon={IconNotes} title="Note" />,
|
||||||
<Button icon={<IconCheckbox />} title="Task" />,
|
<Button Icon={IconCheckbox} title="Task" />,
|
||||||
<Button icon={<IconTimelineEvent />} title="Activity" />,
|
<Button Icon={IconTimelineEvent} title="Activity" />,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
argTypes: {
|
argTypes: {
|
||||||
|
|||||||
@ -23,16 +23,16 @@ export const Default: Story = {
|
|||||||
applyBlur: true,
|
applyBlur: true,
|
||||||
applyShadow: true,
|
applyShadow: true,
|
||||||
position: 'standalone',
|
position: 'standalone',
|
||||||
icon: <IconSearch />,
|
Icon: IconSearch,
|
||||||
},
|
},
|
||||||
argTypes: {
|
argTypes: {
|
||||||
icon: { control: false },
|
Icon: { control: false },
|
||||||
},
|
},
|
||||||
decorators: [ComponentDecorator],
|
decorators: [ComponentDecorator],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Catalog: Story = {
|
export const Catalog: Story = {
|
||||||
args: { title: 'Filter', icon: <IconSearch /> },
|
args: { title: 'Filter', Icon: IconSearch },
|
||||||
argTypes: {
|
argTypes: {
|
||||||
size: { control: false },
|
size: { control: false },
|
||||||
disabled: { control: false },
|
disabled: { control: false },
|
||||||
|
|||||||
@ -19,9 +19,9 @@ export const Default: Story = {
|
|||||||
args: {
|
args: {
|
||||||
size: 'small',
|
size: 'small',
|
||||||
children: [
|
children: [
|
||||||
<FloatingButton icon={<IconNotes />} />,
|
<FloatingButton Icon={IconNotes} />,
|
||||||
<FloatingButton icon={<IconCheckbox />} />,
|
<FloatingButton Icon={IconCheckbox} />,
|
||||||
<FloatingButton icon={<IconTimelineEvent />} />,
|
<FloatingButton Icon={IconTimelineEvent} />,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
argTypes: {
|
argTypes: {
|
||||||
@ -33,9 +33,9 @@ export const Default: Story = {
|
|||||||
export const Catalog: Story = {
|
export const Catalog: Story = {
|
||||||
args: {
|
args: {
|
||||||
children: [
|
children: [
|
||||||
<FloatingButton icon={<IconNotes />} />,
|
<FloatingButton Icon={IconNotes} />,
|
||||||
<FloatingButton icon={<IconCheckbox />} />,
|
<FloatingButton Icon={IconCheckbox} />,
|
||||||
<FloatingButton icon={<IconTimelineEvent />} />,
|
<FloatingButton Icon={IconTimelineEvent} />,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
argTypes: {
|
argTypes: {
|
||||||
|
|||||||
@ -25,16 +25,16 @@ export const Default: Story = {
|
|||||||
applyBlur: true,
|
applyBlur: true,
|
||||||
applyShadow: true,
|
applyShadow: true,
|
||||||
position: 'standalone',
|
position: 'standalone',
|
||||||
icon: <IconSearch />,
|
Icon: IconSearch,
|
||||||
},
|
},
|
||||||
argTypes: {
|
argTypes: {
|
||||||
icon: { control: false },
|
Icon: { control: false },
|
||||||
},
|
},
|
||||||
decorators: [ComponentDecorator],
|
decorators: [ComponentDecorator],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Catalog: Story = {
|
export const Catalog: Story = {
|
||||||
args: { icon: <IconSearch /> },
|
args: { Icon: IconSearch },
|
||||||
argTypes: {
|
argTypes: {
|
||||||
size: { control: false },
|
size: { control: false },
|
||||||
disabled: { control: false },
|
disabled: { control: false },
|
||||||
|
|||||||
@ -28,20 +28,20 @@ export const Default: Story = {
|
|||||||
disabled: false,
|
disabled: false,
|
||||||
focus: false,
|
focus: false,
|
||||||
position: 'standalone',
|
position: 'standalone',
|
||||||
icon: <IconSearch />,
|
Icon: IconSearch,
|
||||||
},
|
},
|
||||||
decorators: [ComponentDecorator],
|
decorators: [ComponentDecorator],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Catalog: Story = {
|
export const Catalog: Story = {
|
||||||
args: { icon: <IconSearch /> },
|
args: { Icon: IconSearch },
|
||||||
argTypes: {
|
argTypes: {
|
||||||
size: { control: false },
|
size: { control: false },
|
||||||
variant: { control: false },
|
variant: { control: false },
|
||||||
focus: { control: false },
|
focus: { control: false },
|
||||||
accent: { control: false },
|
accent: { control: false },
|
||||||
disabled: { control: false },
|
disabled: { control: false },
|
||||||
icon: { control: false },
|
Icon: { control: false },
|
||||||
position: { control: false },
|
position: { control: false },
|
||||||
},
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
@ -104,7 +104,7 @@ export const Catalog: Story = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const PositionCatalog: Story = {
|
export const PositionCatalog: Story = {
|
||||||
args: { icon: <IconSearch /> },
|
args: { Icon: IconSearch },
|
||||||
argTypes: {
|
argTypes: {
|
||||||
size: { control: false },
|
size: { control: false },
|
||||||
variant: { control: false },
|
variant: { control: false },
|
||||||
@ -112,7 +112,7 @@ export const PositionCatalog: Story = {
|
|||||||
accent: { control: false },
|
accent: { control: false },
|
||||||
disabled: { control: false },
|
disabled: { control: false },
|
||||||
position: { control: false },
|
position: { control: false },
|
||||||
icon: { control: false },
|
Icon: { control: false },
|
||||||
},
|
},
|
||||||
parameters: {
|
parameters: {
|
||||||
pseudo: { hover: ['.hover'], active: ['.pressed'] },
|
pseudo: { hover: ['.hover'], active: ['.pressed'] },
|
||||||
|
|||||||
@ -25,16 +25,16 @@ export const Default: Story = {
|
|||||||
disabled: false,
|
disabled: false,
|
||||||
active: false,
|
active: false,
|
||||||
focus: false,
|
focus: false,
|
||||||
icon: <IconSearch />,
|
Icon: IconSearch,
|
||||||
},
|
},
|
||||||
argTypes: {
|
argTypes: {
|
||||||
icon: { control: false },
|
Icon: { control: false },
|
||||||
},
|
},
|
||||||
decorators: [ComponentDecorator],
|
decorators: [ComponentDecorator],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Catalog: Story = {
|
export const Catalog: Story = {
|
||||||
args: { title: 'Filter', icon: <IconSearch /> },
|
args: { title: 'Filter', Icon: IconSearch },
|
||||||
argTypes: {
|
argTypes: {
|
||||||
accent: { control: false },
|
accent: { control: false },
|
||||||
disabled: { control: false },
|
disabled: { control: false },
|
||||||
|
|||||||
@ -13,15 +13,6 @@ const meta: Meta<typeof MainButton> = {
|
|||||||
title: 'UI/Button/MainButton',
|
title: 'UI/Button/MainButton',
|
||||||
component: MainButton,
|
component: MainButton,
|
||||||
decorators: [ComponentDecorator],
|
decorators: [ComponentDecorator],
|
||||||
argTypes: {
|
|
||||||
icon: {
|
|
||||||
type: 'boolean',
|
|
||||||
mapping: {
|
|
||||||
true: <IconBrandGoogle size={16} stroke={4} />,
|
|
||||||
false: undefined,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
args: { title: 'A primary Button', onClick: clickJestFn },
|
args: { title: 'A primary Button', onClick: clickJestFn },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -41,7 +32,7 @@ export const Default: Story = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const WithIcon: Story = {
|
export const WithIcon: Story = {
|
||||||
args: { icon: true },
|
args: { Icon: IconBrandGoogle },
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DisabledWithIcon: Story = {
|
export const DisabledWithIcon: Story = {
|
||||||
|
|||||||
@ -19,8 +19,8 @@ type Story = StoryObj<typeof RoundedIconButton>;
|
|||||||
|
|
||||||
export const Default: Story = {
|
export const Default: Story = {
|
||||||
decorators: [ComponentDecorator],
|
decorators: [ComponentDecorator],
|
||||||
argTypes: { icon: { control: false } },
|
argTypes: { Icon: { control: false } },
|
||||||
args: { onClick: clickJestFn, icon: <IconArrowRight size={15} /> },
|
args: { onClick: clickJestFn, Icon: IconArrowRight },
|
||||||
play: async ({ canvasElement }) => {
|
play: async ({ canvasElement }) => {
|
||||||
const canvas = within(canvasElement);
|
const canvas = within(canvasElement);
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ export function EditableFieldEditButton() {
|
|||||||
<FloatingIconButton
|
<FloatingIconButton
|
||||||
size="small"
|
size="small"
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
icon={<IconPencil />}
|
Icon={IconPencil}
|
||||||
data-testid="editable-field-edit-mode-container"
|
data-testid="editable-field-edit-mode-container"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -198,7 +198,7 @@ export function AutosizeTextInput({
|
|||||||
<StyledBottomRightRoundedIconButton>
|
<StyledBottomRightRoundedIconButton>
|
||||||
<RoundedIconButton
|
<RoundedIconButton
|
||||||
onClick={handleOnClickSendButton}
|
onClick={handleOnClickSendButton}
|
||||||
icon={<IconArrowRight size={15} />}
|
Icon={IconArrowRight}
|
||||||
disabled={isSendButtonDisabled}
|
disabled={isSendButtonDisabled}
|
||||||
/>
|
/>
|
||||||
</StyledBottomRightRoundedIconButton>
|
</StyledBottomRightRoundedIconButton>
|
||||||
|
|||||||
@ -135,7 +135,7 @@ export function ImageInput({
|
|||||||
/>
|
/>
|
||||||
{isUploading && onAbort ? (
|
{isUploading && onAbort ? (
|
||||||
<Button
|
<Button
|
||||||
icon={<IconX />}
|
Icon={IconX}
|
||||||
onClick={onAbort}
|
onClick={onAbort}
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
title="Abort"
|
title="Abort"
|
||||||
@ -144,7 +144,7 @@ export function ImageInput({
|
|||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
icon={<IconUpload />}
|
Icon={IconUpload}
|
||||||
onClick={onUploadButtonClick}
|
onClick={onUploadButtonClick}
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
title="Upload"
|
title="Upload"
|
||||||
@ -153,7 +153,7 @@ export function ImageInput({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Button
|
<Button
|
||||||
icon={<IconTrash />}
|
Icon={IconTrash}
|
||||||
onClick={onRemove}
|
onClick={onRemove}
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
title="Remove"
|
title="Remove"
|
||||||
|
|||||||
@ -8,7 +8,7 @@ type OwnProps = {
|
|||||||
export function PageAddButton({ onClick }: OwnProps) {
|
export function PageAddButton({ onClick }: OwnProps) {
|
||||||
return (
|
return (
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<IconPlus size={16} />}
|
Icon={IconPlus}
|
||||||
size="medium"
|
size="medium"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
data-testid="add-button"
|
data-testid="add-button"
|
||||||
|
|||||||
@ -9,7 +9,7 @@ type OwnProps = {
|
|||||||
export function PageFavoriteButton({ isFavorite, onClick }: OwnProps) {
|
export function PageFavoriteButton({ isFavorite, onClick }: OwnProps) {
|
||||||
return (
|
return (
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<IconHeart size={16} />}
|
Icon={IconHeart}
|
||||||
size="medium"
|
size="medium"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
data-testid="add-button"
|
data-testid="add-button"
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
import { type ComponentProps, type ReactNode, useCallback } from 'react';
|
import { type ComponentProps, useCallback } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { IconButton } from '@/ui/button/components/IconButton';
|
import { IconButton, IconButtonSize } from '@/ui/button/components/IconButton';
|
||||||
import { IconChevronLeft } from '@/ui/icon/index';
|
import { IconChevronLeft } from '@/ui/icon/index';
|
||||||
|
import { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
import NavCollapseButton from '@/ui/navbar/components/NavCollapseButton';
|
import NavCollapseButton from '@/ui/navbar/components/NavCollapseButton';
|
||||||
import { navbarIconSize } from '@/ui/navbar/constants';
|
|
||||||
import { OverflowingTextWithTooltip } from '@/ui/tooltip/OverflowingTextWithTooltip';
|
import { OverflowingTextWithTooltip } from '@/ui/tooltip/OverflowingTextWithTooltip';
|
||||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||||
|
|
||||||
@ -63,28 +64,27 @@ const StyledPageActionContainer = styled.div`
|
|||||||
gap: ${({ theme }) => theme.spacing(2)};
|
gap: ${({ theme }) => theme.spacing(2)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
type OwnProps = ComponentProps<'div'> & {
|
type PageHeaderProps = ComponentProps<'div'> & {
|
||||||
title: string;
|
title: string;
|
||||||
hasBackButton?: boolean;
|
hasBackButton?: boolean;
|
||||||
icon: ReactNode;
|
Icon: IconComponent;
|
||||||
children?: JSX.Element | JSX.Element[];
|
children?: JSX.Element | JSX.Element[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export function PageHeader({
|
export function PageHeader({
|
||||||
title,
|
title,
|
||||||
hasBackButton,
|
hasBackButton,
|
||||||
icon,
|
Icon,
|
||||||
children,
|
children,
|
||||||
...props
|
...props
|
||||||
}: OwnProps) {
|
}: PageHeaderProps) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const navigateBack = useCallback(() => navigate(-1), [navigate]);
|
const navigateBack = useCallback(() => navigate(-1), [navigate]);
|
||||||
|
|
||||||
const isNavbarOpened = useRecoilValue(isNavbarOpenedState);
|
const isNavbarOpened = useRecoilValue(isNavbarOpenedState);
|
||||||
|
|
||||||
const iconSize = useIsMobile()
|
const iconSize: IconButtonSize = useIsMobile() ? 'small' : 'medium';
|
||||||
? navbarIconSize.mobile
|
const theme = useTheme();
|
||||||
: navbarIconSize.desktop;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledTopBarContainer {...props}>
|
<StyledTopBarContainer {...props}>
|
||||||
@ -97,14 +97,15 @@ export function PageHeader({
|
|||||||
{hasBackButton && (
|
{hasBackButton && (
|
||||||
<StyledTopBarButtonContainer>
|
<StyledTopBarButtonContainer>
|
||||||
<StyledBackIconButton
|
<StyledBackIconButton
|
||||||
icon={<IconChevronLeft size={iconSize} />}
|
Icon={IconChevronLeft}
|
||||||
|
size={iconSize}
|
||||||
onClick={navigateBack}
|
onClick={navigateBack}
|
||||||
variant="tertiary"
|
variant="tertiary"
|
||||||
/>
|
/>
|
||||||
</StyledTopBarButtonContainer>
|
</StyledTopBarButtonContainer>
|
||||||
)}
|
)}
|
||||||
<StyledTopBarIconStyledTitleContainer>
|
<StyledTopBarIconStyledTitleContainer>
|
||||||
{icon}
|
{Icon && <Icon size={theme.icon.size.md} />}
|
||||||
<StyledTitleContainer data-testid="top-bar-title">
|
<StyledTitleContainer data-testid="top-bar-title">
|
||||||
<OverflowingTextWithTooltip text={title} />
|
<OverflowingTextWithTooltip text={title} />
|
||||||
</StyledTitleContainer>
|
</StyledTitleContainer>
|
||||||
|
|||||||
@ -1,14 +1,16 @@
|
|||||||
|
import { JSX } from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||||
|
|
||||||
import { PageHeader } from './PageHeader';
|
import { PageHeader } from './PageHeader';
|
||||||
import { RightDrawerContainer } from './RightDrawerContainer';
|
import { RightDrawerContainer } from './RightDrawerContainer';
|
||||||
|
|
||||||
type OwnProps = {
|
type SubMenuTopBarContainerProps = {
|
||||||
children: JSX.Element | JSX.Element[];
|
children: JSX.Element | JSX.Element[];
|
||||||
title: string;
|
title: string;
|
||||||
icon: React.ReactNode;
|
Icon: IconComponent;
|
||||||
};
|
};
|
||||||
|
|
||||||
const StyledContainer = styled.div<{ isMobile: boolean }>`
|
const StyledContainer = styled.div<{ isMobile: boolean }>`
|
||||||
@ -18,12 +20,16 @@ const StyledContainer = styled.div<{ isMobile: boolean }>`
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export function SubMenuTopBarContainer({ children, title, icon }: OwnProps) {
|
export function SubMenuTopBarContainer({
|
||||||
|
children,
|
||||||
|
title,
|
||||||
|
Icon,
|
||||||
|
}: SubMenuTopBarContainerProps) {
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledContainer isMobile={isMobile}>
|
<StyledContainer isMobile={isMobile}>
|
||||||
{isMobile && <PageHeader title={title} icon={icon} />}
|
{isMobile && <PageHeader title={title} Icon={Icon} />}
|
||||||
<RightDrawerContainer topMargin={16}>{children}</RightDrawerContainer>
|
<RightDrawerContainer topMargin={16}>{children}</RightDrawerContainer>
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -37,7 +37,7 @@ export function ShowPageAddButton({
|
|||||||
dropdownKey="add-show-page"
|
dropdownKey="add-show-page"
|
||||||
buttonComponents={
|
buttonComponents={
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={<IconPlus size={16} />}
|
Icon={IconPlus}
|
||||||
size="medium"
|
size="medium"
|
||||||
dataTestId="add-showpage-button"
|
dataTestId="add-showpage-button"
|
||||||
accent="default"
|
accent="default"
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { useTheme } from '@emotion/react';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { Notes } from '@/activities/notes/components/Notes';
|
import { Notes } from '@/activities/notes/components/Notes';
|
||||||
@ -53,31 +52,29 @@ export function ShowPageRightContainer({
|
|||||||
notes,
|
notes,
|
||||||
emails,
|
emails,
|
||||||
}: OwnProps) {
|
}: OwnProps) {
|
||||||
const theme = useTheme();
|
|
||||||
|
|
||||||
const TASK_TABS = [
|
const TASK_TABS = [
|
||||||
{
|
{
|
||||||
id: 'timeline',
|
id: 'timeline',
|
||||||
title: 'Timeline',
|
title: 'Timeline',
|
||||||
icon: <IconTimelineEvent size={theme.icon.size.md} />,
|
Icon: IconTimelineEvent,
|
||||||
hide: !timeline,
|
hide: !timeline,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'tasks',
|
id: 'tasks',
|
||||||
title: 'Tasks',
|
title: 'Tasks',
|
||||||
icon: <IconCheckbox size={theme.icon.size.md} />,
|
Icon: IconCheckbox,
|
||||||
hide: !tasks,
|
hide: !tasks,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'notes',
|
id: 'notes',
|
||||||
title: 'Notes',
|
title: 'Notes',
|
||||||
icon: <IconNotes size={theme.icon.size.md} />,
|
Icon: IconNotes,
|
||||||
hide: !notes,
|
hide: !notes,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'emails',
|
id: 'emails',
|
||||||
title: 'Emails',
|
title: 'Emails',
|
||||||
icon: <IconMail size={theme.icon.size.md} />,
|
Icon: IconMail,
|
||||||
hide: !emails,
|
hide: !emails,
|
||||||
disabled: true,
|
disabled: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -40,7 +40,7 @@ export type MenuItemProps = {
|
|||||||
LeftIcon?: IconComponent;
|
LeftIcon?: IconComponent;
|
||||||
text: string;
|
text: string;
|
||||||
command: string;
|
command: string;
|
||||||
className: string;
|
className?: string;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { IconButton } from '@/ui/button/components/IconButton';
|
||||||
import {
|
import {
|
||||||
IconLayoutSidebarLeftCollapse,
|
IconLayoutSidebarLeftCollapse,
|
||||||
IconLayoutSidebarRightCollapse,
|
IconLayoutSidebarRightCollapse,
|
||||||
@ -8,8 +9,6 @@ import {
|
|||||||
import { isNavbarOpenedState } from '@/ui/layout/states/isNavbarOpenedState';
|
import { isNavbarOpenedState } from '@/ui/layout/states/isNavbarOpenedState';
|
||||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||||
|
|
||||||
import { navbarIconSize } from '../constants';
|
|
||||||
|
|
||||||
const StyledCollapseButton = styled.button<{
|
const StyledCollapseButton = styled.button<{
|
||||||
hide: boolean;
|
hide: boolean;
|
||||||
}>`
|
}>`
|
||||||
@ -57,9 +56,7 @@ export default function NavCollapseButton({
|
|||||||
const [isNavbarOpened, setIsNavbarOpened] =
|
const [isNavbarOpened, setIsNavbarOpened] =
|
||||||
useRecoilState(isNavbarOpenedState);
|
useRecoilState(isNavbarOpenedState);
|
||||||
|
|
||||||
const iconSize = useIsMobile()
|
const iconSize = useIsMobile() ? 'small' : 'medium';
|
||||||
? navbarIconSize.mobile
|
|
||||||
: navbarIconSize.desktop;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -68,14 +65,22 @@ export default function NavCollapseButton({
|
|||||||
hide={hide}
|
hide={hide}
|
||||||
onClick={() => setIsNavbarOpened(!isNavbarOpened)}
|
onClick={() => setIsNavbarOpened(!isNavbarOpened)}
|
||||||
>
|
>
|
||||||
<IconLayoutSidebarLeftCollapse size={iconSize} />
|
<IconButton
|
||||||
|
Icon={IconLayoutSidebarLeftCollapse}
|
||||||
|
variant="tertiary"
|
||||||
|
size={iconSize}
|
||||||
|
/>
|
||||||
</StyledCollapseButton>
|
</StyledCollapseButton>
|
||||||
) : (
|
) : (
|
||||||
<StyledCollapseButton
|
<StyledCollapseButton
|
||||||
hide={hide}
|
hide={hide}
|
||||||
onClick={() => setIsNavbarOpened(!isNavbarOpened)}
|
onClick={() => setIsNavbarOpened(!isNavbarOpened)}
|
||||||
>
|
>
|
||||||
<IconLayoutSidebarRightCollapse size={iconSize} />
|
<IconButton
|
||||||
|
Icon={IconLayoutSidebarRightCollapse}
|
||||||
|
variant="tertiary"
|
||||||
|
size={iconSize}
|
||||||
|
/>
|
||||||
</StyledCollapseButton>
|
</StyledCollapseButton>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -1,19 +1,20 @@
|
|||||||
import { ReactNode } from 'react';
|
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
import { MOBILE_VIEWPORT } from '@/ui/theme/constants/theme';
|
import { MOBILE_VIEWPORT } from '@/ui/theme/constants/theme';
|
||||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||||
|
|
||||||
import { isNavbarOpenedState } from '../../layout/states/isNavbarOpenedState';
|
import { isNavbarOpenedState } from '../../layout/states/isNavbarOpenedState';
|
||||||
|
|
||||||
type OwnProps = {
|
type NavItemProps = {
|
||||||
label: string;
|
label: string;
|
||||||
to?: string;
|
to?: string;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
|
Icon: IconComponent;
|
||||||
active?: boolean;
|
active?: boolean;
|
||||||
icon: ReactNode;
|
|
||||||
danger?: boolean;
|
danger?: boolean;
|
||||||
soon?: boolean;
|
soon?: boolean;
|
||||||
};
|
};
|
||||||
@ -81,7 +82,16 @@ const StyledSoonPill = styled.div`
|
|||||||
padding-right: ${({ theme }) => theme.spacing(2)};
|
padding-right: ${({ theme }) => theme.spacing(2)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
function NavItem({ label, icon, to, onClick, active, danger, soon }: OwnProps) {
|
function NavItem({
|
||||||
|
label,
|
||||||
|
Icon,
|
||||||
|
to,
|
||||||
|
onClick,
|
||||||
|
active,
|
||||||
|
danger,
|
||||||
|
soon,
|
||||||
|
}: NavItemProps) {
|
||||||
|
const theme = useTheme();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [, setIsNavbarOpened] = useRecoilState(isNavbarOpenedState);
|
const [, setIsNavbarOpened] = useRecoilState(isNavbarOpenedState);
|
||||||
|
|
||||||
@ -107,7 +117,7 @@ function NavItem({ label, icon, to, onClick, active, danger, soon }: OwnProps) {
|
|||||||
danger={danger}
|
danger={danger}
|
||||||
soon={soon}
|
soon={soon}
|
||||||
>
|
>
|
||||||
{icon}
|
{Icon && <Icon size={theme.icon.size.md} />}
|
||||||
<StyledItemLabel>{label}</StyledItemLabel>
|
<StyledItemLabel>{label}</StyledItemLabel>
|
||||||
{soon && <StyledSoonPill>Soon</StyledSoonPill>}
|
{soon && <StyledSoonPill>Soon</StyledSoonPill>}
|
||||||
</StyledItem>
|
</StyledItem>
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { useTheme } from '@emotion/react';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
@ -30,7 +29,6 @@ function insertScript({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function SupportChat() {
|
export default function SupportChat() {
|
||||||
const theme = useTheme();
|
|
||||||
const currentUser = useRecoilValue(currentUserState);
|
const currentUser = useRecoilValue(currentUserState);
|
||||||
const supportChat = useRecoilValue(supportChatState);
|
const supportChat = useRecoilValue(supportChatState);
|
||||||
const [isFrontChatLoaded, setIsFrontChatLoaded] = useState(false);
|
const [isFrontChatLoaded, setIsFrontChatLoaded] = useState(false);
|
||||||
@ -85,7 +83,7 @@ export default function SupportChat() {
|
|||||||
variant={'tertiary'}
|
variant={'tertiary'}
|
||||||
size={'small'}
|
size={'small'}
|
||||||
title="Support"
|
title="Support"
|
||||||
icon={<IconHelpCircle size={theme.icon.size.md} />}
|
Icon={IconHelpCircle}
|
||||||
onClick={() => window.FrontChat?.('show')}
|
onClick={() => window.FrontChat?.('show')}
|
||||||
/>
|
/>
|
||||||
</StyledButtonContainer>
|
</StyledButtonContainer>
|
||||||
|
|||||||
@ -8,9 +8,4 @@ export const leftSubMenuNavbarWidth = {
|
|||||||
desktop: '520px',
|
desktop: '520px',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const navbarIconSize = {
|
|
||||||
mobile: 18,
|
|
||||||
desktop: 16,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const githubLink = 'https://github.com/twentyhq/twenty';
|
export const githubLink = 'https://github.com/twentyhq/twenty';
|
||||||
|
|||||||
@ -12,7 +12,7 @@ export function RightDrawerTopBarCloseButton() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<LightIconButton
|
<LightIconButton
|
||||||
icon={<IconChevronsRight />}
|
Icon={IconChevronsRight}
|
||||||
onClick={handleButtonClick}
|
onClick={handleButtonClick}
|
||||||
size="medium"
|
size="medium"
|
||||||
accent="tertiary"
|
accent="tertiary"
|
||||||
|
|||||||
@ -21,12 +21,10 @@ export function RightDrawerTopBarExpandButton() {
|
|||||||
<LightIconButton
|
<LightIconButton
|
||||||
size="medium"
|
size="medium"
|
||||||
accent="tertiary"
|
accent="tertiary"
|
||||||
icon={
|
Icon={
|
||||||
isRightDrawerExpanded ? (
|
isRightDrawerExpanded
|
||||||
<IconLayoutSidebarRightCollapse />
|
? IconLayoutSidebarRightCollapse
|
||||||
) : (
|
: IconLayoutSidebarRightExpand
|
||||||
<IconLayoutSidebarRightExpand />
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
onClick={handleButtonClick}
|
onClick={handleButtonClick}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,10 +1,13 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
type OwnProps = {
|
import { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
|
|
||||||
|
type TabProps = {
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
icon?: React.ReactNode;
|
Icon?: IconComponent;
|
||||||
active?: boolean;
|
active?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
@ -47,12 +50,13 @@ const StyledHover = styled.span`
|
|||||||
export function Tab({
|
export function Tab({
|
||||||
id,
|
id,
|
||||||
title,
|
title,
|
||||||
icon,
|
Icon,
|
||||||
active = false,
|
active = false,
|
||||||
onClick,
|
onClick,
|
||||||
className,
|
className,
|
||||||
disabled,
|
disabled,
|
||||||
}: OwnProps) {
|
}: TabProps) {
|
||||||
|
const theme = useTheme();
|
||||||
return (
|
return (
|
||||||
<StyledTab
|
<StyledTab
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
@ -62,7 +66,7 @@ export function Tab({
|
|||||||
data-testid={'tab-' + id}
|
data-testid={'tab-' + id}
|
||||||
>
|
>
|
||||||
<StyledHover>
|
<StyledHover>
|
||||||
{icon}
|
{Icon && <Icon size={theme.icon.size.md} />}
|
||||||
{title}
|
{title}
|
||||||
</StyledHover>
|
</StyledHover>
|
||||||
</StyledTab>
|
</StyledTab>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
|
import { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
|
|
||||||
import { activeTabIdScopedState } from '../states/activeTabIdScopedState';
|
import { activeTabIdScopedState } from '../states/activeTabIdScopedState';
|
||||||
@ -8,18 +9,18 @@ import { Tab } from './Tab';
|
|||||||
|
|
||||||
type SingleTabProps = {
|
type SingleTabProps = {
|
||||||
title: string;
|
title: string;
|
||||||
icon?: React.ReactNode;
|
Icon?: IconComponent;
|
||||||
id: string;
|
id: string;
|
||||||
hide?: boolean;
|
hide?: boolean;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type OwnProps = {
|
type TabListProps = {
|
||||||
tabs: SingleTabProps[];
|
tabs: SingleTabProps[];
|
||||||
context: React.Context<string | null>;
|
context: React.Context<string | null>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function TabList({ tabs, context }: OwnProps) {
|
export function TabList({ tabs, context }: TabListProps) {
|
||||||
const initialActiveTabId = tabs[0].id;
|
const initialActiveTabId = tabs[0].id;
|
||||||
|
|
||||||
const [activeTabId, setActiveTabId] = useRecoilScopedState(
|
const [activeTabId, setActiveTabId] = useRecoilScopedState(
|
||||||
@ -40,7 +41,7 @@ export function TabList({ tabs, context }: OwnProps) {
|
|||||||
id={tab.id}
|
id={tab.id}
|
||||||
key={tab.id}
|
key={tab.id}
|
||||||
title={tab.title}
|
title={tab.title}
|
||||||
icon={tab.icon}
|
Icon={tab.Icon}
|
||||||
active={tab.id === activeTabId}
|
active={tab.id === activeTabId}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setActiveTabId(tab.id);
|
setActiveTabId(tab.id);
|
||||||
|
|||||||
@ -23,7 +23,7 @@ export const Default: Story = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const Catalog: Story = {
|
export const Catalog: Story = {
|
||||||
args: { title: 'Tab title', icon: <IconCheckbox /> },
|
args: { title: 'Tab title', Icon: IconCheckbox },
|
||||||
argTypes: {
|
argTypes: {
|
||||||
active: { control: false },
|
active: { control: false },
|
||||||
disabled: { control: false },
|
disabled: { control: false },
|
||||||
|
|||||||
@ -12,26 +12,26 @@ const tabs = [
|
|||||||
{
|
{
|
||||||
id: '1',
|
id: '1',
|
||||||
title: 'Tab1',
|
title: 'Tab1',
|
||||||
icon: <IconCheckbox size={16} />,
|
Icon: IconCheckbox,
|
||||||
hide: true,
|
hide: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '2',
|
id: '2',
|
||||||
title: 'Tab2',
|
title: 'Tab2',
|
||||||
icon: <IconCheckbox size={16} />,
|
Icon: IconCheckbox,
|
||||||
hide: false,
|
hide: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '3',
|
id: '3',
|
||||||
title: 'Tab3',
|
title: 'Tab3',
|
||||||
icon: <IconCheckbox size={16} />,
|
Icon: IconCheckbox,
|
||||||
hide: false,
|
hide: false,
|
||||||
disabled: true,
|
disabled: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: '4',
|
id: '4',
|
||||||
title: 'Tab4',
|
title: 'Tab4',
|
||||||
icon: <IconCheckbox size={16} />,
|
Icon: IconCheckbox,
|
||||||
hide: false,
|
hide: false,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -189,7 +189,7 @@ export function EntityTableHeader() {
|
|||||||
<IconButton
|
<IconButton
|
||||||
size="medium"
|
size="medium"
|
||||||
variant="tertiary"
|
variant="tertiary"
|
||||||
icon={<IconPlus />}
|
Icon={IconPlus}
|
||||||
onClick={toggleColumnMenu}
|
onClick={toggleColumnMenu}
|
||||||
position="middle"
|
position="middle"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -117,7 +117,7 @@ export function EditableCell({
|
|||||||
<FloatingIconButton
|
<FloatingIconButton
|
||||||
size="small"
|
size="small"
|
||||||
onClick={handlePenClick}
|
onClick={handlePenClick}
|
||||||
icon={<IconPencil size={14} />}
|
Icon={IconPencil}
|
||||||
/>
|
/>
|
||||||
</StyledEditButtonContainer>
|
</StyledEditButtonContainer>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,18 +1,20 @@
|
|||||||
import { ReactNode } from 'react';
|
import { ReactNode } from 'react';
|
||||||
|
import { useTheme } from '@emotion/react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
|
|
||||||
|
import { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||||
|
|
||||||
import { DropdownMenuContainer } from './DropdownMenuContainer';
|
import { DropdownMenuContainer } from './DropdownMenuContainer';
|
||||||
|
|
||||||
type OwnProps = {
|
type DropdownButtonProps = {
|
||||||
anchor?: 'left' | 'right';
|
anchor?: 'left' | 'right';
|
||||||
label: ReactNode;
|
label: ReactNode;
|
||||||
isActive: boolean;
|
isActive: boolean;
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
isUnfolded?: boolean;
|
isUnfolded?: boolean;
|
||||||
icon?: ReactNode;
|
Icon?: IconComponent;
|
||||||
onIsUnfoldedChange?: (newIsUnfolded: boolean) => void;
|
onIsUnfoldedChange?: (newIsUnfolded: boolean) => void;
|
||||||
resetState?: () => void;
|
resetState?: () => void;
|
||||||
hotkeyScope: string;
|
hotkeyScope: string;
|
||||||
@ -64,11 +66,11 @@ function DropdownButton({
|
|||||||
children,
|
children,
|
||||||
isUnfolded = false,
|
isUnfolded = false,
|
||||||
onIsUnfoldedChange,
|
onIsUnfoldedChange,
|
||||||
|
Icon,
|
||||||
hotkeyScope,
|
hotkeyScope,
|
||||||
icon,
|
|
||||||
color,
|
color,
|
||||||
menuWidth,
|
menuWidth,
|
||||||
}: OwnProps) {
|
}: DropdownButtonProps) {
|
||||||
useScopedHotkeys(
|
useScopedHotkeys(
|
||||||
[Key.Enter, Key.Escape],
|
[Key.Enter, Key.Escape],
|
||||||
() => {
|
() => {
|
||||||
@ -86,6 +88,8 @@ function DropdownButton({
|
|||||||
onIsUnfoldedChange?.(false);
|
onIsUnfoldedChange?.(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledDropdownButtonContainer>
|
<StyledDropdownButtonContainer>
|
||||||
<StyledDropdownButton
|
<StyledDropdownButton
|
||||||
@ -95,7 +99,11 @@ function DropdownButton({
|
|||||||
aria-selected={isActive}
|
aria-selected={isActive}
|
||||||
color={color}
|
color={color}
|
||||||
>
|
>
|
||||||
{icon && <StyledDropdownButtonIcon>{icon}</StyledDropdownButtonIcon>}
|
{Icon && (
|
||||||
|
<StyledDropdownButtonIcon>
|
||||||
|
{<Icon size={theme.icon.size.md} />}
|
||||||
|
</StyledDropdownButtonIcon>
|
||||||
|
)}
|
||||||
{label}
|
{label}
|
||||||
</StyledDropdownButton>
|
</StyledDropdownButton>
|
||||||
{isUnfolded && (
|
{isUnfolded && (
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { Context } from 'react';
|
import { Context } from 'react';
|
||||||
|
|
||||||
|
import { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
|
|
||||||
import { availableFiltersScopedState } from '../states/availableFiltersScopedState';
|
import { availableFiltersScopedState } from '../states/availableFiltersScopedState';
|
||||||
@ -8,21 +9,23 @@ import { FiltersHotkeyScope } from '../types/FiltersHotkeyScope';
|
|||||||
import { MultipleFiltersDropdownButton } from './MultipleFiltersDropdownButton';
|
import { MultipleFiltersDropdownButton } from './MultipleFiltersDropdownButton';
|
||||||
import { SingleEntityFilterDropdownButton } from './SingleEntityFilterDropdownButton';
|
import { SingleEntityFilterDropdownButton } from './SingleEntityFilterDropdownButton';
|
||||||
|
|
||||||
|
type FilterDropdownButtonProps = {
|
||||||
|
context: Context<string | null>;
|
||||||
|
hotkeyScope: FiltersHotkeyScope;
|
||||||
|
isPrimaryButton?: boolean;
|
||||||
|
Icon?: IconComponent;
|
||||||
|
color?: string;
|
||||||
|
label?: string;
|
||||||
|
};
|
||||||
|
|
||||||
export function FilterDropdownButton({
|
export function FilterDropdownButton({
|
||||||
context,
|
context,
|
||||||
hotkeyScope,
|
hotkeyScope,
|
||||||
isPrimaryButton = false,
|
isPrimaryButton = false,
|
||||||
color,
|
color,
|
||||||
icon,
|
Icon,
|
||||||
label,
|
label,
|
||||||
}: {
|
}: FilterDropdownButtonProps) {
|
||||||
context: Context<string | null>;
|
|
||||||
hotkeyScope: FiltersHotkeyScope;
|
|
||||||
isPrimaryButton?: boolean;
|
|
||||||
icon?: React.ReactNode;
|
|
||||||
color?: string;
|
|
||||||
label?: string;
|
|
||||||
}) {
|
|
||||||
const [availableFilters] = useRecoilScopedState(
|
const [availableFilters] = useRecoilScopedState(
|
||||||
availableFiltersScopedState,
|
availableFiltersScopedState,
|
||||||
context,
|
context,
|
||||||
@ -40,7 +43,7 @@ export function FilterDropdownButton({
|
|||||||
<MultipleFiltersDropdownButton
|
<MultipleFiltersDropdownButton
|
||||||
context={context}
|
context={context}
|
||||||
hotkeyScope={hotkeyScope}
|
hotkeyScope={hotkeyScope}
|
||||||
icon={icon}
|
Icon={Icon}
|
||||||
isPrimaryButton={isPrimaryButton}
|
isPrimaryButton={isPrimaryButton}
|
||||||
color={color}
|
color={color}
|
||||||
label={label}
|
label={label}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { Context, useCallback, useState } from 'react';
|
import { Context, useCallback, useState } from 'react';
|
||||||
|
|
||||||
import { StyledDropdownMenuSeparator } from '@/ui/dropdown/components/StyledDropdownMenuSeparator';
|
import { StyledDropdownMenuSeparator } from '@/ui/dropdown/components/StyledDropdownMenuSeparator';
|
||||||
|
import { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { filterDefinitionUsedInDropdownScopedState } from '@/ui/view-bar/states/filterDefinitionUsedInDropdownScopedState';
|
import { filterDefinitionUsedInDropdownScopedState } from '@/ui/view-bar/states/filterDefinitionUsedInDropdownScopedState';
|
||||||
@ -22,21 +23,23 @@ import { FilterDropdownOperandButton } from './FilterDropdownOperandButton';
|
|||||||
import { FilterDropdownOperandSelect } from './FilterDropdownOperandSelect';
|
import { FilterDropdownOperandSelect } from './FilterDropdownOperandSelect';
|
||||||
import { FilterDropdownTextSearchInput } from './FilterDropdownTextSearchInput';
|
import { FilterDropdownTextSearchInput } from './FilterDropdownTextSearchInput';
|
||||||
|
|
||||||
|
type MultipleFiltersDropdownButtonProps = {
|
||||||
|
context: Context<string | null>;
|
||||||
|
hotkeyScope: FiltersHotkeyScope;
|
||||||
|
isPrimaryButton?: boolean;
|
||||||
|
Icon?: IconComponent;
|
||||||
|
color?: string;
|
||||||
|
label?: string;
|
||||||
|
};
|
||||||
|
|
||||||
export function MultipleFiltersDropdownButton({
|
export function MultipleFiltersDropdownButton({
|
||||||
context,
|
context,
|
||||||
hotkeyScope,
|
hotkeyScope,
|
||||||
isPrimaryButton = false,
|
isPrimaryButton = false,
|
||||||
color,
|
color,
|
||||||
icon,
|
Icon,
|
||||||
label,
|
label,
|
||||||
}: {
|
}: MultipleFiltersDropdownButtonProps) {
|
||||||
context: Context<string | null>;
|
|
||||||
hotkeyScope: FiltersHotkeyScope;
|
|
||||||
isPrimaryButton?: boolean;
|
|
||||||
icon?: React.ReactNode;
|
|
||||||
color?: string;
|
|
||||||
label?: string;
|
|
||||||
}) {
|
|
||||||
const [isUnfolded, setIsUnfolded] = useState(false);
|
const [isUnfolded, setIsUnfolded] = useState(false);
|
||||||
|
|
||||||
const [
|
const [
|
||||||
@ -108,7 +111,7 @@ export function MultipleFiltersDropdownButton({
|
|||||||
label={label ?? 'Filter'}
|
label={label ?? 'Filter'}
|
||||||
isActive={isFilterSelected}
|
isActive={isFilterSelected}
|
||||||
isUnfolded={isUnfolded}
|
isUnfolded={isUnfolded}
|
||||||
icon={icon}
|
Icon={Icon}
|
||||||
onIsUnfoldedChange={handleIsUnfoldedChange}
|
onIsUnfoldedChange={handleIsUnfoldedChange}
|
||||||
hotkeyScope={hotkeyScope}
|
hotkeyScope={hotkeyScope}
|
||||||
color={color}
|
color={color}
|
||||||
|
|||||||
@ -67,7 +67,7 @@ function SortOrFilterChip({
|
|||||||
<StyledChip isSort={isSort}>
|
<StyledChip isSort={isSort}>
|
||||||
{Icon && (
|
{Icon && (
|
||||||
<StyledIcon>
|
<StyledIcon>
|
||||||
<Icon />
|
<Icon size={theme.icon.size.md} />
|
||||||
</StyledIcon>
|
</StyledIcon>
|
||||||
)}
|
)}
|
||||||
{labelKey && <StyledLabelKey>{labelKey}</StyledLabelKey>}
|
{labelKey && <StyledLabelKey>{labelKey}</StyledLabelKey>}
|
||||||
|
|||||||
@ -108,7 +108,7 @@ export const UpdateViewButtonGroup = ({
|
|||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
size="small"
|
size="small"
|
||||||
icon={<IconChevronDown />}
|
Icon={IconChevronDown}
|
||||||
onClick={handleArrowDownButtonClick}
|
onClick={handleArrowDownButtonClick}
|
||||||
/>
|
/>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
|
|||||||
@ -202,7 +202,7 @@ function ViewBarDetails<SortField>({
|
|||||||
context={context}
|
context={context}
|
||||||
hotkeyScope={FiltersHotkeyScope.FilterDropdownButton}
|
hotkeyScope={FiltersHotkeyScope.FilterDropdownButton}
|
||||||
color={theme.font.color.tertiary}
|
color={theme.font.color.tertiary}
|
||||||
icon={<IconPlus size={theme.icon.size.md} />}
|
Icon={IconPlus}
|
||||||
label="Add filter"
|
label="Add filter"
|
||||||
/>
|
/>
|
||||||
</StyledAddFilterContainer>
|
</StyledAddFilterContainer>
|
||||||
|
|||||||
@ -12,7 +12,7 @@ export type AvatarSize = 'xl' | 'lg' | 'md' | 'sm' | 'xs';
|
|||||||
|
|
||||||
export type AvatarProps = {
|
export type AvatarProps = {
|
||||||
avatarUrl: string | null | undefined;
|
avatarUrl: string | null | undefined;
|
||||||
size: AvatarSize;
|
size?: AvatarSize;
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
colorId?: string;
|
colorId?: string;
|
||||||
type?: AvatarType;
|
type?: AvatarType;
|
||||||
@ -83,7 +83,7 @@ const StyledAvatar = styled.div<AvatarProps & { colorId: string }>`
|
|||||||
|
|
||||||
export function Avatar({
|
export function Avatar({
|
||||||
avatarUrl,
|
avatarUrl,
|
||||||
size,
|
size = 'md',
|
||||||
placeholder,
|
placeholder,
|
||||||
colorId = placeholder,
|
colorId = placeholder,
|
||||||
type = 'squared',
|
type = 'squared',
|
||||||
|
|||||||
@ -32,7 +32,7 @@ export function WorkspaceInviteLink({ inviteLink }: OwnProps) {
|
|||||||
<TextInput value={inviteLink} disabled fullWidth />
|
<TextInput value={inviteLink} disabled fullWidth />
|
||||||
</StyledLinkContainer>
|
</StyledLinkContainer>
|
||||||
<Button
|
<Button
|
||||||
icon={<IconLink size={theme.icon.size.md} />}
|
Icon={IconLink}
|
||||||
variant="primary"
|
variant="primary"
|
||||||
accent="blue"
|
accent="blue"
|
||||||
title="Copy link"
|
title="Copy link"
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { getOperationName } from '@apollo/client/utilities';
|
import { getOperationName } from '@apollo/client/utilities';
|
||||||
import { useTheme } from '@emotion/react';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
@ -70,15 +69,10 @@ export function Companies() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const theme = useTheme();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SpreadsheetImportProvider>
|
<SpreadsheetImportProvider>
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
<PageHeader
|
<PageHeader title="Companies" Icon={IconBuildingSkyscraper}>
|
||||||
title="Companies"
|
|
||||||
icon={<IconBuildingSkyscraper size={theme.icon.size.md} />}
|
|
||||||
>
|
|
||||||
<RecoilScope SpecificContext={DropdownRecoilScopeContext}>
|
<RecoilScope SpecificContext={DropdownRecoilScopeContext}>
|
||||||
<PageHotkeys onAddButtonClick={handleAddButtonClick} />
|
<PageHotkeys onAddButtonClick={handleAddButtonClick} />
|
||||||
<PageAddButton onClick={handleAddButtonClick} />
|
<PageAddButton onClick={handleAddButtonClick} />
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { useTheme } from '@emotion/react';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { CompanyTableMockMode } from '@/companies/table/components/CompanyTableMockMode';
|
import { CompanyTableMockMode } from '@/companies/table/components/CompanyTableMockMode';
|
||||||
@ -15,14 +14,9 @@ const StyledTableContainer = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export function CompaniesMockMode() {
|
export function CompaniesMockMode() {
|
||||||
const theme = useTheme();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
<PageHeader
|
<PageHeader title="Companies" Icon={IconBuildingSkyscraper} />
|
||||||
title="Companies"
|
|
||||||
icon={<IconBuildingSkyscraper size={theme.icon.size.md} />}
|
|
||||||
/>
|
|
||||||
<PageBody>
|
<PageBody>
|
||||||
<RecoilScope SpecificContext={TableRecoilScopeContext}>
|
<RecoilScope SpecificContext={TableRecoilScopeContext}>
|
||||||
<StyledTableContainer>
|
<StyledTableContainer>
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
import { useTheme } from '@emotion/react';
|
|
||||||
|
|
||||||
import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity';
|
import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity';
|
||||||
import { CompanyTeam } from '@/companies/components/CompanyTeam';
|
import { CompanyTeam } from '@/companies/components/CompanyTeam';
|
||||||
@ -37,7 +36,6 @@ export function CompanyShow() {
|
|||||||
const companyId = useParams().companyId ?? '';
|
const companyId = useParams().companyId ?? '';
|
||||||
const { insertCompanyFavorite, deleteCompanyFavorite } = useFavorites();
|
const { insertCompanyFavorite, deleteCompanyFavorite } = useFavorites();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const theme = useTheme();
|
|
||||||
const { data, loading } = useCompanyQuery(companyId);
|
const { data, loading } = useCompanyQuery(companyId);
|
||||||
const company = data?.findUniqueCompany;
|
const company = data?.findUniqueCompany;
|
||||||
|
|
||||||
@ -63,7 +61,7 @@ export function CompanyShow() {
|
|||||||
<PageHeader
|
<PageHeader
|
||||||
title={company.name ?? ''}
|
title={company.name ?? ''}
|
||||||
hasBackButton
|
hasBackButton
|
||||||
icon={<IconBuildingSkyscraper size={theme.icon.size.md} />}
|
Icon={IconBuildingSkyscraper}
|
||||||
>
|
>
|
||||||
<RecoilScope SpecificContext={DropdownRecoilScopeContext}>
|
<RecoilScope SpecificContext={DropdownRecoilScopeContext}>
|
||||||
<PageFavoriteButton
|
<PageFavoriteButton
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { useTheme } from '@emotion/react';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { HooksCompanyBoard } from '@/companies/components/HooksCompanyBoard';
|
import { HooksCompanyBoard } from '@/companies/components/HooksCompanyBoard';
|
||||||
@ -24,8 +23,6 @@ const StyledPageHeader = styled(PageHeader)`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export function Opportunities() {
|
export function Opportunities() {
|
||||||
const theme = useTheme();
|
|
||||||
|
|
||||||
const { handlePipelineStageAdd, handlePipelineStageDelete } =
|
const { handlePipelineStageAdd, handlePipelineStageDelete } =
|
||||||
usePipelineStages();
|
usePipelineStages();
|
||||||
|
|
||||||
@ -56,10 +53,7 @@ export function Opportunities() {
|
|||||||
return (
|
return (
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
<RecoilScope>
|
<RecoilScope>
|
||||||
<StyledPageHeader
|
<StyledPageHeader title="Opportunities" Icon={IconTargetArrow}>
|
||||||
title="Opportunities"
|
|
||||||
icon={<IconTargetArrow size={theme.icon.size.md} />}
|
|
||||||
>
|
|
||||||
<RecoilScope SpecificContext={DropdownRecoilScopeContext}>
|
<RecoilScope SpecificContext={DropdownRecoilScopeContext}>
|
||||||
<PipelineAddButton />
|
<PipelineAddButton />
|
||||||
</RecoilScope>
|
</RecoilScope>
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { useTheme } from '@emotion/react';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
@ -62,15 +61,10 @@ export function People() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const theme = useTheme();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SpreadsheetImportProvider>
|
<SpreadsheetImportProvider>
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
<PageHeader
|
<PageHeader title="People" Icon={IconUser}>
|
||||||
title="People"
|
|
||||||
icon={<IconUser size={theme.icon.size.md} />}
|
|
||||||
>
|
|
||||||
<RecoilScope SpecificContext={DropdownRecoilScopeContext}>
|
<RecoilScope SpecificContext={DropdownRecoilScopeContext}>
|
||||||
<PageHotkeys onAddButtonClick={handleAddButtonClick} />
|
<PageHotkeys onAddButtonClick={handleAddButtonClick} />
|
||||||
<PageAddButton onClick={handleAddButtonClick} />
|
<PageAddButton onClick={handleAddButtonClick} />
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
import { getOperationName } from '@apollo/client/utilities';
|
import { getOperationName } from '@apollo/client/utilities';
|
||||||
import { useTheme } from '@emotion/react';
|
|
||||||
|
|
||||||
import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity';
|
import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity';
|
||||||
import { useFavorites } from '@/favorites/hooks/useFavorites';
|
import { useFavorites } from '@/favorites/hooks/useFavorites';
|
||||||
@ -41,8 +40,6 @@ export function PersonShow() {
|
|||||||
const { insertPersonFavorite, deletePersonFavorite } = useFavorites();
|
const { insertPersonFavorite, deletePersonFavorite } = useFavorites();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const theme = useTheme();
|
|
||||||
|
|
||||||
const { data, loading } = usePersonQuery(personId);
|
const { data, loading } = usePersonQuery(personId);
|
||||||
const person = data?.findUniquePerson;
|
const person = data?.findUniquePerson;
|
||||||
|
|
||||||
@ -80,11 +77,7 @@ export function PersonShow() {
|
|||||||
return (
|
return (
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
<PageTitle title={person.displayName || 'No Name'} />
|
<PageTitle title={person.displayName || 'No Name'} />
|
||||||
<PageHeader
|
<PageHeader title={person.firstName ?? ''} Icon={IconUser} hasBackButton>
|
||||||
title={person.firstName ?? ''}
|
|
||||||
icon={<IconUser size={theme.icon.size.md} />}
|
|
||||||
hasBackButton
|
|
||||||
>
|
|
||||||
<RecoilScope SpecificContext={DropdownRecoilScopeContext}>
|
<RecoilScope SpecificContext={DropdownRecoilScopeContext}>
|
||||||
<PageFavoriteButton
|
<PageFavoriteButton
|
||||||
isFavorite={isFavorite}
|
isFavorite={isFavorite}
|
||||||
|
|||||||
@ -20,7 +20,7 @@ export function SettingsExperience() {
|
|||||||
const { colorScheme, setColorScheme } = useColorScheme();
|
const { colorScheme, setColorScheme } = useColorScheme();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SubMenuTopBarContainer icon={<IconSettings size={16} />} title="Settings">
|
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<H1Title title="Experience" />
|
<H1Title title="Experience" />
|
||||||
<Section>
|
<Section>
|
||||||
|
|||||||
@ -23,7 +23,7 @@ const StyledContainer = styled.div`
|
|||||||
|
|
||||||
export function SettingsProfile() {
|
export function SettingsProfile() {
|
||||||
return (
|
return (
|
||||||
<SubMenuTopBarContainer icon={<IconSettings size={16} />} title="Settings">
|
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||||
<>
|
<>
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<H1Title title="Profile" />
|
<H1Title title="Profile" />
|
||||||
|
|||||||
@ -18,7 +18,7 @@ const StyledContainer = styled.div`
|
|||||||
|
|
||||||
export function SettingsWorkspace() {
|
export function SettingsWorkspace() {
|
||||||
return (
|
return (
|
||||||
<SubMenuTopBarContainer icon={<IconSettings size={16} />} title="Settings">
|
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||||
<div>
|
<div>
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<H1Title title="General" />
|
<H1Title title="General" />
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useTheme } from '@emotion/react';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { currentUserState } from '@/auth/states/currentUserState';
|
import { currentUserState } from '@/auth/states/currentUserState';
|
||||||
import { Button } from '@/ui/button/components/Button';
|
import { IconButton } from '@/ui/button/components/IconButton';
|
||||||
import { IconSettings, IconTrash } from '@/ui/icon';
|
import { IconSettings, IconTrash } from '@/ui/icon';
|
||||||
import { SubMenuTopBarContainer } from '@/ui/layout/components/SubMenuTopBarContainer';
|
import { SubMenuTopBarContainer } from '@/ui/layout/components/SubMenuTopBarContainer';
|
||||||
import { ConfirmationModal } from '@/ui/modal/components/ConfirmationModal';
|
import { ConfirmationModal } from '@/ui/modal/components/ConfirmationModal';
|
||||||
@ -39,7 +38,6 @@ export function SettingsWorkspaceMembers() {
|
|||||||
|
|
||||||
const [currentUser] = useRecoilState(currentUserState);
|
const [currentUser] = useRecoilState(currentUserState);
|
||||||
const workspace = currentUser?.workspaceMember?.workspace;
|
const workspace = currentUser?.workspaceMember?.workspace;
|
||||||
const theme = useTheme();
|
|
||||||
|
|
||||||
const { data } = useGetWorkspaceMembersQuery();
|
const { data } = useGetWorkspaceMembersQuery();
|
||||||
|
|
||||||
@ -85,7 +83,7 @@ export function SettingsWorkspaceMembers() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SubMenuTopBarContainer icon={<IconSettings size={16} />} title="Settings">
|
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<H1Title title="Members" />
|
<H1Title title="Members" />
|
||||||
{workspace?.inviteHash && (
|
{workspace?.inviteHash && (
|
||||||
@ -111,14 +109,14 @@ export function SettingsWorkspaceMembers() {
|
|||||||
accessory={
|
accessory={
|
||||||
currentUser?.id !== member.user.id && (
|
currentUser?.id !== member.user.id && (
|
||||||
<StyledButtonContainer>
|
<StyledButtonContainer>
|
||||||
<Button
|
<IconButton
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsConfirmationModalOpen(true);
|
setIsConfirmationModalOpen(true);
|
||||||
setUserToDelete(member.user.id);
|
setUserToDelete(member.user.id);
|
||||||
}}
|
}}
|
||||||
variant={'tertiary'}
|
variant="tertiary"
|
||||||
size={'small'}
|
size="medium"
|
||||||
icon={<IconTrash size={theme.icon.size.md} />}
|
Icon={IconTrash}
|
||||||
/>
|
/>
|
||||||
</StyledButtonContainer>
|
</StyledButtonContainer>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { useTheme } from '@emotion/react';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
|
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
|
||||||
@ -32,28 +31,24 @@ const StyledTabListContainer = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export function Tasks() {
|
export function Tasks() {
|
||||||
const theme = useTheme();
|
|
||||||
const openCreateActivity = useOpenCreateActivityDrawer();
|
const openCreateActivity = useOpenCreateActivityDrawer();
|
||||||
|
|
||||||
const TASK_TABS = [
|
const TASK_TABS = [
|
||||||
{
|
{
|
||||||
id: 'to-do',
|
id: 'to-do',
|
||||||
title: 'To do',
|
title: 'To do',
|
||||||
icon: <IconCheck size={theme.icon.size.md} />,
|
Icon: IconCheck,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'done',
|
id: 'done',
|
||||||
title: 'Done',
|
title: 'Done',
|
||||||
icon: <IconArchive size={theme.icon.size.md} />,
|
Icon: IconArchive,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
<PageHeader
|
<PageHeader title="Tasks" Icon={IconCheckbox}>
|
||||||
title="Tasks"
|
|
||||||
icon={<IconCheckbox size={theme.icon.size.md} />}
|
|
||||||
>
|
|
||||||
<RecoilScope SpecificContext={DropdownRecoilScopeContext}>
|
<RecoilScope SpecificContext={DropdownRecoilScopeContext}>
|
||||||
<PageAddButton
|
<PageAddButton
|
||||||
onClick={() => openCreateActivity(ActivityType.Task)}
|
onClick={() => openCreateActivity(ActivityType.Task)}
|
||||||
|
|||||||
@ -189,7 +189,7 @@ export function PageChangeEffect() {
|
|||||||
to: '',
|
to: '',
|
||||||
label: 'Create Task',
|
label: 'Create Task',
|
||||||
type: CommandType.Create,
|
type: CommandType.Create,
|
||||||
icon: <IconCheckbox />,
|
Icon: IconCheckbox,
|
||||||
onCommandClick: () =>
|
onCommandClick: () =>
|
||||||
openCreateActivity(
|
openCreateActivity(
|
||||||
ActivityType.Task,
|
ActivityType.Task,
|
||||||
@ -200,7 +200,7 @@ export function PageChangeEffect() {
|
|||||||
to: '',
|
to: '',
|
||||||
label: 'Create Note',
|
label: 'Create Note',
|
||||||
type: CommandType.Create,
|
type: CommandType.Create,
|
||||||
icon: <IconNotes />,
|
Icon: IconNotes,
|
||||||
onCommandClick: () =>
|
onCommandClick: () =>
|
||||||
openCreateActivity(
|
openCreateActivity(
|
||||||
ActivityType.Note,
|
ActivityType.Note,
|
||||||
@ -223,7 +223,7 @@ export function PageChangeEffect() {
|
|||||||
to: '',
|
to: '',
|
||||||
label: 'Create Task',
|
label: 'Create Task',
|
||||||
type: CommandType.Create,
|
type: CommandType.Create,
|
||||||
icon: <IconCheckbox />,
|
Icon: IconCheckbox,
|
||||||
onCommandClick: () =>
|
onCommandClick: () =>
|
||||||
openCreateActivity(
|
openCreateActivity(
|
||||||
ActivityType.Task,
|
ActivityType.Task,
|
||||||
@ -234,7 +234,7 @@ export function PageChangeEffect() {
|
|||||||
to: '',
|
to: '',
|
||||||
label: 'Create Note',
|
label: 'Create Note',
|
||||||
type: CommandType.Create,
|
type: CommandType.Create,
|
||||||
icon: <IconNotes />,
|
Icon: IconNotes,
|
||||||
onCommandClick: () =>
|
onCommandClick: () =>
|
||||||
openCreateActivity(
|
openCreateActivity(
|
||||||
ActivityType.Note,
|
ActivityType.Note,
|
||||||
@ -250,7 +250,7 @@ export function PageChangeEffect() {
|
|||||||
to: '',
|
to: '',
|
||||||
label: 'Create Task',
|
label: 'Create Task',
|
||||||
type: CommandType.Create,
|
type: CommandType.Create,
|
||||||
icon: <IconCheckbox />,
|
Icon: IconCheckbox,
|
||||||
onCommandClick: () => openCreateActivity(ActivityType.Task),
|
onCommandClick: () => openCreateActivity(ActivityType.Task),
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|||||||
Reference in New Issue
Block a user