Skip to the solution
EasyFrontend11 min read

Build a Read More / Show Less text component

685 views

The problem

Question presented to candidate: "Our product page shows customer reviews, and some of them are several paragraphs long. Build a component that shows the first part of a long review with a Read more button, expands to the full text on click, and collapses again with Show less. Short reviews should just show in full, with no button."

Requirements:

  • A reusable component that takes text and a maxChars limit (120 in the demo).
  • Collapsed: the text cut at a word boundary where possible, with an ellipsis; no broken emoji.
  • A Read more / Show less button with the right ARIA state; no button at all when the text fits.
  • Each instance keeps its own expanded state, so several reviews can be open independently.

What a strong answer should cover:

  • State is one boolean per instance; the preview and "is it truncated" are derived from the props.
  • Truncating by characters the user sees (grapheme clusters), not with slice on UTF-16 code units, and backing off to the last space.
  • A real <button> with aria-expanded and aria-controls, and keeping focus on it when toggling.
  • The trade-off with CSS -webkit-line-clamp: it clamps by rendered lines but needs layout measurement (scrollHeight > clientHeight) to decide whether to show the button.
  • Edge cases: text shorter than the limit, no spaces at all, text that changes after render.

Clarifying questions expected:

  • "Is the limit in characters or in visible lines?"
  • "Should screen reader and search engine users get the full text even when collapsed?"
  • "Does the text ever contain markup, or is it plain text?"

Code / implementation expected: Yes. A component with derived truncation, a toggle button and a small demo list in the framework of your choice.

  • Rendering
  • State
  • Accessibility

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

11 min read Β· 9 sections

React solution

Every file of the working solution. Open it in the playground to run and change it.

ReactComplete solution
import ReadMore from "./src/components/ReadMore";
import { reviews } from "./src/data/reviews";

export default function App() {
  return (
    <main className="app">
      <h1>Customer reviews</h1>
      {reviews.map((r) => (
        <article key={r.id} className="card" data-testid="review">
          <h2>{r.author}</h2>
          <ReadMore text={r.text} maxChars={120} />
        </article>
      ))}
    </main>
  );
}

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 16 of 107 in Machine coding

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

Up nextEasy

Build a Breadcrumbs component

Continue