add hw 11

This commit is contained in:
neko
2022-06-19 19:55:42 +03:00
parent 9c0c1c2e14
commit 598d34d5c7
5 changed files with 154 additions and 1 deletions

View File

@@ -1,12 +1,13 @@
import React from 'react' import React from 'react'
import HW10 from '../../hw10/HW10' import HW10 from '../../hw10/HW10'
import HW11 from '../../hw11/HW11'
function JuniorPlus() { function JuniorPlus() {
return ( return (
<div id={'hw5-page-junior-plus'}> <div id={'hw5-page-junior-plus'}>
junior plus page junior plus page
<HW10/> <HW10/>
{/*<HW11/>*/} <HW11/>
{/*<HW12/>*/} {/*<HW12/>*/}
{/*<HW13/>*/} {/*<HW13/>*/}
</div> </div>

View File

@@ -0,0 +1,48 @@
import React, {useState} from 'react'
import SuperRange from './common/c7-SuperRange/SuperRange'
import SuperDoubleRange from './common/c8-SuperDoubleRange/SuperDoubleRange'
import s2 from '../../s1-main/App.module.css'
import {restoreState} from '../hw06/localStorage/localStorage'
function HW11() {
const [value1, setValue1] = useState(restoreState<number>('hw11-value1', 0))
const [value2, setValue2] = useState(restoreState<number>('hw11-value2', 100))
const change = (values: [number, number]) => {
value1 !== values[0] && setValue1(values[0])
value2 !== values[1] && setValue2(values[1])
}
return (
<div id={'hw11'} className={s2.hw}>
<hr/>
{/*можно убрать этот тег*/}
{/*should work (должно работать)*/}
<div>
<span id={'hw11-value'} style={{display: 'inline-block', width: 32}}>{value1}</span>
<SuperRange
// сделать так чтоб value1 изменялось
value={value1}
onChangeRange={setValue1}
/>
</div>
<div>
<span id={'hw11-value-1'} style={{display: 'inline-block', width: 32}}>{value1}</span>
<SuperDoubleRange
value={[value1, value2]}
onChangeRange={change}
/>
<span id={'hw11-value-2'} style={{display: 'inline-block', width: 32}}>{value2}</span>
</div>
<hr/>
{/*можно убрать этот тег*/}
<hr/>
{/*можно убрать этот тег*/}
</div>
)
}
export default HW11

View File

@@ -0,0 +1,21 @@
.range {
appearance: none;
width: 160px;
outline: none;
border-radius: 3px;
background: #99ff99;
}
.range::-webkit-slider-thumb {
appearance: none;
position: relative;
width: 16px;
height: 16px;
top: 3px;
margin-top: -6px;
background: red;
cursor: pointer;
z-index: 2;
}

View File

@@ -0,0 +1,45 @@
import React, {ChangeEvent, DetailedHTMLProps, InputHTMLAttributes} from 'react'
import s from './SuperRange.module.css'
// тип пропсов обычного инпута
type DefaultInputPropsType = DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
// здесь мы говорим что у нашего инпута будут такие же пропсы как у обычного инпута
// (чтоб не писать value: string, onChange: ...; они уже все описаны в DefaultInputPropsType)
type SuperRangePropsType = DefaultInputPropsType & { // и + ещё пропсы которых нет в стандартном инпуте
onChangeRange?: (value: number) => void
};
const SuperRange: React.FC<SuperRangePropsType> = (
{
type, // достаём и игнорируем чтоб нельзя было задать другой тип инпута
onChange, onChangeRange,
className,
...restProps// все остальные пропсы попадут в объект restProps
}
) => {
const onChangeCallback = (e: ChangeEvent<HTMLInputElement>) => {
onChange && onChange(e) // сохраняем старую функциональность
onChangeRange && onChangeRange(+e.currentTarget.value)
}
const finalRangeClassName = `${s.range} ${className ? className : ''}`
// взять одинарный ползунок из материал-юай и повесить на него ид
return (
<>
<input
id={'hw11-single-slider'}
type={'range'}
onChange={onChangeCallback}
className={finalRangeClassName}
{...restProps} // отдаём инпуту остальные пропсы если они есть (value например там внутри)
/>
</>
)
}
export default SuperRange

View File

@@ -0,0 +1,38 @@
import React, {DetailedHTMLProps, InputHTMLAttributes} from 'react'
import SuperRange from '../c7-SuperRange/SuperRange'
type DefaultInputPropsType = DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
type SuperDoubleRangePropsType = Omit<DefaultInputPropsType, 'value'> & {
onChangeRange?: (value: [number, number]) => void
value?: [number, number]
// min, max, step, disable, ...
}
const SuperDoubleRange: React.FC<SuperDoubleRangePropsType> = (
{
onChangeRange, value,
// min, max, step, disable, ...
...restProps
}
) => {
// сделать самому, можно подключать библиотеки
const [value1, value2] = value || [-1, -1]
const change1 = (n: number) => {
if (n <= value2) onChangeRange?.([n, value2])
}
const change2 = (n: number) => {
if (value1 <= n) onChangeRange?.([value1, n])
}
// взять двойной ползунок из материал-юай и повесить на него ид
return (
<div id={'hw11-double-slider'} style={{position: "relative", display: "inline-block", width: 176}}>
<SuperRange style={{position: "absolute", top: -12}} value={value?.[0]} onChangeRange={change1} {...restProps}/>
<SuperRange style={{position: "absolute", top: -12}} value={value?.[1]} onChangeRange={change2} {...restProps}/>
</div>
)
}
export default SuperDoubleRange