From 9d88dcdfe27cbd9cdb164724e0a7cff7546fadfe Mon Sep 17 00:00:00 2001 From: Sebastian Sebald Date: Fri, 16 Feb 2024 11:18:11 +0100 Subject: [PATCH] lgtm --- src/App.jsx | 29 +- src/{Frame.jsx => components.jsx} | 17 +- src/conclusion.mdx | 3 +- src/index.css | 37 +- src/{slideshow.mdx => intro.mdx} | 6 - src/validation.mdx | 608 +++++------------------------- 6 files changed, 161 insertions(+), 539 deletions(-) rename src/{Frame.jsx => components.jsx} (68%) rename src/{slideshow.mdx => intro.mdx} (99%) diff --git a/src/App.jsx b/src/App.jsx index 5feecbb..4d2ac27 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -2,35 +2,32 @@ import "@code-hike/mdx/styles"; import { MarigoldProvider } from "@marigold/components"; import theme from "@marigold/theme-b2b"; -import Slides from "./slideshow.mdx"; +import Intro from "./intro.mdx"; import Validation from "./validation.mdx"; import Conclusion from "./conclusion.mdx"; import { Example } from "./example"; -import { Frame } from "./Frame"; +import { Slide, Frame } from "./components"; const App = () => ( -
-
- -
-
+ + + + + -
-
+ + -
-
+ + -
-
+ + ); export default App; diff --git a/src/Frame.jsx b/src/components.jsx similarity index 68% rename from src/Frame.jsx rename to src/components.jsx index 61658b7..c9e6336 100644 --- a/src/Frame.jsx +++ b/src/components.jsx @@ -1,4 +1,5 @@ -// eslint-disable-next-line react/prop-types +/* eslint-disable react/prop-types */ + export const Frame = ({ children }) => (
(
); + +export const Slide = ({ children, maxWidth }) => ( +
+
{children}
+
+); + +const SlideContainer = ({ children }) => ( +
+ {children} +
+); + +Slide.Container = SlideContainer; diff --git a/src/conclusion.mdx b/src/conclusion.mdx index eea1946..cdc92a0 100644 --- a/src/conclusion.mdx +++ b/src/conclusion.mdx @@ -1,4 +1,5 @@ ## Summary - Reduces the need for state management and boilerplate -- +- Uses native input validation, opt-in for more complex use cases +- Handles client-side **and** server-side errors diff --git a/src/index.css b/src/index.css index b7f7cf3..b3861ab 100644 --- a/src/index.css +++ b/src/index.css @@ -8,15 +8,20 @@ body { background: #f9fafb; + height: 100vh; } /* LAYOUT */ -.content { +.slide-container { + height: 100vh; + width: 100vw; overflow-y: scroll; scroll-snap-type: y mandatory; } -.content-item { +.slide { + display: grid; + place-items: center; scroll-snap-align: start; max-width: 900px; height: 100vh; @@ -24,6 +29,34 @@ body { padding: 48px 0; } +.slide h2 { + color: #030712; + font-size: clamp(48px, 2vw, 64px); + font-weight: 700; + text-decoration: underline; + text-underline-offset: 4px; + text-decoration-thickness: 4px; + text-decoration-color: #9ca3af; + margin-bottom: 16px; +} + +.slide ul { + list-style: circle inside; +} + +.slide li { + color: #374151; + font-size: clamp(24px, 2vw, 32px); + padding: 4px 0; +} + +.slide strong { + font-weight: inherit; + text-decoration: underline; + text-underline-offset: 4px; + text-decoration-thickness: 2px; +} + /* CODE HIKE */ .ch-codegroup { box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); diff --git a/src/slideshow.mdx b/src/intro.mdx similarity index 99% rename from src/slideshow.mdx rename to src/intro.mdx index a89ddda..41d4368 100644 --- a/src/slideshow.mdx +++ b/src/intro.mdx @@ -176,12 +176,6 @@ export const App = () => { --- -```tsx example.tsx - -``` - ---- - ```tsx example.tsx export const App = () => { const onSubmit = (e: React.FormEvent) => { diff --git a/src/validation.mdx b/src/validation.mdx index abd1869..6cbde78 100644 --- a/src/validation.mdx +++ b/src/validation.mdx @@ -1,521 +1,103 @@ -# Slideshow with preview - -This is how to use the `` component. Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam, quia! Quidem, quisquam. - - - - - -```jsx src/index.js -import React from "react"; -import ReactDOM from "react-dom"; - -const app = React.createElement( - "h1", - { style: { color: "teal" } }, - "Hello React" -); - -ReactDOM.render(app, document.getElementById("root")); -``` - - - -React provides a createElement function to declare what we want to render to the DOM - ---- - - - -```jsx src/index.js focus=4 -import React from "react"; -import ReactDOM from "react-dom"; - -const app =

Hello React

; - -ReactDOM.render(app, document.getElementById("root")); -``` - -
- -But instead of using createElement directly you can use JSX. - ---- - - - -```jsx src/index.js focus=4:10 -import React from "react"; -import ReactDOM from "react-dom"; - -function MyComponent() { - return ( -
- -
- ); + + +```tsx validation.tsx +
+ + + + + +
+``` + +--- + +```tsx validation.tsx focus=7:11 +
+ + + + validationDetails.valueMissing + ? "Please enter a valid email address!" + : "" + } + /> + + +
+``` + +--- + +```tsx validation.tsx focus=7:11 +
+ + + + val.length && /^\S+@\S+\.\S+$/.test(val) + ? "" + : "Please enter a valid email address!" + } + /> + + +
+``` + +--- + +```tsx validation.tsx focus=3 +
+ + + + + +
+``` + +--- + +```tsx realtime.tsx +const [password, setPassword] = useState(""); +const errors = []; + +if (password.length < 8) { + errors.push("Password must be 8 characters or more."); } - -const app =

Hello React

; - -ReactDOM.render(app, document.getElementById("root")); -``` - -
- -To create a component you only need to write a function with a name that starts with a capital letter. - ---- - - - -```jsx src/index.js focus=4[10:20],12:17 -import React from "react"; -import ReactDOM from "react-dom"; - -function MyComponent() { - return ( -
- -
- ); +if ((password.match(/[A-Z]/g) ?? []).length < 2) { + errors.push("Password must include at least 2 upper case letters"); } - -const app = ( -
- - -
-); - -ReactDOM.render(app, document.getElementById("root")); -``` - -
- -Now you can use that function in JSX. - ---- - - - -```jsx src/index.js focus=14[18:29],15[18:31] -import React from "react"; -import ReactDOM from "react-dom"; - -function MyComponent() { - return ( -
- -
- ); +if ((password.match(/[^a-z]/gi) ?? []).length < 2) { + errors.push("Password must include at least 2 symbols."); } -const app = ( -
- - -
+return ( + 0} + errorMessage={errors} + /> ); - -ReactDOM.render(app, document.getElementById("root")); ``` -
- -You can assign attributes - ---- - - - -```jsx src/index.js focus=4[22:29],14[18:29],15[18:31] -import React from "react"; -import ReactDOM from "react-dom"; - -function MyComponent({ name }) { - return ( -
- -
- ); -} - -const app = ( -
- - -
-); - -ReactDOM.render(app, document.getElementById("root")); -``` - -
- -And React will pass them to the component as parameters - ---- - - - -```jsx src/index.js focus=4[22:29],7 -import React from "react"; -import ReactDOM from "react-dom"; - -function MyComponent({ name }) { - return ( -
- -
- ); -} - -const app = ( -
- - -
-); - -ReactDOM.render(app, document.getElementById("root")); -``` - -
- -Inside JSX, you use curly braces to wrap dynamic data - ---- - - - -```jsx src/index.js focus=5,9 -import React from "react"; -import ReactDOM from "react-dom"; - -function MyComponent({ name }) { - const goalCount = 2; - return ( -
- - {"⚽".repeat(goalCount)} -
- ); -} - -const app = ( -
- - -
-); - -ReactDOM.render(app, document.getElementById("root")); -``` - -
- -In fact you can wrap any javascript expression. - ---- - - - -```jsx src/index.js focus=7:9,13[15:35] -import React from "react"; -import ReactDOM from "react-dom"; - -function MyComponent({ name }) { - const goalCount = 2; - - const handleClick = (event) => { - // do something - }; - - return ( -
- - {"⚽".repeat(goalCount)} -
- ); -} - -const app = ( -
- - -
-); - -ReactDOM.render(app, document.getElementById("root")); -``` - -
- -To add event listeners you pass a function to the corresponding attribute - ---- - - - -```jsx src/index.js focus=5 -import React from "react"; -import ReactDOM from "react-dom"; - -function MyComponent({ name }) { - const [goalCount, setCount] = React.useState(2); - - const handleClick = (event) => { - // do something - }; - return ( -
- - {"⚽".repeat(goalCount)} -
- ); -} - -const app = ( -
- - -
-); - -ReactDOM.render(app, document.getElementById("root")); -``` - -
- -To add state to a component there's the useState function from React. - ---- - - - -```jsx src/index.js focus=5,7:9 -import React from "react"; -import ReactDOM from "react-dom"; - -function MyComponent({ name }) { - const [goalCount, setCount] = React.useState(2); - - const handleClick = (event) => { - setCount(goalCount + 1); - }; - - return ( -
- - {"⚽".repeat(goalCount)} -
- ); -} - -const app = ( -
- - -
-); - -ReactDOM.render(app, document.getElementById("root")); -``` - -
- -It gives you a function to update the state. - ---- - - - -```jsx src/index.js focus=5,7:9,13,14 - -``` - - - -When you call it, React will know it needs to re-render the component. - ---- - - - -```jsx src/index.js focus=19 -import React from "react"; -import ReactDOM from "react-dom"; - -function MyComponent({ name }) { - const [goalCount, setCount] = React.useState(2); - - const handleClick = (event) => { - setCount(goalCount + 1); - }; - - return ( -
- - {"⚽".repeat(goalCount)} -
- ); -} - -const players = ["Messi", "Ronaldo", "Laspada"]; - -const app = ( -
- - -
-); - -ReactDOM.render(app, document.getElementById("root")); -``` - -
- -To render a list - ---- - - - -```jsx src/index.js focus=19,23[6:34],24,25[1:6] -import React from "react"; -import ReactDOM from "react-dom"; - -function MyComponent({ name }) { - const [goalCount, setCount] = React.useState(2); - - const handleClick = (event) => { - setCount(goalCount + 1); - }; - - return ( -
- - {"⚽".repeat(goalCount)} -
- ); -} - -const players = ["Messi", "Ronaldo", "Laspada"]; - -const app = ( -
- {players.map((playerName) => ( - - ))} -
-); - -ReactDOM.render(app, document.getElementById("root")); -``` - -
- -you can map each list item to an element using javascript. - ---- - - - -```jsx src/index.js focus=24[38:54] - -``` - - - -React only needs a unique key for each element, to find out when something changes. - ---- - - - -```jsx src/index.js focus=21:27,30,34 -import React from "react"; -import ReactDOM from "react-dom"; - -function MyComponent({ name }) { - const [goalCount, setCount] = React.useState(2); - - const handleClick = (event) => { - setCount(goalCount + 1); - }; - - return ( -
- - {"⚽".repeat(goalCount)} -
- ); -} - -const players = ["Messi", "Ronaldo", "Laspada"]; - -function MyBox() { - return
// TODO something
; -} - -const app = ( - - {players.map((playerName) => ( - - ))} - -); - -ReactDOM.render(app, document.getElementById("root")); -``` - -
- -If you want to compose components together - ---- - - - -```jsx src/index.js focus=21[16:27],24,30:34 -import React from "react"; -import ReactDOM from "react-dom"; - -function MyComponent({ name }) { - const [goalCount, setCount] = React.useState(2); - - const handleClick = (event) => { - setCount(goalCount + 1); - }; - - return ( -
- - {"⚽".repeat(goalCount)} -
- ); -} - -const players = ["Messi", "Ronaldo", "Laspada"]; - -function MyBox({ children }) { - return
{children}
; -} - -const app = ( - - {players.map((playerName) => ( - - ))} - -); - -ReactDOM.render(app, document.getElementById("root")); -``` - -
- -React passes the nested elements inside a special property called children. -