From e0e3b5bdbb88a443b1dde2958db5f4df89d26f4f Mon Sep 17 00:00:00 2001 From: "Kent C. Dodds" Date: Fri, 8 Mar 2024 15:28:06 -0700 Subject: [PATCH] finish 05 --- .../05.portals/01.problem.create/README.mdx | 28 +++++++++ .../form.tsx | 0 .../index.css | 0 .../index.tsx | 0 .../params.tsx | 0 .../posts.tsx | 0 .../tooltip.tsx | 1 + exercises/05.portals/01.problem/README.mdx | 1 - .../05.portals/01.solution.create/README.mdx | 3 + .../form.tsx | 0 .../index.css | 0 .../index.tsx | 0 .../params.tsx | 0 .../posts.tsx | 0 .../tooltip.tsx | 0 exercises/05.portals/01.solution/README.mdx | 1 - exercises/05.portals/FINISHED.mdx | 3 + exercises/05.portals/README.mdx | 57 ++++++++++++++++++- 18 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 exercises/05.portals/01.problem.create/README.mdx rename exercises/05.portals/{01.problem => 01.problem.create}/form.tsx (100%) rename exercises/05.portals/{01.problem => 01.problem.create}/index.css (100%) rename exercises/05.portals/{01.problem => 01.problem.create}/index.tsx (100%) rename exercises/05.portals/{01.problem => 01.problem.create}/params.tsx (100%) rename exercises/05.portals/{01.problem => 01.problem.create}/posts.tsx (100%) rename exercises/05.portals/{01.problem => 01.problem.create}/tooltip.tsx (96%) delete mode 100644 exercises/05.portals/01.problem/README.mdx create mode 100644 exercises/05.portals/01.solution.create/README.mdx rename exercises/05.portals/{01.solution => 01.solution.create}/form.tsx (100%) rename exercises/05.portals/{01.solution => 01.solution.create}/index.css (100%) rename exercises/05.portals/{01.solution => 01.solution.create}/index.tsx (100%) rename exercises/05.portals/{01.solution => 01.solution.create}/params.tsx (100%) rename exercises/05.portals/{01.solution => 01.solution.create}/posts.tsx (100%) rename exercises/05.portals/{01.solution => 01.solution.create}/tooltip.tsx (100%) delete mode 100644 exercises/05.portals/01.solution/README.mdx diff --git a/exercises/05.portals/01.problem.create/README.mdx b/exercises/05.portals/01.problem.create/README.mdx new file mode 100644 index 00000000..86d37185 --- /dev/null +++ b/exercises/05.portals/01.problem.create/README.mdx @@ -0,0 +1,28 @@ +# createPortal + +👨‍💼 Some of our users find the heart icon to be unclear and would like to have a +tooltip that explains what it's for. + +🧝‍♂️ I've moved things around a little bit to reduce the amount of code you need +to work in. I've also added a simple tooltip component that's not working quite +yet. The positioning is all funny because the tooltip is being rendered within +the context of the card instead of at the root of the document. + +👨‍💼 Thanks Kellie. Now, let's see if you can make the tooltip component work +properly with a portal. + +Note, the change you're making is pretty minimal. You'll also need to change +some of the CSS to make the tooltip look a little better. + +🦉 Don't forget about the "Files" button in the bottom of this screen. It will +show you which files are changed in this exercise step and allow you to click +to open the relevant files. + +📜 Parts of this exercise was lifted from [the React docs](https://react.dev/reference/react/useLayoutEffect#measuring-layout-before-the-browser-repaints-the-screen) + + + Typically you'll want to use a library for tooltips which have been tested for + accessibility best practices. But they're likely using `createPortal` under + the hood and you'll very likely find yourself needing to use this API at some + point. + diff --git a/exercises/05.portals/01.problem/form.tsx b/exercises/05.portals/01.problem.create/form.tsx similarity index 100% rename from exercises/05.portals/01.problem/form.tsx rename to exercises/05.portals/01.problem.create/form.tsx diff --git a/exercises/05.portals/01.problem/index.css b/exercises/05.portals/01.problem.create/index.css similarity index 100% rename from exercises/05.portals/01.problem/index.css rename to exercises/05.portals/01.problem.create/index.css diff --git a/exercises/05.portals/01.problem/index.tsx b/exercises/05.portals/01.problem.create/index.tsx similarity index 100% rename from exercises/05.portals/01.problem/index.tsx rename to exercises/05.portals/01.problem.create/index.tsx diff --git a/exercises/05.portals/01.problem/params.tsx b/exercises/05.portals/01.problem.create/params.tsx similarity index 100% rename from exercises/05.portals/01.problem/params.tsx rename to exercises/05.portals/01.problem.create/params.tsx diff --git a/exercises/05.portals/01.problem/posts.tsx b/exercises/05.portals/01.problem.create/posts.tsx similarity index 100% rename from exercises/05.portals/01.problem/posts.tsx rename to exercises/05.portals/01.problem.create/posts.tsx diff --git a/exercises/05.portals/01.problem/tooltip.tsx b/exercises/05.portals/01.problem.create/tooltip.tsx similarity index 96% rename from exercises/05.portals/01.problem/tooltip.tsx rename to exercises/05.portals/01.problem.create/tooltip.tsx index 36600a50..727e7bf1 100644 --- a/exercises/05.portals/01.problem/tooltip.tsx +++ b/exercises/05.portals/01.problem.create/tooltip.tsx @@ -38,6 +38,7 @@ export default function Tooltip({ tooltipY += window.scrollY } + // 🐨 put this inside a createPortal call and append it to the document.body return ( {children} diff --git a/exercises/05.portals/01.problem/README.mdx b/exercises/05.portals/01.problem/README.mdx deleted file mode 100644 index 8350c7c7..00000000 --- a/exercises/05.portals/01.problem/README.mdx +++ /dev/null @@ -1 +0,0 @@ -# createPortal diff --git a/exercises/05.portals/01.solution.create/README.mdx b/exercises/05.portals/01.solution.create/README.mdx new file mode 100644 index 00000000..651c5062 --- /dev/null +++ b/exercises/05.portals/01.solution.create/README.mdx @@ -0,0 +1,3 @@ +# createPortal + +👨‍💼 Great job! That tooltip works much better now. Our users will be thrilled! diff --git a/exercises/05.portals/01.solution/form.tsx b/exercises/05.portals/01.solution.create/form.tsx similarity index 100% rename from exercises/05.portals/01.solution/form.tsx rename to exercises/05.portals/01.solution.create/form.tsx diff --git a/exercises/05.portals/01.solution/index.css b/exercises/05.portals/01.solution.create/index.css similarity index 100% rename from exercises/05.portals/01.solution/index.css rename to exercises/05.portals/01.solution.create/index.css diff --git a/exercises/05.portals/01.solution/index.tsx b/exercises/05.portals/01.solution.create/index.tsx similarity index 100% rename from exercises/05.portals/01.solution/index.tsx rename to exercises/05.portals/01.solution.create/index.tsx diff --git a/exercises/05.portals/01.solution/params.tsx b/exercises/05.portals/01.solution.create/params.tsx similarity index 100% rename from exercises/05.portals/01.solution/params.tsx rename to exercises/05.portals/01.solution.create/params.tsx diff --git a/exercises/05.portals/01.solution/posts.tsx b/exercises/05.portals/01.solution.create/posts.tsx similarity index 100% rename from exercises/05.portals/01.solution/posts.tsx rename to exercises/05.portals/01.solution.create/posts.tsx diff --git a/exercises/05.portals/01.solution/tooltip.tsx b/exercises/05.portals/01.solution.create/tooltip.tsx similarity index 100% rename from exercises/05.portals/01.solution/tooltip.tsx rename to exercises/05.portals/01.solution.create/tooltip.tsx diff --git a/exercises/05.portals/01.solution/README.mdx b/exercises/05.portals/01.solution/README.mdx deleted file mode 100644 index 8350c7c7..00000000 --- a/exercises/05.portals/01.solution/README.mdx +++ /dev/null @@ -1 +0,0 @@ -# createPortal diff --git a/exercises/05.portals/FINISHED.mdx b/exercises/05.portals/FINISHED.mdx index e69de29b..32fa4e29 100644 --- a/exercises/05.portals/FINISHED.mdx +++ b/exercises/05.portals/FINISHED.mdx @@ -0,0 +1,3 @@ +# Portals + +👨‍💼 Nice and quick on, but useful tool in your React toolbelt! diff --git a/exercises/05.portals/README.mdx b/exercises/05.portals/README.mdx index 85b319f3..4d1c905b 100644 --- a/exercises/05.portals/README.mdx +++ b/exercises/05.portals/README.mdx @@ -1,3 +1,58 @@ # Portals -📜 Parts of this exercise was lifted from [the React docs](https://react.dev/reference/react/useLayoutEffect#measuring-layout-before-the-browser-repaints-the-screen) +There are a variety of UI patterns that require a component render some part of +its UI that appears outside of the component's normal DOM hierarchy. For +example, a modal dialog might need to render its contents at the root of the +document, or a tooltip might need to render its contents at the end of the +`body` element. Typically this is for the purpose of layering or positioning +content above other content. + +You could imperatively add a `useEffect` that creates a DOM node yourself, +appends it to the document, and then removes it when the component unmounts. +However, this is a common enough pattern that React provides a built-in way to +do this with the `ReactDOM.createPortal` method. + +```tsx lines=1,12-18 +import { createPortal } from 'react-dom' + +function Modal({ + title, + content, + handleClose, +}: { + title: string + content: string + handleClose: () => void +}) { + return createPortal( +
+

{title}

+

{content}

+
, + document.body, + ) +} + +function App() { + const [showModal, setShowModal] = React.useState(false) + + return ( +
+ + {showModal && ( + setShowModal(false)} + /> + )} +
+ ) +} +``` + +The first argument is the UI you want rendered (which has access to props, +state, whatever) and the second argument is the DOM node you want to render it +to. In this case, we're rendering the modal to the `body` element. + +📜 Learn more from [the `createPortal` docs](https://react.dev/reference/react-dom/createPortal)