Skip to content

Commit

Permalink
Merge pull request #65 from FRIED-NOTE/64-design-update-editor
Browse files Browse the repository at this point in the history
64 design update editor
  • Loading branch information
strawji02 authored Nov 23, 2023
2 parents ab0413a + dec2189 commit 6c6e073
Show file tree
Hide file tree
Showing 4 changed files with 163 additions and 38 deletions.
7 changes: 7 additions & 0 deletions src/pages/404.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface NotFoundProps {}

function NotFound({ ...props }: NotFoundProps) {
return <>404 not found</>;
}

export default NotFound;
9 changes: 8 additions & 1 deletion src/pages/post/components/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Stack, Stroke } from '@base';
import { css } from '@emotion/react';
import { produce } from 'immer';
import { ChangeEvent, useEffect, useRef, useState } from 'react';
import { Navigate } from 'react-router-dom';
import Image from './Editor/Image';
import Ingredient, { IngredientType } from './Editor/Ingredient';
import TextInput, { TextInputValueItemType } from './Editor/TextInput';
Expand Down Expand Up @@ -74,6 +75,11 @@ function Editor({ onChange, ...props }: EditorProps) {
onChange(data);
}, [data]);

useEffect(() => {
if (data.text.length > 1000)
setData({ ...data, text: data.text.slice(0, 1000) });
}, [data]);

const handleTitleChange = (e: ChangeEvent<HTMLInputElement>) => {
setData({
...data,
Expand Down Expand Up @@ -268,6 +274,7 @@ function Editor({ onChange, ...props }: EditorProps) {
css={styles.input}
placeholder="레시피의 이름을 알려주세요."
onChange={handleTitleChange}
maxLength={13}
/>
<Stroke css={styles.stroke} />
</div>
Expand Down Expand Up @@ -334,7 +341,7 @@ function Editor({ onChange, ...props }: EditorProps) {
onFocusBlur={(isFocus) => handleFocusBlur(isFocus, index)}
/>
) : (
<>hi</>
<Navigate to="/404" />
),
)}
<div
Expand Down
1 change: 1 addition & 0 deletions src/pages/post/components/Editor/Image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const styles = {
{
borderRadius: DesignSystem.Round.solid,
margin: 2,
width: 672,
},
globalStyles.button,
),
Expand Down
184 changes: 147 additions & 37 deletions src/pages/post/components/Editor/Timer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ import { mergeRef } from '@/utils/components';
import DesignSystem from '@/utils/designSystem';
import { Group, Typography } from '@base';
import { css } from '@emotion/react';
import { forwardRef, useEffect, useRef, useState } from 'react';
import {
FocusEvent,
KeyboardEvent,
forwardRef,
useEffect,
useRef,
useState,
} from 'react';
import { keyDownEventHandler } from './utils';

const styles = {
Expand All @@ -14,22 +21,34 @@ const styles = {
background: DesignSystem.Color.background.gray,
alignSelf: 'start',
}),
input: css(DesignSystem.Text.body, {
padding: '4px 12px',
borderRadius: DesignSystem.Round.solid,
background: DesignSystem.Color.background.disabled,
margin: 1,
color: DesignSystem.Color.text.gray,
width: 'auto',
':focus': {
input: {
root: css({
padding: '4px 4px',
borderRadius: DesignSystem.Round.solid,
background: DesignSystem.Color.background.disabled,
margin: 1,
color: DesignSystem.Color.text.gray,
width: 'auto',
}),
rootFocus: css({
margin: 0,
border: '1px solid var(--secondary-green)',
background: DesignSystem.Color.background.white,
},
'::placeholder': {
}),
number: css(DesignSystem.Text.body, {
color: DesignSystem.Color.text.gray,
},
}),
padding: 0,
textAlign: 'right',
}),
numberSecond: css({
textAlign: 'left',
}),
numberFocus: css({ color: DesignSystem.Color.text.black }),
colone: css(DesignSystem.Text.body, {
color: DesignSystem.Color.text.gray,
padding: '0 4px',
}),
},
};

export interface TimerProps {
Expand All @@ -51,22 +70,107 @@ const Timer = forwardRef<HTMLInputElement, TimerProps>(function Timer(
}: TimerProps,
ref,
) {
const [inputValue, setInputValue] = useState('');
const timerRef = useRef<HTMLInputElement>(null);
const [minuteValue, setMinuteValue] = useState('10');
const [secondValue, setSecondValue] = useState('00');
const [isFocused, setIsFocused] = useState(false);
const minuteRef = useRef<HTMLInputElement>(null);
const secondRef = useRef<HTMLInputElement>(null);

const mergedRef = ref ? mergeRef(ref, timerRef) : timerRef;
const mergedRef = ref ? mergeRef(ref, minuteRef) : minuteRef;

const handleKeyDown = keyDownEventHandler({
onClickArrowKey,
onDelete,
onSubmit,
setValue: setInputValue,
value: inputValue,
});
const commonParam = { onClickArrowKey, onDelete, onSubmit };

const inputFocusCaretSet = (e: KeyboardEvent<HTMLInputElement>) => {
const currentPos = e.currentTarget.selectionStart;
currentPos && e.currentTarget.setSelectionRange(currentPos, currentPos + 1);
if (currentPos === 2) secondRef.current?.focus();
};

const handleKeyPress = (e: KeyboardEvent<HTMLInputElement>) => {
if (!/[0-9]/.test(e.key)) {
e.preventDefault();
}
};
const handleMinuteInput = (e: KeyboardEvent<HTMLInputElement>) => {
inputFocusCaretSet(e);
setMinuteValue(e.currentTarget.value);
};
const handleSecondInput = (e: KeyboardEvent<HTMLInputElement>) => {
inputFocusCaretSet(e);
setSecondValue(e.currentTarget.value);
};
const handleMinuteKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'ArrowRight' && e.currentTarget.selectionEnd === 2) {
secondRef.current?.focus();
return;
}
keyDownEventHandler({
setValue: setMinuteValue,
value: minuteValue,
...commonParam,
})(e);
};
const handleSecondKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'ArrowLeft' && e.currentTarget.selectionStart === 0) {
minuteRef.current?.focus();
return;
} else if (e.key === 'Backspace' && e.currentTarget.selectionEnd === 0) {
minuteRef.current?.focus();
e.preventDefault();
return;
}
keyDownEventHandler({
setValue: setSecondValue,
value: secondValue,
...commonParam,
})(e);
};
const handleFocus = (e: FocusEvent<HTMLInputElement, Element>) => {
e.target.setSelectionRange(0, 1);
onFocusBlur?.(true);
setIsFocused(true);
};
const handelBlur = (e: FocusEvent<HTMLInputElement, Element>) => {
let minuteNewVal = minuteValue.padEnd(2, '0');
let secondNewVal = secondValue.padEnd(2, '0');
if (parseInt(secondNewVal) > 59) {
minuteNewVal = `${parseInt(minuteNewVal) + 1}`;
secondNewVal = `${parseInt(secondNewVal) - 60}`.padStart(2, '0');
}
if (parseInt(minuteNewVal) >= 59) {
minuteNewVal = '59';
secondNewVal = '00';
}
setMinuteValue(minuteNewVal);
setSecondValue(secondNewVal);
setIsFocused(false);
onFocusBlur?.(false);
};
const handleKeyUp = (e: KeyboardEvent<HTMLInputElement>) => {
let currentPos = e.currentTarget.selectionStart;
currentPos = currentPos === 0 ? 1 : currentPos === 2 ? 1 : currentPos;
if (e.key === 'ArrowRight')
currentPos &&
e.currentTarget.setSelectionRange(currentPos, currentPos + 1);
else if (e.key === 'ArrowLeft')
currentPos &&
e.currentTarget.setSelectionRange(currentPos - 1, currentPos);
};

useEffect(() => {
onChange?.(inputValue);
}, [inputValue]);
onChange?.(`${minuteValue}:${secondValue}}`);
}, [minuteValue, secondValue]);

const commonProps = {
maxLength: 2,
size: 2,
css: [styles.input.number, isFocused && styles.input.numberFocus],
onFocus: handleFocus,
onBlur: handelBlur,
autoFocus: true,
onKeyUp: handleKeyUp,
onKeyPress: handleKeyPress,
};

return (
<Group css={styles.root} gap={20}>
Expand All @@ -77,18 +181,24 @@ const Timer = forwardRef<HTMLInputElement, TimerProps>(function Timer(
</Typography>
</Group>
<Group gap={5}>
<input
ref={mergedRef}
value={inputValue}
onInput={(e) => setInputValue(e.currentTarget.value)}
onKeyDown={handleKeyDown}
onFocus={() => onFocusBlur?.(true)}
onBlur={() => onFocusBlur?.(false)}
autoFocus
placeholder="10:00"
size={4}
css={styles.input}
/>
<Group css={[styles.input.root, isFocused && styles.input.rootFocus]}>
<input
ref={mergedRef}
value={minuteValue}
onInput={handleMinuteInput}
onKeyDown={handleMinuteKeyDown}
{...commonProps}
/>
<div css={styles.input.colone}>:</div>
<input
ref={secondRef}
value={secondValue}
onInput={handleSecondInput}
onKeyDown={handleSecondKeyDown}
{...commonProps}
css={[...commonProps.css, styles.input.numberSecond]}
/>
</Group>
<IconStart />
</Group>
</Group>
Expand Down

0 comments on commit 6c6e073

Please sign in to comment.