devYuraKim / react

udemy - jonas schmedtmann
0 stars 0 forks source link

c01-text-expander/src/App_OnMyOwn | children content manipulation #3

Open devYuraKim opened 3 months ago

devYuraKim commented 3 months ago

How can I show only the first 10 words of {children} ?

import "./styles.css";
import { useState } from "react";

export default function App() {
  return (
    <div>
      <TextExpander>
        Space travel is the ultimate adventure! Imagine soaring past the stars
        and exploring new worlds. It's the stuff of dreams and science fiction,
        but believe it or not, space travel is a real thing. Humans and robots
        are constantly venturing out into the cosmos to uncover its secrets and
        push the boundaries of what's possible.
      </TextExpander>

      <TextExpander
        collapsedNumWords={20}
        expandButtonText="Show text"
        collapseButtonText="Collapse text"
        buttonColor="#ff6622"
      >
        Space travel requires some seriously amazing technology and
        collaboration between countries, private companies, and international
        space organizations. And while it's not always easy (or cheap), the
        results are out of this world. Think about the first time humans stepped
        foot on the moon or when rovers were sent to roam around on Mars.
      </TextExpander>

      <TextExpander expanded={true} className="box">
        Space missions have given us incredible insights into our universe and
        have inspired future generations to keep reaching for the stars. Space
        travel is a pretty cool thing to think about. Who knows what we'll
        discover next!
      </TextExpander>
    </div>
  );
}

function TextExpander({
  collapsedNumWords = 10,
  expandButtonText = "Show more",
  collapseButtonText = "Show less",
  buttonColor = "blue",
  expanded = false,
  className,
  children,
}) {
  const [isExpanded, setIsExpanded] = useState(expanded);

  function handleClick() {
    setIsExpanded((prev) => !isExpanded);
  }

  return (
    <div className={className}>
      {isExpanded ? collapsedNumWords : children}
      <span style={{ color: buttonColor }} onClick={handleClick}>
        {isExpanded ? expandButtonText : collapseButtonText}
      </span>
    </div>
  );
}
devYuraKim commented 3 months ago

To display only the first 10 words of the children prop in the TextExpander component when it is not expanded, you need to split the children string, extract the first 10 words, and then join them back together. You also need to ensure the rest of the text is displayed when the component is expanded. Here's the updated TextExpander component:

function TextExpander({
  collapsedNumWords = 10,
  expandButtonText = "Show more",
  collapseButtonText = "Show less",
  buttonColor = "blue",
  expanded = false,
  className,
  children,
}) {
  const [isExpanded, setIsExpanded] = useState(expanded);

  function handleClick() {
    setIsExpanded((prev) => !prev);
  }

  // Split the children into words and get the first collapsedNumWords
  const words = children.split(" ");
  const previewText = words.slice(0, collapsedNumWords).join(" ");

  return (
    <div className={className}>
      {isExpanded ? children : `${previewText}...`}
      <span style={{ color: buttonColor, cursor: "pointer" }} onClick={handleClick}>
        {isExpanded ? collapseButtonText : expandButtonText}
      </span>
    </div>
  );
}

Changes made:

  1. Split the children prop into words and extract the first collapsedNumWords words.
  2. Display the first collapsedNumWords words followed by an ellipsis (...) when the text is not expanded.
  3. Display the full children text when the text is expanded.
  4. Added cursor: "pointer" style to the toggle span to indicate it is clickable. 5. Correct syntax for SetIsExpanded setIsExpanded((prev)=>!prev)