Ver código fonte

HW<react02>done

Gennadysht 2 anos atrás
pai
commit
3819e362db

+ 60 - 0
react/02/myproject/package-lock.json

@@ -11,8 +11,10 @@
         "@testing-library/jest-dom": "^5.16.5",
         "@testing-library/react": "^13.4.0",
         "@testing-library/user-event": "^13.5.0",
+        "lorem-ipsum": "^1.0.2",
         "react": "^18.2.0",
         "react-dom": "^18.2.0",
+        "react-lorem-ipsum": "^1.4.10",
         "react-scripts": "5.0.1",
         "web-vitals": "^2.1.4"
       }
@@ -11661,6 +11663,17 @@
         "loose-envify": "cli.js"
       }
     },
+    "node_modules/lorem-ipsum": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/lorem-ipsum/-/lorem-ipsum-1.0.2.tgz",
+      "integrity": "sha512-eWmp96Vwp0OoY+oaiWC2LhG5CfIxhQR/WSAG3oGN6qY5/h+k0lq0dkPzFy24QeVAylxi5Sz5L7gtyjs0KN+2ow==",
+      "dependencies": {
+        "optimist": "~0.3.5"
+      },
+      "bin": {
+        "lorem-ipsum": "bin/lorem-ipsum.bin.js"
+      }
+    },
     "node_modules/lower-case": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
@@ -12268,6 +12281,14 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/optimist": {
+      "version": "0.3.7",
+      "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz",
+      "integrity": "sha512-TCx0dXQzVtSCg2OgY/bO9hjM9cV4XYx09TVK+s3+FhkjT6LovsLe+pPMzpWf+6yXK/hUizs2gUoTw3jHM0VaTQ==",
+      "dependencies": {
+        "wordwrap": "~0.0.2"
+      }
+    },
     "node_modules/optionator": {
       "version": "0.9.1",
       "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
@@ -14169,6 +14190,11 @@
       "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
       "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
     },
+    "node_modules/react-lorem-ipsum": {
+      "version": "1.4.10",
+      "resolved": "https://registry.npmjs.org/react-lorem-ipsum/-/react-lorem-ipsum-1.4.10.tgz",
+      "integrity": "sha512-PCEuauLZTGJkm++oxJeUycEgQOBg3qmmD7pn5sUyq9e0OvvNbW32RKQsSgalAYGUIbS91UkDgxvt6iHVAsqYJw=="
+    },
     "node_modules/react-refresh": {
       "version": "0.11.0",
       "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
@@ -16558,6 +16584,14 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/wordwrap": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+      "integrity": "sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw==",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
     "node_modules/workbox-background-sync": {
       "version": "6.5.4",
       "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz",
@@ -25347,6 +25381,14 @@
         "js-tokens": "^3.0.0 || ^4.0.0"
       }
     },
+    "lorem-ipsum": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/lorem-ipsum/-/lorem-ipsum-1.0.2.tgz",
+      "integrity": "sha512-eWmp96Vwp0OoY+oaiWC2LhG5CfIxhQR/WSAG3oGN6qY5/h+k0lq0dkPzFy24QeVAylxi5Sz5L7gtyjs0KN+2ow==",
+      "requires": {
+        "optimist": "~0.3.5"
+      }
+    },
     "lower-case": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
@@ -25778,6 +25820,14 @@
         "is-wsl": "^2.2.0"
       }
     },
+    "optimist": {
+      "version": "0.3.7",
+      "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz",
+      "integrity": "sha512-TCx0dXQzVtSCg2OgY/bO9hjM9cV4XYx09TVK+s3+FhkjT6LovsLe+pPMzpWf+6yXK/hUizs2gUoTw3jHM0VaTQ==",
+      "requires": {
+        "wordwrap": "~0.0.2"
+      }
+    },
     "optionator": {
       "version": "0.9.1",
       "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
@@ -26970,6 +27020,11 @@
       "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
       "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
     },
+    "react-lorem-ipsum": {
+      "version": "1.4.10",
+      "resolved": "https://registry.npmjs.org/react-lorem-ipsum/-/react-lorem-ipsum-1.4.10.tgz",
+      "integrity": "sha512-PCEuauLZTGJkm++oxJeUycEgQOBg3qmmD7pn5sUyq9e0OvvNbW32RKQsSgalAYGUIbS91UkDgxvt6iHVAsqYJw=="
+    },
     "react-refresh": {
       "version": "0.11.0",
       "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
@@ -28715,6 +28770,11 @@
       "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
       "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ=="
     },
+    "wordwrap": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+      "integrity": "sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw=="
+    },
     "workbox-background-sync": {
       "version": "6.5.4",
       "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz",

+ 2 - 0
react/02/myproject/package.json

@@ -6,8 +6,10 @@
     "@testing-library/jest-dom": "^5.16.5",
     "@testing-library/react": "^13.4.0",
     "@testing-library/user-event": "^13.5.0",
+    "lorem-ipsum": "^1.0.2",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
+    "react-lorem-ipsum": "^1.4.10",
     "react-scripts": "5.0.1",
     "web-vitals": "^2.1.4"
   },

+ 90 - 2
react/02/myproject/src/App.js

@@ -1,7 +1,8 @@
 import logo from './logo.svg';
 import React, { useState } from 'react';
 import './App.css';
-
+import { LoremIpsum, Avatar } from 'react-lorem-ipsum';
+;
 const oneCat = {
     "_id": "62c9472cb74e1f5f2ec1a0d4",
     "name": "iPhone",
@@ -120,7 +121,25 @@ function App() {
     return (
         <div className="App"
             onClick={() => setShow(!show)}>
-            {div}
+           
+            <Spoiler header={<h1>+ Card</h1>}>
+                {div}
+            </Spoiler>
+
+                <Spoiler header={<h1>Заголовок</h1>} open>
+                    Контент 1
+                    <p> <LoremIpsum/></p>
+                </Spoiler>
+                <Spoiler>
+                    <h2>Контент 2</h2>
+                    <p> <LoremIpsum/></p>
+                </Spoiler>
+            {/*/////////////////////////////////////////*/}
+            <RangeInput min={2} max={10} />
+            <LoginForm />
+            <PasswordConfirm/>
+
+
             {/*
             {show && <div>Вуаля</div>}
             <ul>
@@ -130,5 +149,74 @@ function App() {
         </div>
     );
 }
+///////////////////////////////////spoiler//////////////////
+const Spoiler = ({ header = "+", open, children }) => {
+    const [isOpen, setIsOpen] = useState('');
+    if (isOpen !== '') {
+        open = isOpen;
+    }
+    return <div onClick={() => setIsOpen(!open)}>{header}{open && children}</div>
+}
+
+////////////////////////////////////////////////////////////
+const RangeInput = ({ min, max }) => {
+
+    const [text, setText] = useState('')
+    let length = text.length;
+    return <input
+        value={text}
+        onChange={e => setText(e.target.value)}
+        type="text"
+        style={{ color: length > max || length < min ? 'red' : 'darkgreen' }} />
+
+}
+///////////////////////////////////////////////////////////////////
+const LoginForm = ({ onLogin }) => {
+    const [login, setLogin] = useState('');
+    const [password, setPassword] = useState('');
+    const isButtonActive = login?.length > 3 && password?.length > 3;
+    return (
+        <div>
+            <input placeholder='Login' value={login}
+                onChange={e => setLogin(e.target.value)}
+                type="text" />
+            <input placeholder='Password' value={password}
+                onChange={e => setPassword(e.target.value)}
+                type="password" />
+            <button
+                disabled={!isButtonActive}
+                onClick={() => { onLogin({ login, password }) }}
+            >Login...</button>
+        </div >
+    )
+}
+function hasNumber(str) {
+    return /\d/.test(str);
+  }
+const PasswordConfirm = ({ onEqual }) => {
+    const [password1, setPassword1] = useState('');
+    const [password2, setPassword2] = useState('');
+    let minLength = 3;
+    const isButtonActive = (password1?.length > minLength && password2?.length > minLength &&
+        password1===password2 && hasNumber(password1));
+    return (
+        <div>
+            <input placeholder='Password' value={password1}
+                onChange={e => setPassword1(e.target.value)}
+                style={{ borderColor: isButtonActive ? 'darkgreen' : 'red' }}
+                type="password" />
+            <input placeholder='Password' value={password2}
+                onChange={e => setPassword2(e.target.value)}
+                style={{ borderColor: isButtonActive ? 'darkgreen' : 'red' }}
+                type="password" />
+            <button
+                disabled={!isButtonActive}
+                onClick={() => { onEqual({ password1, password2 }) }}
+            >OK...</button>
+        </div >
+    )
+}
+
+
 
 export default App;