final ref hw6

This commit is contained in:
neko
2022-09-20 13:02:00 +03:00
parent 6380529923
commit 5efc1d9d37
5 changed files with 64 additions and 41 deletions

View File

@@ -1,4 +1,8 @@
.buttonsContainer { .buttonsContainer {
display: flex; display: flex;
gap: 24px; gap: 24px;
}
.editableSpanContainer {
height: 50px;
} }

View File

@@ -5,6 +5,12 @@ import s2 from '../../s1-main/App.module.css'
import SuperButton from '../hw04/common/c2-SuperButton/SuperButton' import SuperButton from '../hw04/common/c2-SuperButton/SuperButton'
import s from './HW6.module.css' import s from './HW6.module.css'
/*
* 1 - в файле SuperEditableSpan.tsx дописать логику функций onEnterCallback, onBlurCallback, onDoubleClickCallBack
* 2 - дописать логику функции restore
* 3 - сделать стили в соответствии с дизайном
*/
const HW6 = () => { const HW6 = () => {
const [value, setValue] = useState<string>('') const [value, setValue] = useState<string>('')
@@ -22,27 +28,26 @@ const HW6 = () => {
{/*should work (должно работать)*/} {/*should work (должно работать)*/}
<div className={s2.hw}> <div className={s2.hw}>
<div> <div className={s.editableSpanContainer}>
<SuperEditableSpan <SuperEditableSpan
id={'hw6-spanable-input'} id={'hw6-spanable-input'}
value={value} value={value}
onChangeText={setValue} onChangeText={setValue}
spanProps={{ spanProps={{
children: value ? undefined : 'enter text...', defaultText: 'enter text...'
id: 'hw6-editable-span',
}} }}
/> />
</div> </div>
<div className={s.buttonsContainer}> <div className={s.buttonsContainer}>
<SuperButton id={'hw6-save'} onClick={save}> <SuperButton id={'hw6-save'} onClick={save}>
save to ls Save to ls
</SuperButton> </SuperButton>
<SuperButton <SuperButton
id={'hw6-restore'} id={'hw6-restore'}
onClick={restore} onClick={restore}
xType={'secondary'} xType={'secondary'}
> >
get from ls Get from ls
</SuperButton> </SuperButton>
</div> </div>
</div> </div>

View File

@@ -1,17 +1,24 @@
.span { .spanBlock {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10px; gap: 10px;
margin-bottom: 28px; }
cursor: pointer;
.span {
color: #0080FF;
font-family: 'Montserrat', sans-serif; font-family: 'Montserrat', sans-serif;
font-weight: 500; font-weight: 500;
font-size: 16px; font-size: 16px;
line-height: 20px; line-height: 20px;
color: #0080FF; cursor: pointer;
} }
.input { .input {
margin-bottom: 16px;
width: 276px; width: 276px;
margin-bottom: 16px;
}
.pen {
width: 24px;
height: 24px;
} }

View File

@@ -7,16 +7,13 @@ import React, {
import s from './SuperEditableSpan.module.css' import s from './SuperEditableSpan.module.css'
import SuperInputText from '../../../hw04/common/c1-SuperInputText/SuperInputText' import SuperInputText from '../../../hw04/common/c1-SuperInputText/SuperInputText'
import editIcon from './editIcon.svg' import editIcon from './editIcon.svg'
// тип пропсов обычного инпута // тип пропсов обычного инпута
type DefaultInputPropsType = DetailedHTMLProps< type DefaultInputPropsType = DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>,
InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
HTMLInputElement
>
// тип пропсов обычного спана // тип пропсов обычного спана
type DefaultSpanPropsType = DetailedHTMLProps< type DefaultSpanPropsType = DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>,
HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>
HTMLSpanElement
>
// здесь мы говорим что у нашего инпута будут такие же пропсы как у обычного инпута, кроме type // здесь мы говорим что у нашего инпута будут такие же пропсы как у обычного инпута, кроме type
// (чтоб не писать value: string, onChange: ...; они уже все описаны в DefaultInputPropsType) // (чтоб не писать value: string, onChange: ...; они уже все описаны в DefaultInputPropsType)
@@ -26,20 +23,23 @@ type SuperEditableSpanType = Omit<DefaultInputPropsType, 'type'> & {
onEnter?: () => void onEnter?: () => void
error?: string error?: string
spanProps?: DefaultSpanPropsType // пропсы для спана spanProps?: DefaultSpanPropsType & {defaultText?: string}// пропсы для спана
} }
const SuperEditableSpan: React.FC<SuperEditableSpanType> = ({ const SuperEditableSpan: React.FC<SuperEditableSpanType> = (
autoFocus, {
onBlur, id,
onEnter, autoFocus,
spanProps, onBlur,
onEnter,
spanProps,
...restProps // все остальные пропсы попадут в объект restProps ...restProps // все остальные пропсы попадут в объект restProps
}) => { }
) => {
const [editMode, setEditMode] = useState<boolean>(false) const [editMode, setEditMode] = useState<boolean>(false)
const { children, onDoubleClick, className, ...restSpanProps } = const {children, onDoubleClick, className, defaultText, ...restSpanProps} =
spanProps || {} spanProps || {}
const onEnterCallback = () => { const onEnterCallback = () => {
setEditMode(false) // выключить editMode при нажатии Enter // делают студенты setEditMode(false) // выключить editMode при нажатии Enter // делают студенты
@@ -59,12 +59,14 @@ const SuperEditableSpan: React.FC<SuperEditableSpanType> = ({
onDoubleClick?.(e) onDoubleClick?.(e)
} }
const spanClassName = `${s.span} ${className ? className : ''}` const spanClassName = s.span
+ (className ? ' ' + className : '')
return ( return (
<> <>
{editMode ? ( {editMode ? (
<SuperInputText <SuperInputText
id={id}
autoFocus={autoFocus || true} autoFocus={autoFocus || true}
onBlur={onBlurCallback} onBlur={onBlurCallback}
onEnter={onEnterCallback} onEnter={onEnterCallback}
@@ -72,20 +74,23 @@ const SuperEditableSpan: React.FC<SuperEditableSpanType> = ({
{...restProps} // отдаём инпуту остальные пропсы если они есть (value например там внутри) {...restProps} // отдаём инпуту остальные пропсы если они есть (value например там внутри)
/> />
) : ( ) : (
<span <div className={s.spanBlock}>
onDoubleClick={onDoubleClickCallBack}
className={spanClassName}
{...restSpanProps}
>
{/*если нет захардкодженного текста для спана, то значение инпута*/}
<img <img
src={editIcon} src={editIcon}
width={'24px'} className={s.pen}
height={'24px'}
alt={'edit'} alt={'edit'}
/>{' '} />
{children || restProps.value} <span
</span> id={id ? id + '-span' : undefined}
onDoubleClick={onDoubleClickCallBack}
className={spanClassName}
{...restSpanProps}
>
{/*если нет захардкодженного текста для спана, то значение инпута*/}
{children || restProps.value || defaultText}
</span>
</div>
)} )}
</> </>
) )

View File

@@ -15,6 +15,7 @@ export function restoreState<T>(key: string, defaultState: T) {
// --------------------------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------------------------
// пример использования: // пример использования:
/*
type StateType = { type StateType = {
x: string x: string
y: number y: number
@@ -23,5 +24,6 @@ type StateType = {
// сохраняем объект типа StateType в ячейке 'test' // сохраняем объект типа StateType в ячейке 'test'
saveState<StateType>('test', { x: 'A', y: 1 }) saveState<StateType>('test', { x: 'A', y: 1 })
// получем в переменную state объект из ячейки 'test' или дэфолтный объект если ячейка пуста // получаем в переменную state объект из ячейки 'test' или дэфолтный объект если ячейка пуста
const state: StateType = restoreState<StateType>('test', { x: '', y: 0 }) const state: StateType = restoreState<StateType>('test', { x: '', y: 0 })
*/