diff --git a/src/s2-homeworks/hw04/common/c1-SuperInputText/SuperInputText.tsx b/src/s2-homeworks/hw04/common/c1-SuperInputText/SuperInputText.tsx index 60de30f..f36f79f 100644 --- a/src/s2-homeworks/hw04/common/c1-SuperInputText/SuperInputText.tsx +++ b/src/s2-homeworks/hw04/common/c1-SuperInputText/SuperInputText.tsx @@ -15,7 +15,6 @@ type SuperInputTextPropsType = Omit & { // и + const SuperInputText: React.FC = ( { - // type, // достаём и игнорируем чтоб нельзя было задать другой тип инпута onChange, onChangeText, onKeyPress, onEnter, error, diff --git a/src/s2-homeworks/hw05/pages/Error404.tsx b/src/s2-homeworks/hw05/pages/Error404.tsx index d6cd306..49a0dc3 100644 --- a/src/s2-homeworks/hw05/pages/Error404.tsx +++ b/src/s2-homeworks/hw05/pages/Error404.tsx @@ -2,7 +2,7 @@ import React from 'react' const Error404 = () => { return ( -
+
404
Page not found!
—ฅ/ᐠ.̫ .ᐟ\ฅ—
diff --git a/src/s2-homeworks/hw05/pages/Junior.tsx b/src/s2-homeworks/hw05/pages/Junior.tsx index 4966092..3b84e34 100644 --- a/src/s2-homeworks/hw05/pages/Junior.tsx +++ b/src/s2-homeworks/hw05/pages/Junior.tsx @@ -1,10 +1,11 @@ import React from 'react' +import HW6 from '../../hw06/HW6' function Junior() { return (
junior page - {/**/} + {/**/} {/**/} {/**/} diff --git a/src/s2-homeworks/hw06/HW6.tsx b/src/s2-homeworks/hw06/HW6.tsx new file mode 100644 index 0000000..408fae1 --- /dev/null +++ b/src/s2-homeworks/hw06/HW6.tsx @@ -0,0 +1,44 @@ +import React, {useState} from 'react' +import SuperEditableSpan from './common/c4-SuperEditableSpan/SuperEditableSpan' +import {restoreState, saveState} from './localStorage/localStorage' +import s2 from '../../s1-main/App.module.css' +import SuperButton from '../hw04/common/c2-SuperButton/SuperButton' + +const HW6 = () => { + const [value, setValue] = useState('') + + const save = () => { + saveState('hw6-editable-span-value', value) + } + const restore = () => { // делают студенты + setValue(restoreState('hw6-editable-span-value', '')) + } + + return ( +
+
+ {/*можно убрать этот тег*/} + +
homeworks 6
+ + {/*should work (должно работать)*/} +
+ +
+ save to ls + get from ls + +
+ {/*можно убрать этот тег*/} +
+ {/*можно убрать этот тег*/} +
+ ) +} + +export default HW6 diff --git a/src/s2-homeworks/hw06/common/c4-SuperEditableSpan/SuperEditableSpan.module.css b/src/s2-homeworks/hw06/common/c4-SuperEditableSpan/SuperEditableSpan.module.css new file mode 100644 index 0000000..fa55835 --- /dev/null +++ b/src/s2-homeworks/hw06/common/c4-SuperEditableSpan/SuperEditableSpan.module.css @@ -0,0 +1,9 @@ +.span { + display: inline-block; + + height: 31px; + padding-top: 10px; + + cursor: pointer; + color: #77aaff; +} \ No newline at end of file diff --git a/src/s2-homeworks/hw06/common/c4-SuperEditableSpan/SuperEditableSpan.tsx b/src/s2-homeworks/hw06/common/c4-SuperEditableSpan/SuperEditableSpan.tsx new file mode 100644 index 0000000..78824bc --- /dev/null +++ b/src/s2-homeworks/hw06/common/c4-SuperEditableSpan/SuperEditableSpan.tsx @@ -0,0 +1,78 @@ +import React, {DetailedHTMLProps, InputHTMLAttributes, HTMLAttributes, useState} from 'react' +import s from './SuperEditableSpan.module.css' +import SuperInputText from '../../../hw04/common/c1-SuperInputText/SuperInputText' + +// тип пропсов обычного инпута +type DefaultInputPropsType = DetailedHTMLProps, HTMLInputElement> +// тип пропсов обычного спана +type DefaultSpanPropsType = DetailedHTMLProps, HTMLSpanElement> + +// здесь мы говорим что у нашего инпута будут такие же пропсы как у обычного инпута, кроме type +// (чтоб не писать value: string, onChange: ...; они уже все описаны в DefaultInputPropsType) +type SuperEditableSpanType = Omit & { // и + ещё пропсы которых нет в стандартном инпуте + onChangeText?: (value: string) => void + onEnter?: () => void + error?: string + + spanProps?: DefaultSpanPropsType // пропсы для спана +} + +const SuperEditableSpan: React.FC = ( + { + autoFocus, + onBlur, + onEnter, + spanProps, + + ...restProps// все остальные пропсы попадут в объект restProps + } +) => { + const [editMode, setEditMode] = useState(false) + const {children, onDoubleClick, className, ...restSpanProps} = spanProps || {} + + const onEnterCallback = () => { + setEditMode(false) // выключить editMode при нажатии Enter // делают студенты + + onEnter?.() + } + const onBlurCallback = (e: React.FocusEvent) => { + setEditMode(false) // выключить editMode при нажатии за пределами инпута // делают студенты + + onBlur?.(e) + } + const onDoubleClickCallBack = (e: React.MouseEvent) => { + setEditMode(true) // включить editMode при двойном клике // делают студенты + + onDoubleClick?.(e) + } + + const spanClassName = `${s.span} ${className ? className : ''}` + + return ( + <> + {editMode + ? ( + + ) : ( + + {/*если нет захардкодженного текста для спана, то значение инпута*/} + ✎ {children || restProps.value} + + ) + } + + ) +} + +export default SuperEditableSpan diff --git a/src/s2-homeworks/hw06/localStorage/localStorage.ts b/src/s2-homeworks/hw06/localStorage/localStorage.ts new file mode 100644 index 0000000..d4ab677 --- /dev/null +++ b/src/s2-homeworks/hw06/localStorage/localStorage.ts @@ -0,0 +1,27 @@ +// вот вам функция для сохранения объектов в память браузера +// (данные в этом хранилище сохраняться даже при перезагрузке компа): +export function saveState(key: string, state: T) { + const stateAsString = JSON.stringify(state) + localStorage.setItem(key, stateAsString) +} + +// и вот вам функция для получения сохранённого объекта в памяти браузера: +export function restoreState(key: string, defaultState: T) { + let state = defaultState + const stateAsString = localStorage.getItem(key) + if (stateAsString !== null) state = JSON.parse(stateAsString) as T + return state +} + +// --------------------------------------------------------------------------------------------------------------- +// пример использования: +type StateType = { + x: string + y: number +} + +// сохраняем объект типа StateType в ячейке 'test' +saveState('test', {x: 'A', y: 1}) + +// получем в переменную state объект из ячейки 'test' или дэфолтный объект если ячейка пуста +const state: StateType = restoreState('test', {x: '', y: 0})