|
@@ -0,0 +1,64 @@
|
|
|
|
+import './App.css';
|
|
|
|
+import { useState } from 'react'
|
|
|
|
+
|
|
|
|
+const LoginForm = ({onLogin}) => {
|
|
|
|
+ const [login, setLogin] = useState('')
|
|
|
|
+ const [password, setPassword] = useState('')
|
|
|
|
+ return (
|
|
|
|
+ <>
|
|
|
|
+ <input type='text' value={login} onChange={(e) => setLogin(e.target.value)} />
|
|
|
|
+ <input type='password' value={password} onChange={(e) => setPassword(e.target.value)} />
|
|
|
|
+ <button onClick={() => onLogin(login, password)} disabled={!login.length || !password.length}>Log in</button>
|
|
|
|
+ </>
|
|
|
|
+ )
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const Spoiler = ({header="+", open, children}) => {
|
|
|
|
+ const [isOpen, setOpen] = useState(open)
|
|
|
|
+ return (
|
|
|
|
+ <>
|
|
|
|
+ <div onClick={() => setOpen(!isOpen)} style={{cursor: 'pointer'}}>{header}</div>
|
|
|
|
+ <div>
|
|
|
|
+ { isOpen ? children : undefined}
|
|
|
|
+ </div>
|
|
|
|
+ </>
|
|
|
|
+ )
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const RangeInput = ({min, max}) => {
|
|
|
|
+ const [color, setColor] = useState('')
|
|
|
|
+ return (
|
|
|
|
+ <input onChange={e => e.target.value.length < min || e.target.value.length > max ? setColor('red') : setColor('green')} style={{color}} />
|
|
|
|
+ )
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const PasswordConfirm = ({min}) => {
|
|
|
|
+ const [password, setPassword] = useState('')
|
|
|
|
+ const [password2, setPassword2] = useState('')
|
|
|
|
+ return (
|
|
|
|
+ <>
|
|
|
|
+ <input type="password" value={password} onChange={e => setPassword(e.target.value)} />
|
|
|
|
+ <input type="password" value={password2} onChange={e => setPassword2(e.target.value)} />
|
|
|
|
+ <button disabled={ password !== password2 || password.length < min }>Confirm</button>
|
|
|
|
+ </>
|
|
|
|
+ )
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function App() {
|
|
|
|
+ return (
|
|
|
|
+ <div>
|
|
|
|
+ <LoginForm onLogin={(l, p) => console.log(l, p)} />
|
|
|
|
+
|
|
|
|
+ <Spoiler header={'тык сюда'} open>
|
|
|
|
+ children
|
|
|
|
+ <p>more children</p>
|
|
|
|
+ </Spoiler>
|
|
|
|
+
|
|
|
|
+ <RangeInput min={5} max={10} />
|
|
|
|
+
|
|
|
|
+ <PasswordConfirm min={5} />
|
|
|
|
+ </div>
|
|
|
|
+ );
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+export default App;
|