mirror of
https://github.com/IgnatZakalinsky/home-works.git
synced 2026-01-28 12:32:45 +00:00
hw4
This commit is contained in:
@@ -1,3 +1,11 @@
|
|||||||
.App {
|
.App {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hw {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.hwTitle {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,19 +3,21 @@ import s from './App.module.css'
|
|||||||
import HW1 from '../s2-homeworks/hw01/HW1'
|
import HW1 from '../s2-homeworks/hw01/HW1'
|
||||||
import HW2 from '../s2-homeworks/hw02/HW2'
|
import HW2 from '../s2-homeworks/hw02/HW2'
|
||||||
import HW3 from '../s2-homeworks/hw03/HW3'
|
import HW3 from '../s2-homeworks/hw03/HW3'
|
||||||
|
import HW4 from '../s2-homeworks/hw04/HW4'
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
return (
|
return (
|
||||||
<div className={s.App}>
|
<div className={s.App}>
|
||||||
<div>react homeworks:</div>
|
<div>react homeworks:</div>
|
||||||
<HW1/>
|
|
||||||
<HW2/>
|
|
||||||
<HW3/>
|
|
||||||
{/*<HW4/>*/}
|
|
||||||
{/*<HW5/>*/}
|
|
||||||
|
|
||||||
</div>
|
<HW1/>
|
||||||
)
|
<HW2/>
|
||||||
|
<HW3/>
|
||||||
|
<HW4/>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App
|
export default App
|
||||||
@@ -2,6 +2,7 @@ import React from 'react'
|
|||||||
import Message from './Message'
|
import Message from './Message'
|
||||||
import MessageSender from './MessageSender'
|
import MessageSender from './MessageSender'
|
||||||
import s from './Message.module.css'
|
import s from './Message.module.css'
|
||||||
|
import s2 from '../../s1-main/App.module.css'
|
||||||
import FriendMessage from './FriendMessage'
|
import FriendMessage from './FriendMessage'
|
||||||
|
|
||||||
// нужно создать правильный тип вместо any
|
// нужно создать правильный тип вместо any
|
||||||
@@ -34,11 +35,11 @@ export const friendMessage0: MessageType = {
|
|||||||
|
|
||||||
const HW1 = () => {
|
const HW1 = () => {
|
||||||
return (
|
return (
|
||||||
<div id={'hw1'} className={s.hw1}>
|
<div id={'hw1'} className={s2.hw}>
|
||||||
<hr/>
|
<hr/>
|
||||||
{/*можно убрать этот тег*/}
|
{/*можно убрать этот тег*/}
|
||||||
|
|
||||||
<div className={s.hwTitle}>homeworks 1</div>
|
<div className={s2.hwTitle}>homeworks 1</div>
|
||||||
|
|
||||||
{/*проверка отображения (не менять)*/}
|
{/*проверка отображения (не менять)*/}
|
||||||
<Message message={message0}/>
|
<Message message={message0}/>
|
||||||
|
|||||||
@@ -1,11 +1,3 @@
|
|||||||
.hw1 {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.hwTitle {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.message {
|
.message {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: right;
|
justify-content: right;
|
||||||
|
|||||||
@@ -1,7 +1,3 @@
|
|||||||
.hw2 {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
width: 60px;
|
width: 60px;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, {useState} from 'react'
|
import React, {useState} from 'react'
|
||||||
import Affairs from './Affairs'
|
import Affairs from './Affairs'
|
||||||
import s from './Affairs.module.css'
|
import s from './Affairs.module.css'
|
||||||
import s2 from '../hw01/Message.module.css'
|
import s2 from '../../s1-main/App.module.css'
|
||||||
|
|
||||||
// types
|
// types
|
||||||
export type AffairPriorityType = any // 'high' | 'low' | 'middle' // need to fix any
|
export type AffairPriorityType = any // 'high' | 'low' | 'middle' // need to fix any
|
||||||
@@ -44,7 +44,7 @@ function HW2() {
|
|||||||
const deleteAffairCallback = (_id: any) => setAffairs(deleteAffair(affairs, _id)) // need to fix any // number
|
const deleteAffairCallback = (_id: any) => setAffairs(deleteAffair(affairs, _id)) // need to fix any // number
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id={'hw2'} className={s.hw2}>
|
<div id={'hw2'} className={s2.hw}>
|
||||||
<hr/>
|
<hr/>
|
||||||
{/*можно убрать этот тег*/}
|
{/*можно убрать этот тег*/}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, {useState} from 'react'
|
import React, {useState} from 'react'
|
||||||
import {v1} from 'uuid'
|
import {v1} from 'uuid'
|
||||||
import s from './Greeting.module.css'
|
import s from './Greeting.module.css'
|
||||||
|
import s2 from '../../s1-main/App.module.css'
|
||||||
import GreetingContainer from './GreetingContainer'
|
import GreetingContainer from './GreetingContainer'
|
||||||
|
|
||||||
// types
|
// types
|
||||||
@@ -9,7 +10,7 @@ export type UserType = {
|
|||||||
name: string // need to fix any
|
name: string // need to fix any
|
||||||
}
|
}
|
||||||
|
|
||||||
const HW1 = () => {
|
const HW3 = () => {
|
||||||
const [users, setUsers] = useState<UserType[]>([]) // need to fix any
|
const [users, setUsers] = useState<UserType[]>([]) // need to fix any
|
||||||
|
|
||||||
const addUserCallback = (name: string) => { // need to fix any
|
const addUserCallback = (name: string) => { // need to fix any
|
||||||
@@ -21,10 +22,12 @@ const HW1 = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id={'hw3'} className={s.hw3}>
|
<div id={'hw3'} className={s2.hw}>
|
||||||
<hr/>
|
<hr/>
|
||||||
{/*можно убрать этот тег*/}
|
{/*можно убрать этот тег*/}
|
||||||
|
|
||||||
|
<div className={s2.hwTitle}>homeworks 3</div>
|
||||||
|
|
||||||
{/*для автоматической проверки дз (не менять)*/}
|
{/*для автоматической проверки дз (не менять)*/}
|
||||||
<GreetingContainer users={users} addUserCallback={addUserCallback}/>
|
<GreetingContainer users={users} addUserCallback={addUserCallback}/>
|
||||||
|
|
||||||
@@ -36,4 +39,4 @@ const HW1 = () => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default HW1
|
export default HW3
|
||||||
|
|||||||
25
src/s2-homeworks/hw04/HW4.tsx
Normal file
25
src/s2-homeworks/hw04/HW4.tsx
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import s2 from '../../s1-main/App.module.css'
|
||||||
|
import Stand from './Stand'
|
||||||
|
|
||||||
|
const HW4 = () => {
|
||||||
|
return (
|
||||||
|
<div id={'hw4'} className={s2.hw}>
|
||||||
|
<hr/>
|
||||||
|
{/*можно убрать этот тег*/}
|
||||||
|
|
||||||
|
<div className={s2.hwTitle}>homeworks 4</div>
|
||||||
|
|
||||||
|
{/*проверка отображения*/}
|
||||||
|
демострация возможностей компонент:
|
||||||
|
<Stand/>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
{/*можно убрать этот тег*/}
|
||||||
|
<hr/>
|
||||||
|
{/*можно убрать этот тег*/}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HW4
|
||||||
16
src/s2-homeworks/hw04/Stand.module.css
Normal file
16
src/s2-homeworks/hw04/Stand.module.css
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
.stand {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputs {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttons {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkboxes {
|
||||||
|
|
||||||
|
}
|
||||||
79
src/s2-homeworks/hw04/Stand.tsx
Normal file
79
src/s2-homeworks/hw04/Stand.tsx
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
import React, {useState} from 'react'
|
||||||
|
import s from './Stand.module.css'
|
||||||
|
import SuperInputText from './common/c1-SuperInputText/SuperInputText'
|
||||||
|
import SuperCheckbox from './common/c3-SuperCheckbox/SuperCheckbox'
|
||||||
|
import SuperButton from "./common/c2-SuperButton/SuperButton";
|
||||||
|
|
||||||
|
const Stand = () => {
|
||||||
|
const [stateForAllInputs, setValue] = useState('')
|
||||||
|
const [error, setError] = useState<undefined | string>(undefined)
|
||||||
|
|
||||||
|
const [stateForAllCheckboxes, setChecked] = useState(false)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={s.stand}>
|
||||||
|
<div className={s.inputs}>
|
||||||
|
инпут с ошибкой:
|
||||||
|
<div>
|
||||||
|
<SuperInputText
|
||||||
|
id={'super-input-with-error'}
|
||||||
|
value={stateForAllInputs}
|
||||||
|
onChangeText={setValue}
|
||||||
|
error={error}
|
||||||
|
onEnter={() => {
|
||||||
|
setError(stateForAllInputs.trim() ? undefined : 'some error')
|
||||||
|
setValue('')
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
совместим со старым кодом
|
||||||
|
<div>
|
||||||
|
<SuperInputText
|
||||||
|
id={'super-input-like-old'}
|
||||||
|
value={stateForAllInputs}
|
||||||
|
onChange={e => setValue(e.currentTarget.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={s.buttons}>
|
||||||
|
обычная кнопка:
|
||||||
|
<div>
|
||||||
|
<SuperButton id={'super-button-default'}>default</SuperButton>
|
||||||
|
</div>
|
||||||
|
красная кнопка:
|
||||||
|
<div>
|
||||||
|
<SuperButton id={'super-button-red'} xType={'red'}>red</SuperButton>
|
||||||
|
</div>
|
||||||
|
задизэйбленная кнопка:
|
||||||
|
<div>
|
||||||
|
<SuperButton id={'super-button-disabled'} xType={'red'} disabled>disabled</SuperButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={s.checkboxes}>
|
||||||
|
чекбокс с текстом:
|
||||||
|
<div>
|
||||||
|
<SuperCheckbox
|
||||||
|
id={'super-checkbox-with-text'}
|
||||||
|
checked={stateForAllCheckboxes}
|
||||||
|
onChangeChecked={setChecked}
|
||||||
|
>
|
||||||
|
some text
|
||||||
|
</SuperCheckbox>
|
||||||
|
</div>
|
||||||
|
совместим со старым кодом
|
||||||
|
<div>
|
||||||
|
<SuperCheckbox
|
||||||
|
id={'super-checkbox-like-old'}
|
||||||
|
checked={stateForAllCheckboxes}
|
||||||
|
onChange={e => setChecked(e.currentTarget.checked)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Stand
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
.input:focus {
|
||||||
|
outline: none;
|
||||||
|
border: #99ff99 solid 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.superInput {
|
||||||
|
margin: 10px;
|
||||||
|
|
||||||
|
background: #003300;
|
||||||
|
color: #99ff99;
|
||||||
|
}
|
||||||
|
|
||||||
|
.errorInput {
|
||||||
|
margin: 10px;
|
||||||
|
|
||||||
|
background: #003300;
|
||||||
|
color: #99ff99;
|
||||||
|
|
||||||
|
border: 2px solid #dd3355;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
color: #dd3355;
|
||||||
|
height: 21px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import React, {ChangeEvent, DetailedHTMLProps, InputHTMLAttributes, KeyboardEvent, ReactNode} from 'react'
|
||||||
|
import s from './SuperInputText.module.css'
|
||||||
|
|
||||||
|
// тип пропсов обычного инпута
|
||||||
|
type DefaultInputPropsType = DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
|
||||||
|
|
||||||
|
// здесь мы говорим что у нашего инпута будут такие же пропсы как у обычного инпута, кроме type
|
||||||
|
// (чтоб не писать value: string, onChange: ...; они уже все описаны в DefaultInputPropsType)
|
||||||
|
type SuperInputTextPropsType = Omit<DefaultInputPropsType, 'type'> & { // и + ещё пропсы которых нет в стандартном инпуте
|
||||||
|
onChangeText?: (value: string) => void
|
||||||
|
onEnter?: () => void
|
||||||
|
error?: ReactNode
|
||||||
|
spanClassName?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const SuperInputText: React.FC<SuperInputTextPropsType> = (
|
||||||
|
{
|
||||||
|
// type, // достаём и игнорируем чтоб нельзя было задать другой тип инпута
|
||||||
|
onChange, onChangeText,
|
||||||
|
onKeyPress, onEnter,
|
||||||
|
error,
|
||||||
|
className, spanClassName,
|
||||||
|
id,
|
||||||
|
|
||||||
|
...restProps// все остальные пропсы попадут в объект restProps
|
||||||
|
}
|
||||||
|
) => {
|
||||||
|
const onChangeCallback = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
onChange?.(e) // если есть пропс onChange, то передать ему е (поскольку onChange не обязателен)
|
||||||
|
|
||||||
|
onChangeText?.(e.currentTarget.value)
|
||||||
|
}
|
||||||
|
const onKeyPressCallback = (e: KeyboardEvent<HTMLInputElement>) => {
|
||||||
|
onKeyPress?.(e)
|
||||||
|
|
||||||
|
onEnter // если есть пропс onEnter
|
||||||
|
&& e.key === 'Enter' // и если нажата кнопка Enter
|
||||||
|
&& onEnter() // то вызвать его
|
||||||
|
}
|
||||||
|
|
||||||
|
const finalSpanClassName = `${s.error} ${spanClassName ? spanClassName : ''}`
|
||||||
|
const finalInputClassName = `${s.input} ${error ? s.errorInput : s.superInput} ${className}` // задача на смешивание классов
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<input
|
||||||
|
id={id}
|
||||||
|
type={'text'}
|
||||||
|
onChange={onChangeCallback}
|
||||||
|
onKeyPress={onKeyPressCallback}
|
||||||
|
className={finalInputClassName}
|
||||||
|
|
||||||
|
{...restProps} // отдаём инпуту остальные пропсы если они есть (value например там внутри)
|
||||||
|
/>
|
||||||
|
<span id={id ? id + '-span' : undefined} className={finalSpanClassName}>{error}</span>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SuperInputText
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
@keyframes blink {
|
||||||
|
0% {
|
||||||
|
left: -130%;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
left: 130%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.default {
|
||||||
|
background: #003300;
|
||||||
|
color: #99ff99;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red {
|
||||||
|
background: #dd3355;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disabled {
|
||||||
|
color: #005500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
position: relative;
|
||||||
|
margin: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button::after {
|
||||||
|
display: block;
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
left: -130%;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 20%;
|
||||||
|
|
||||||
|
transform: skew(45deg);
|
||||||
|
|
||||||
|
background-color: #ffffff;
|
||||||
|
opacity: 0.7;
|
||||||
|
|
||||||
|
z-index: 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover::after {
|
||||||
|
animation: blink 0.35s ease; /*https://html5book.ru/css3-animation/*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover::before {
|
||||||
|
display: block;
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
left: -100vw;
|
||||||
|
top: 0;
|
||||||
|
height: 100vh;
|
||||||
|
width: 300vw;
|
||||||
|
|
||||||
|
background-color: #ffffff;
|
||||||
|
opacity: 0.2;
|
||||||
|
|
||||||
|
z-index: 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:focus {
|
||||||
|
outline: #99ff99 solid 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:active {
|
||||||
|
background: #99ff99;
|
||||||
|
color: #003300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:disabled {
|
||||||
|
cursor: no-drop;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:disabled::after {
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:disabled::before {
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
35
src/s2-homeworks/hw04/common/c2-SuperButton/SuperButton.tsx
Normal file
35
src/s2-homeworks/hw04/common/c2-SuperButton/SuperButton.tsx
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import React, {ButtonHTMLAttributes, DetailedHTMLProps} from 'react'
|
||||||
|
import s from './SuperButton.module.css'
|
||||||
|
|
||||||
|
// тип пропсов обычной кнопки, children в котором храниться название кнопки там уже описан
|
||||||
|
type DefaultButtonPropsType = DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
|
||||||
|
|
||||||
|
type SuperButtonPropsType = DefaultButtonPropsType & {
|
||||||
|
xType?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const SuperButton: React.FC<SuperButtonPropsType> = (
|
||||||
|
{
|
||||||
|
xType, className,
|
||||||
|
disabled,
|
||||||
|
...restProps// все остальные пропсы попадут в объект restProps, там же будет children
|
||||||
|
}
|
||||||
|
) => {
|
||||||
|
const finalClassName = `${s.button} ${
|
||||||
|
disabled
|
||||||
|
? s.disabled
|
||||||
|
: xType === 'red'
|
||||||
|
? s.red
|
||||||
|
: s.default
|
||||||
|
} ${className}` // задачка на смешивание классов
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
disabled={disabled}
|
||||||
|
className={finalClassName}
|
||||||
|
{...restProps} // отдаём кнопке остальные пропсы если они есть (children там внутри)
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SuperButton
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
.label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*input[type="checkbox"] - no*/
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
appearance: none; /*Свойство appearance изменяет внешний вид элемента интерфейса, при сохранении его функции.
|
||||||
|
Если задать значение none, то чекбокс пропадет, но по нему, тем не менее,
|
||||||
|
можно щелкать и состояние чекбокса будет меняться*/
|
||||||
|
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
|
||||||
|
/*background-repeat: no-repeat;*/
|
||||||
|
/*background-position: center center;*/
|
||||||
|
|
||||||
|
/*background-size: 90% 90%;*/
|
||||||
|
/*vertical-align: middle;*/
|
||||||
|
margin-right: 10px;
|
||||||
|
|
||||||
|
background: #335533;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox:checked {
|
||||||
|
appearance: none;
|
||||||
|
|
||||||
|
background-image: url("checked.png");
|
||||||
|
/*background: #99ff99;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox:focus {
|
||||||
|
outline: #99ff99 solid 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spanClassName {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import React, {ChangeEvent, DetailedHTMLProps, InputHTMLAttributes} from 'react'
|
||||||
|
import s from './SuperCheckbox.module.css'
|
||||||
|
|
||||||
|
// тип пропсов обычного инпута
|
||||||
|
type DefaultInputPropsType = DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
|
||||||
|
|
||||||
|
type SuperCheckboxPropsType = Omit<DefaultInputPropsType, 'type'> & {
|
||||||
|
onChangeChecked?: (checked: boolean) => void
|
||||||
|
spanClassName?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const SuperCheckbox: React.FC<SuperCheckboxPropsType> = (
|
||||||
|
{
|
||||||
|
onChange, onChangeChecked,
|
||||||
|
className, spanClassName,
|
||||||
|
children, // в эту переменную попадёт текст, типизировать не нужно так как он затипизирован в React.FC
|
||||||
|
id,
|
||||||
|
|
||||||
|
...restProps// все остальные пропсы попадут в объект restProps
|
||||||
|
}
|
||||||
|
) => {
|
||||||
|
const onChangeCallback = (e: ChangeEvent<HTMLInputElement>) => { // задачка на написание онченджа
|
||||||
|
onChange?.(e)
|
||||||
|
|
||||||
|
onChangeChecked?.(e.currentTarget.checked)
|
||||||
|
}
|
||||||
|
|
||||||
|
const finalInputClassName = `${s.checkbox} ${className ? className : ''}`
|
||||||
|
|
||||||
|
return (
|
||||||
|
<label className={s.label}>
|
||||||
|
<input
|
||||||
|
id={id}
|
||||||
|
type={'checkbox'}
|
||||||
|
onChange={onChangeCallback}
|
||||||
|
className={finalInputClassName}
|
||||||
|
|
||||||
|
{...restProps} // отдаём инпуту остальные пропсы если они есть (checked например там внутри)
|
||||||
|
/>
|
||||||
|
{children && <span id={id ? id + '-span' : undefined} className={s.spanClassName}>{children}</span>}
|
||||||
|
</label> // благодаря label нажатие на спан передастся в инпут
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SuperCheckbox
|
||||||
BIN
src/s2-homeworks/hw04/common/c3-SuperCheckbox/checked.png
Normal file
BIN
src/s2-homeworks/hw04/common/c3-SuperCheckbox/checked.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 711 B |
Reference in New Issue
Block a user