Feat/harmonize chips cell fields (#724)

* Wip

* Finished

* Fix lint
This commit is contained in:
Lucas Bordeau 2023-07-18 02:14:09 +02:00 committed by GitHub
parent 8b7314cd39
commit 5b21657c4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 347 additions and 217 deletions

View File

@ -1,70 +1,21 @@
import { Link } from 'react-router-dom'; import { EntityChip } from '@/ui/chip/components/EntityChip';
import { Theme } from '@emotion/react';
import styled from '@emotion/styled';
import { Avatar } from '@/users/components/Avatar'; type OwnProps = {
export type CompanyChipPropsType = {
id: string; id: string;
name: string; name: string;
picture?: string; picture?: string;
clickable?: boolean;
}; };
const baseStyle = ({ theme }: { theme: Theme }) => ` export function CompanyChip({ id, name, picture, clickable }: OwnProps) {
align-items: center;
background-color: ${theme.background.tertiary};
border-radius: ${theme.spacing(1)};
color: ${theme.font.color.primary};
display: inline-flex;
gap: ${theme.spacing(1)};
height: calc(20px - 2 * ${theme.spacing(1)});
overflow: hidden;
padding: ${theme.spacing(1)};
text-decoration: none;
user-select: none;
:hover {
filter: brightness(95%);
}
img {
height: 14px;
object-fit: cover;
width: 14px;
}
`;
const StyledName = styled.span`
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;
const StyledContainerLink = styled(Link)`
${baseStyle}
`;
const StyledContainerNoLink = styled.div`
${baseStyle}
`;
export function CompanyChip({ id, name, picture }: CompanyChipPropsType) {
const ContainerComponent = id ? StyledContainerLink : StyledContainerNoLink;
return ( return (
<ContainerComponent data-testid="company-chip" to={`/companies/${id}`}> <EntityChip
{picture && ( entityId={id}
<Avatar linkToEntity={`/companies/${id}`}
avatarUrl={picture?.toString()} name={name}
colorId={id} avatarType="squared"
placeholder={name} clickable={clickable}
type="squared" picture={picture}
size={14} />
/>
)}
<StyledName>{name}</StyledName>
</ContainerComponent>
); );
} }

View File

@ -29,10 +29,15 @@ export function CompanyEditableNameChipCell({ company }: OwnProps) {
<EditableCellChip <EditableCellChip
value={internalValue} value={internalValue}
placeholder="Name" placeholder="Name"
picture={getLogoUrlFromDomainName(company.domainName)}
id={company.id}
changeHandler={setInternalValue} changeHandler={setInternalValue}
ChipComponent={CompanyChip} ChipComponent={
<CompanyChip
id={company.id}
name={company.name}
clickable
picture={getLogoUrlFromDomainName(company.domainName)}
/>
}
onSubmit={() => onSubmit={() =>
updateCompany({ updateCompany({
variables: { variables: {

View File

@ -25,15 +25,13 @@ export function CompanyAccountOwnerEditableField({ company }: OwnProps) {
}} }}
parentHotkeyScope={{ parentHotkeyScope={{
scope: PageHotkeyScope.CompanyShowPage, scope: PageHotkeyScope.CompanyShowPage,
customScopes: {
goto: true,
},
}} }}
iconLabel={<IconUserCircle />} iconLabel={<IconUserCircle />}
editModeContent={ editModeContent={
<CompanyAccountOwnerPickerFieldEditMode <CompanyAccountOwnerPickerFieldEditMode company={company} />
parentHotkeyScope={{
scope: PageHotkeyScope.CompanyShowPage,
}}
company={company}
/>
} }
displayModeContent={ displayModeContent={
company.accountOwner?.displayName ? ( company.accountOwner?.displayName ? (

View File

@ -24,9 +24,8 @@ export function CompanyAccountOwnerPickerFieldEditMode({
company, company,
onSubmit, onSubmit,
onCancel, onCancel,
parentHotkeyScope,
}: OwnProps) { }: OwnProps) {
const { closeEditableField } = useEditableField(parentHotkeyScope); const { closeEditableField } = useEditableField();
function handleSubmit() { function handleSubmit() {
closeEditableField(); closeEditableField();

View File

@ -54,6 +54,7 @@ export function CompanyAddressEditableField({ company }: OwnProps) {
/> />
} }
displayModeContent={internalValue ?? ''} displayModeContent={internalValue ?? ''}
isDisplayModeContentEmpty={!(internalValue !== '')}
/> />
</RecoilScope> </RecoilScope>
); );

View File

@ -51,6 +51,7 @@ export function EditablePeopleFullName({
<PersonChip <PersonChip
name={person?.firstName + ' ' + person?.lastName} name={person?.firstName + ' ' + person?.lastName}
id={person?.id ?? ''} id={person?.id ?? ''}
clickable
/> />
</NoEditModeContainer> </NoEditModeContainer>
} }

View File

@ -1,66 +1,26 @@
import * as React from 'react'; import { EntityChip } from '@/ui/chip/components/EntityChip';
import { Link } from 'react-router-dom';
import { Theme } from '@emotion/react';
import styled from '@emotion/styled';
import { Avatar } from '@/users/components/Avatar';
export type PersonChipPropsType = { export type PersonChipPropsType = {
id: string; id: string;
name: string; name: string;
picture?: string; picture?: string;
clickable?: boolean;
}; };
const baseStyle = ({ theme }: { theme: Theme }) => ` export function PersonChip({
align-items: center; id,
background-color: ${theme.background.tertiary}; name,
border-radius: ${theme.spacing(1)}; picture,
color: ${theme.font.color.primary}; clickable,
display: inline-flex; }: PersonChipPropsType) {
gap: ${theme.spacing(1)};
height: 12px;
overflow: hidden;
padding: ${theme.spacing(1)};
text-decoration: none;
:hover {
filter: brightness(95%);
}
img {
border-radius: ${theme.border.radius.rounded};
height: 14px;
object-fit: cover;
width: 14px;
}
white-space: nowrap;
`;
const StyledContainerLink = styled(Link)`
${baseStyle}
`;
const StyledContainerNoLink = styled.div`
${baseStyle}
`;
const StyledName = styled.span`
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;
export function PersonChip({ id, name, picture }: PersonChipPropsType) {
const ContainerComponent = id ? StyledContainerLink : StyledContainerNoLink;
return ( return (
<ContainerComponent data-testid="person-chip" to={`/person/${id}`}> <EntityChip
<Avatar entityId={id}
avatarUrl={picture} linkToEntity={`/person/${id}`}
colorId={id} name={name}
placeholder={name} avatarType="rounded"
size={14} clickable={clickable}
type="rounded" picture={picture}
/> />
<StyledName>{name}</StyledName>
</ContainerComponent>
); );
} }

View File

@ -0,0 +1,97 @@
import * as React from 'react';
import { useNavigate } from 'react-router-dom';
import { Theme } from '@emotion/react';
import styled from '@emotion/styled';
import { Avatar, AvatarType } from '@/users/components/Avatar';
const baseStyle = ({ theme }: { theme: Theme }) => `
align-items: center;
border-radius: ${theme.spacing(1)};
color: ${theme.font.color.primary};
display: inline-flex;
gap: ${theme.spacing(1)};
height: 12px;
overflow: hidden;
padding: ${theme.spacing(1)};
text-decoration: none;
img {
border-radius: ${theme.border.radius.rounded};
height: 14px;
object-fit: cover;
width: 14px;
}
white-space: nowrap;
`;
const StyledContainerLink = styled.div`
${baseStyle}
background-color: ${(props) => props.theme.background.tertiary};
:hover {
filter: brightness(95%);
}
`;
const StyledContainerReadOnly = styled.div`
${baseStyle}
`;
const StyledName = styled.span`
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;
type OwnProps = {
linkToEntity: string;
entityId: string;
name: string;
picture?: string;
clickable?: boolean;
avatarType?: AvatarType;
};
export function EntityChip({
linkToEntity,
entityId,
name,
picture,
clickable,
avatarType = 'rounded',
}: OwnProps) {
const navigate = useNavigate();
function handleLinkClick(event: React.MouseEvent<HTMLDivElement>) {
event.preventDefault();
event.stopPropagation();
navigate(linkToEntity);
}
return clickable && linkToEntity ? (
<StyledContainerLink data-testid="entity-chip" onClick={handleLinkClick}>
<Avatar
avatarUrl={picture}
colorId={entityId}
placeholder={name}
size={14}
type={avatarType}
/>
<StyledName>{name}</StyledName>
</StyledContainerLink>
) : (
<StyledContainerReadOnly data-testid="entity-chip">
<Avatar
avatarUrl={picture}
colorId={entityId}
placeholder={name}
size={14}
type={avatarType}
/>
<StyledName>{name}</StyledName>
</StyledContainerReadOnly>
);
}

View File

@ -4,6 +4,7 @@ import { motion } from 'framer-motion';
import { HotkeyScope } from '@/ui/hotkey/types/HotkeyScope'; import { HotkeyScope } from '@/ui/hotkey/types/HotkeyScope';
import { useBindFieldHotkeyScope } from '../hooks/useBindFieldHotkeyScope';
import { useEditableField } from '../hooks/useEditableField'; import { useEditableField } from '../hooks/useEditableField';
import { EditableFieldDisplayMode } from './EditableFieldDisplayMode'; import { EditableFieldDisplayMode } from './EditableFieldDisplayMode';
@ -43,8 +44,10 @@ export const EditableFieldBaseContainer = styled.div`
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
gap: ${({ theme }) => theme.spacing(1)}; gap: ${({ theme }) => theme.spacing(1)};
height: 24px; height: 24px;
justify-content: flex-start;
position: relative; position: relative;
user-select: none; user-select: none;
@ -60,6 +63,7 @@ type OwnProps = {
displayModeContent: React.ReactNode; displayModeContent: React.ReactNode;
parentHotkeyScope?: HotkeyScope; parentHotkeyScope?: HotkeyScope;
customEditHotkeyScope?: HotkeyScope; customEditHotkeyScope?: HotkeyScope;
isDisplayModeContentEmpty?: boolean;
onSubmit?: () => void; onSubmit?: () => void;
onCancel?: () => void; onCancel?: () => void;
}; };
@ -73,11 +77,17 @@ export function EditableField({
displayModeContent, displayModeContent,
parentHotkeyScope, parentHotkeyScope,
customEditHotkeyScope, customEditHotkeyScope,
isDisplayModeContentEmpty,
onSubmit, onSubmit,
onCancel, onCancel,
}: OwnProps) { }: OwnProps) {
const [isHovered, setIsHovered] = useState(false); const [isHovered, setIsHovered] = useState(false);
useBindFieldHotkeyScope({
customEditHotkeyScope,
parentHotkeyScope,
});
function handleContainerMouseEnter() { function handleContainerMouseEnter() {
setIsHovered(true); setIsHovered(true);
} }
@ -86,11 +96,10 @@ export function EditableField({
setIsHovered(false); setIsHovered(false);
} }
const { isFieldInEditMode, openEditableField } = const { isFieldInEditMode, openEditableField } = useEditableField();
useEditableField(parentHotkeyScope);
function handleDisplayModeClick() { function handleDisplayModeClick() {
openEditableField(customEditHotkeyScope); openEditableField();
} }
const showEditButton = !isFieldInEditMode && isHovered && useEditButton; const showEditButton = !isFieldInEditMode && isHovered && useEditButton;
@ -114,6 +123,7 @@ export function EditableField({
<EditableFieldDisplayMode <EditableFieldDisplayMode
disableClick={useEditButton} disableClick={useEditButton}
onClick={handleDisplayModeClick} onClick={handleDisplayModeClick}
isDisplayModeContentEmpty={isDisplayModeContentEmpty}
> >
{displayModeContent} {displayModeContent}
</EditableFieldDisplayMode> </EditableFieldDisplayMode>

View File

@ -2,7 +2,7 @@ import { css } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
export const EditableFieldNormalModeOuterContainer = styled.div< export const EditableFieldNormalModeOuterContainer = styled.div<
Pick<OwnProps, 'disableClick'> Pick<OwnProps, 'disableClick' | 'isDisplayModeContentEmpty'>
>` >`
align-items: center; align-items: center;
border-radius: ${({ theme }) => theme.border.radius.sm}; border-radius: ${({ theme }) => theme.border.radius.sm};
@ -15,7 +15,18 @@ export const EditableFieldNormalModeOuterContainer = styled.div<
padding: ${({ theme }) => theme.spacing(1)}; padding: ${({ theme }) => theme.spacing(1)};
width: 100%; ${(props) => {
console.log(props.isDisplayModeContentEmpty);
if (props.isDisplayModeContentEmpty) {
return css`
min-width: 50px;
`;
} else {
return css`
width: fit-content;
`;
}
}}
${(props) => { ${(props) => {
if (props.disableClick) { if (props.disableClick) {
@ -51,17 +62,20 @@ export const EditableFieldNormalModeInnerContainer = styled.div`
type OwnProps = { type OwnProps = {
disableClick?: boolean; disableClick?: boolean;
onClick?: () => void; onClick?: () => void;
isDisplayModeContentEmpty?: boolean;
}; };
export function EditableFieldDisplayMode({ export function EditableFieldDisplayMode({
children, children,
disableClick, disableClick,
onClick, onClick,
isDisplayModeContentEmpty,
}: React.PropsWithChildren<OwnProps>) { }: React.PropsWithChildren<OwnProps>) {
return ( return (
<EditableFieldNormalModeOuterContainer <EditableFieldNormalModeOuterContainer
onClick={disableClick ? undefined : onClick} onClick={disableClick ? undefined : onClick}
disableClick={disableClick} disableClick={disableClick}
isDisplayModeContentEmpty={isDisplayModeContentEmpty}
> >
<EditableFieldNormalModeInnerContainer> <EditableFieldNormalModeInnerContainer>
{children} {children}

View File

@ -34,7 +34,7 @@ export function EditableFieldEditButton({ customHotkeyScope }: OwnProps) {
const { openEditableField } = useEditableField(); const { openEditableField } = useEditableField();
function handleClick() { function handleClick() {
openEditableField(customHotkeyScope); openEditableField();
} }
return ( return (

View File

@ -0,0 +1,52 @@
import { useEffect } from 'react';
import { HotkeyScope } from '@/ui/hotkey/types/HotkeyScope';
import { isSameHotkeyScope } from '@/ui/hotkey/utils/isSameHotkeyScope';
import { useRecoilScopedState } from '@/ui/recoil-scope/hooks/useRecoilScopedState';
import { customEditHotkeyScopeForFieldScopedState } from '../states/customEditHotkeyScopeForFieldScopedState';
import { FieldContext } from '../states/FieldContext';
import { parentHotkeyScopeForFieldScopedState } from '../states/parentHotkeyScopeForFieldScopedState';
export function useBindFieldHotkeyScope({
customEditHotkeyScope,
parentHotkeyScope,
}: {
customEditHotkeyScope?: HotkeyScope;
parentHotkeyScope?: HotkeyScope;
}) {
const [customEditHotkeyScopeForField, setCustomEditHotkeyScopeForField] =
useRecoilScopedState(
customEditHotkeyScopeForFieldScopedState,
FieldContext,
);
const [parentHotkeyScopeForField, setParentHotkeyScopeForField] =
useRecoilScopedState(parentHotkeyScopeForFieldScopedState, FieldContext);
useEffect(() => {
if (
customEditHotkeyScope &&
!isSameHotkeyScope(customEditHotkeyScope, customEditHotkeyScopeForField)
) {
setCustomEditHotkeyScopeForField(customEditHotkeyScope);
}
}, [
customEditHotkeyScope,
customEditHotkeyScopeForField,
setCustomEditHotkeyScopeForField,
]);
useEffect(() => {
if (
parentHotkeyScope &&
!isSameHotkeyScope(parentHotkeyScope, parentHotkeyScopeForField)
) {
setParentHotkeyScopeForField(parentHotkeyScope);
}
}, [
parentHotkeyScope,
parentHotkeyScopeForField,
setParentHotkeyScopeForField,
]);
}

View File

@ -1,33 +1,50 @@
import { useSetHotkeyScope } from '@/ui/hotkey/hooks/useSetHotkeyScope'; import { useSetHotkeyScope } from '@/ui/hotkey/hooks/useSetHotkeyScope';
import { HotkeyScope } from '@/ui/hotkey/types/HotkeyScope';
import { useRecoilScopedState } from '@/ui/recoil-scope/hooks/useRecoilScopedState'; import { useRecoilScopedState } from '@/ui/recoil-scope/hooks/useRecoilScopedState';
import { customEditHotkeyScopeForFieldScopedState } from '../states/customEditHotkeyScopeForFieldScopedState';
import { FieldContext } from '../states/FieldContext'; import { FieldContext } from '../states/FieldContext';
import { isFieldInEditModeScopedState } from '../states/isFieldInEditModeScopedState'; import { isFieldInEditModeScopedState } from '../states/isFieldInEditModeScopedState';
import { parentHotkeyScopeForFieldScopedState } from '../states/parentHotkeyScopeForFieldScopedState';
import { EditableFieldHotkeyScope } from '../types/EditableFieldHotkeyScope'; import { EditableFieldHotkeyScope } from '../types/EditableFieldHotkeyScope';
// TODO: use atoms for hotkey scopes // TODO: use atoms for hotkey scopes
export function useEditableField(parentHotkeyScope?: HotkeyScope) { export function useEditableField() {
const [isFieldInEditMode, setIsFieldInEditMode] = useRecoilScopedState( const [isFieldInEditMode, setIsFieldInEditMode] = useRecoilScopedState(
isFieldInEditModeScopedState, isFieldInEditModeScopedState,
FieldContext, FieldContext,
); );
const [customEditHotkeyScopeForField] = useRecoilScopedState(
customEditHotkeyScopeForFieldScopedState,
FieldContext,
);
const [parentHotkeyScopeForField] = useRecoilScopedState(
parentHotkeyScopeForFieldScopedState,
FieldContext,
);
const setHotkeyScope = useSetHotkeyScope(); const setHotkeyScope = useSetHotkeyScope();
function closeEditableField() { function closeEditableField() {
setIsFieldInEditMode(false); setIsFieldInEditMode(false);
if (parentHotkeyScope) { if (parentHotkeyScopeForField) {
setHotkeyScope(parentHotkeyScope.scope, parentHotkeyScope.customScopes); setHotkeyScope(
parentHotkeyScopeForField.scope,
parentHotkeyScopeForField.customScopes,
);
} }
} }
function openEditableField(customHotkeyScope?: HotkeyScope) { function openEditableField() {
setIsFieldInEditMode(true); setIsFieldInEditMode(true);
if (customHotkeyScope) { if (customEditHotkeyScopeForField) {
setHotkeyScope(customHotkeyScope.scope, customHotkeyScope.customScopes); setHotkeyScope(
customEditHotkeyScopeForField.scope,
customEditHotkeyScopeForField.customScopes,
);
} else { } else {
setHotkeyScope(EditableFieldHotkeyScope.EditableField); setHotkeyScope(EditableFieldHotkeyScope.EditableField);
} }

View File

@ -0,0 +1,11 @@
import { atomFamily } from 'recoil';
import { HotkeyScope } from '@/ui/hotkey/types/HotkeyScope';
export const customEditHotkeyScopeForFieldScopedState = atomFamily<
HotkeyScope | null,
string
>({
key: 'customEditHotkeyScopeForFieldScopedState',
default: null,
});

View File

@ -0,0 +1,11 @@
import { atomFamily } from 'recoil';
import { HotkeyScope } from '@/ui/hotkey/types/HotkeyScope';
export const parentHotkeyScopeForFieldScopedState = atomFamily<
HotkeyScope | null,
string
>({
key: 'parentHotkeyScopeForFieldScopedState',
default: null,
});

View File

@ -10,12 +10,8 @@ type OwnProps = {
parentHotkeyScope?: HotkeyScope; parentHotkeyScope?: HotkeyScope;
}; };
export function EditableFieldEditModeDate({ export function EditableFieldEditModeDate({ value, onChange }: OwnProps) {
value, const { closeEditableField } = useEditableField();
onChange,
parentHotkeyScope,
}: OwnProps) {
const { closeEditableField } = useEditableField(parentHotkeyScope);
function handleChange(newValue: string) { function handleChange(newValue: string) {
onChange?.(newValue); onChange?.(newValue);

View File

@ -0,0 +1,8 @@
import { HotkeyScope } from '../types/HotkeyScope';
export function isSameHotkeyScope(
hotkeyScope1: HotkeyScope | undefined | null,
hotkeyScope2: HotkeyScope | undefined | null,
): boolean {
return JSON.stringify(hotkeyScope1) === JSON.stringify(hotkeyScope2);
}

View File

@ -0,0 +1,51 @@
import styled from '@emotion/styled';
type Props = {
softFocus?: boolean;
onClick?: () => void;
};
export const EditableCellDisplayModeOuterContainer = styled.div<
Pick<Props, 'softFocus'>
>`
align-items: center;
display: flex;
height: 100%;
overflow: hidden;
padding-left: ${({ theme }) => theme.spacing(2)};
padding-right: ${({ theme }) => theme.spacing(1)};
width: 100%;
${(props) =>
props.softFocus
? `background: ${props.theme.background.transparent.secondary};
border-radius: ${props.theme.border.radius.sm};
box-shadow: inset 0 0 0 1px ${props.theme.font.color.extraLight};`
: ''}
`;
export const EditableCellDisplayModeInnerContainer = styled.div`
align-items: center;
display: flex;
height: 100%;
overflow: hidden;
width: 100%;
`;
export function EditableCellDisplayContainer({
children,
softFocus,
onClick,
}: React.PropsWithChildren<Props>) {
return (
<EditableCellDisplayModeOuterContainer
onClick={onClick}
softFocus={softFocus}
>
<EditableCellDisplayModeInnerContainer>
{children}
</EditableCellDisplayModeInnerContainer>
</EditableCellDisplayModeOuterContainer>
);
}

View File

@ -1,51 +1,19 @@
import styled from '@emotion/styled';
import { useSetSoftFocusOnCurrentCell } from '../hooks/useSetSoftFocusOnCurrentCell'; import { useSetSoftFocusOnCurrentCell } from '../hooks/useSetSoftFocusOnCurrentCell';
type Props = { import { EditableCellDisplayContainer } from './EditableCellContainer';
softFocus?: boolean;
};
export const EditableCellNormalModeOuterContainer = styled.div<Props>`
align-items: center;
display: flex;
height: 100%;
overflow: hidden;
padding-left: ${({ theme }) => theme.spacing(2)};
padding-right: ${({ theme }) => theme.spacing(1)};
width: 100%;
${(props) =>
props.softFocus
? `background: ${props.theme.background.transparent.secondary};
border-radius: ${props.theme.border.radius.sm};
box-shadow: inset 0 0 0 1px ${props.theme.font.color.extraLight};`
: ''}
`;
export const EditableCellNormalModeInnerContainer = styled.div`
align-items: center;
display: flex;
height: 100%;
overflow: hidden;
width: 100%;
`;
export function EditableCellDisplayMode({ export function EditableCellDisplayMode({
children, children,
}: React.PropsWithChildren<unknown>) { }: React.PropsWithChildren<unknown>) {
const setSoftFocusOnCurrentCell = useSetSoftFocusOnCurrentCell(); const setSoftFocusOnCurrentCell = useSetSoftFocusOnCurrentCell();
function handleOnClick() { function handleClick() {
setSoftFocusOnCurrentCell(); setSoftFocusOnCurrentCell();
} }
return ( return (
<EditableCellNormalModeOuterContainer onClick={handleOnClick}> <EditableCellDisplayContainer onClick={handleClick}>
<EditableCellNormalModeInnerContainer> {children}
{children} </EditableCellDisplayContainer>
</EditableCellNormalModeInnerContainer>
</EditableCellNormalModeOuterContainer>
); );
} }

View File

@ -1,4 +1,4 @@
import React from 'react'; import { PropsWithChildren } from 'react';
import { useScopedHotkeys } from '@/ui/hotkey/hooks/useScopedHotkeys'; import { useScopedHotkeys } from '@/ui/hotkey/hooks/useScopedHotkeys';
import { HotkeyScope } from '@/ui/hotkey/types/HotkeyScope'; import { HotkeyScope } from '@/ui/hotkey/types/HotkeyScope';
@ -7,15 +7,16 @@ import { isNonTextWritingKey } from '@/ui/hotkey/utils/isNonTextWritingKey';
import { TableHotkeyScope } from '../../types/TableHotkeyScope'; import { TableHotkeyScope } from '../../types/TableHotkeyScope';
import { useEditableCell } from '../hooks/useEditableCell'; import { useEditableCell } from '../hooks/useEditableCell';
import { import { EditableCellDisplayContainer } from './EditableCellContainer';
EditableCellNormalModeInnerContainer,
EditableCellNormalModeOuterContainer, type OwnProps = PropsWithChildren<{
} from './EditableCellDisplayMode'; editHotkeyScope?: HotkeyScope;
}>;
export function EditableCellSoftFocusMode({ export function EditableCellSoftFocusMode({
children, children,
editHotkeyScope, editHotkeyScope,
}: React.PropsWithChildren<{ editHotkeyScope?: HotkeyScope }>) { }: OwnProps) {
const { openEditableCell } = useEditableCell(); const { openEditableCell } = useEditableCell();
function openEditMode() { function openEditMode() {
@ -61,13 +62,8 @@ export function EditableCellSoftFocusMode({
} }
return ( return (
<EditableCellNormalModeOuterContainer <EditableCellDisplayContainer onClick={handleClick} softFocus>
onClick={handleClick} {children}
softFocus={true} </EditableCellDisplayContainer>
>
<EditableCellNormalModeInnerContainer>
{children}
</EditableCellNormalModeInnerContainer>
</EditableCellNormalModeOuterContainer>
); );
} }

View File

@ -1,11 +1,4 @@
import { import { ChangeEvent, ReactNode, useEffect, useRef, useState } from 'react';
ChangeEvent,
ComponentType,
ReactNode,
useEffect,
useRef,
useState,
} from 'react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { textInputStyle } from '@/ui/themes/effects'; import { textInputStyle } from '@/ui/themes/effects';
@ -13,18 +6,11 @@ import { textInputStyle } from '@/ui/themes/effects';
import { EditableCell } from '../components/EditableCell'; import { EditableCell } from '../components/EditableCell';
export type EditableChipProps = { export type EditableChipProps = {
id: string;
placeholder?: string; placeholder?: string;
value: string; value: string;
picture: string;
changeHandler: (updated: string) => void; changeHandler: (updated: string) => void;
editModeHorizontalAlign?: 'left' | 'right'; editModeHorizontalAlign?: 'left' | 'right';
ChipComponent: ComponentType<{ ChipComponent: React.ReactNode;
id: string;
name: string;
picture: string;
isOverlapped?: boolean;
}>;
commentThreadCount?: number; commentThreadCount?: number;
onCommentClick?: (event: React.MouseEvent<HTMLDivElement>) => void; onCommentClick?: (event: React.MouseEvent<HTMLDivElement>) => void;
rightEndContents?: ReactNode[]; rightEndContents?: ReactNode[];
@ -52,11 +38,9 @@ const RightContainer = styled.div`
// TODO: move right end content in EditableCell // TODO: move right end content in EditableCell
export function EditableCellChip({ export function EditableCellChip({
id,
value, value,
placeholder, placeholder,
changeHandler, changeHandler,
picture,
editModeHorizontalAlign, editModeHorizontalAlign,
ChipComponent, ChipComponent,
rightEndContents, rightEndContents,
@ -95,7 +79,7 @@ export function EditableCellChip({
onCancel={onCancel} onCancel={onCancel}
nonEditModeContent={ nonEditModeContent={
<NoEditModeContainer> <NoEditModeContainer>
<ChipComponent id={id} name={inputValue} picture={picture} /> {ChipComponent}
<RightContainer> <RightContainer>
{rightEndContents && {rightEndContents &&
rightEndContents.length > 0 && rightEndContents.length > 0 &&