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
21 changed files with 347 additions and 217 deletions

View File

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

View File

@ -2,7 +2,7 @@ import { css } from '@emotion/react';
import styled from '@emotion/styled';
export const EditableFieldNormalModeOuterContainer = styled.div<
Pick<OwnProps, 'disableClick'>
Pick<OwnProps, 'disableClick' | 'isDisplayModeContentEmpty'>
>`
align-items: center;
border-radius: ${({ theme }) => theme.border.radius.sm};
@ -15,7 +15,18 @@ export const EditableFieldNormalModeOuterContainer = styled.div<
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) => {
if (props.disableClick) {
@ -51,17 +62,20 @@ export const EditableFieldNormalModeInnerContainer = styled.div`
type OwnProps = {
disableClick?: boolean;
onClick?: () => void;
isDisplayModeContentEmpty?: boolean;
};
export function EditableFieldDisplayMode({
children,
disableClick,
onClick,
isDisplayModeContentEmpty,
}: React.PropsWithChildren<OwnProps>) {
return (
<EditableFieldNormalModeOuterContainer
onClick={disableClick ? undefined : onClick}
disableClick={disableClick}
isDisplayModeContentEmpty={isDisplayModeContentEmpty}
>
<EditableFieldNormalModeInnerContainer>
{children}

View File

@ -34,7 +34,7 @@ export function EditableFieldEditButton({ customHotkeyScope }: OwnProps) {
const { openEditableField } = useEditableField();
function handleClick() {
openEditableField(customHotkeyScope);
openEditableField();
}
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 { HotkeyScope } from '@/ui/hotkey/types/HotkeyScope';
import { useRecoilScopedState } from '@/ui/recoil-scope/hooks/useRecoilScopedState';
import { customEditHotkeyScopeForFieldScopedState } from '../states/customEditHotkeyScopeForFieldScopedState';
import { FieldContext } from '../states/FieldContext';
import { isFieldInEditModeScopedState } from '../states/isFieldInEditModeScopedState';
import { parentHotkeyScopeForFieldScopedState } from '../states/parentHotkeyScopeForFieldScopedState';
import { EditableFieldHotkeyScope } from '../types/EditableFieldHotkeyScope';
// TODO: use atoms for hotkey scopes
export function useEditableField(parentHotkeyScope?: HotkeyScope) {
export function useEditableField() {
const [isFieldInEditMode, setIsFieldInEditMode] = useRecoilScopedState(
isFieldInEditModeScopedState,
FieldContext,
);
const [customEditHotkeyScopeForField] = useRecoilScopedState(
customEditHotkeyScopeForFieldScopedState,
FieldContext,
);
const [parentHotkeyScopeForField] = useRecoilScopedState(
parentHotkeyScopeForFieldScopedState,
FieldContext,
);
const setHotkeyScope = useSetHotkeyScope();
function closeEditableField() {
setIsFieldInEditMode(false);
if (parentHotkeyScope) {
setHotkeyScope(parentHotkeyScope.scope, parentHotkeyScope.customScopes);
if (parentHotkeyScopeForField) {
setHotkeyScope(
parentHotkeyScopeForField.scope,
parentHotkeyScopeForField.customScopes,
);
}
}
function openEditableField(customHotkeyScope?: HotkeyScope) {
function openEditableField() {
setIsFieldInEditMode(true);
if (customHotkeyScope) {
setHotkeyScope(customHotkeyScope.scope, customHotkeyScope.customScopes);
if (customEditHotkeyScopeForField) {
setHotkeyScope(
customEditHotkeyScopeForField.scope,
customEditHotkeyScopeForField.customScopes,
);
} else {
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;
};
export function EditableFieldEditModeDate({
value,
onChange,
parentHotkeyScope,
}: OwnProps) {
const { closeEditableField } = useEditableField(parentHotkeyScope);
export function EditableFieldEditModeDate({ value, onChange }: OwnProps) {
const { closeEditableField } = useEditableField();
function handleChange(newValue: string) {
onChange?.(newValue);