Skip to content

Conversation

@lokesh
Copy link
Collaborator

@lokesh lokesh commented Jan 6, 2026

feature: Add OLReadMore Lit web component for expandable/collapsible text

Technical

  • Introduces a new Lit-based web component <ol-read-more> in openlibrary/components/lit/OLReadMore.js
  • Component is registered in openlibrary/components/lit/index.js
  • Updated edition/view.html and work/view.html templates to use the new component for main book descriptions
  • Supports two truncation modes:
    • Height-based: Use max-height attribute (e.g., max-height="80px")
    • Line-based: Use max-lines attribute (e.g., max-lines="4")
  • Includes scroll-up behavior when collapsing long content
<ol-read-more max-height="100px" more-text="Read more" less-text="Read less">
   <p>Long content here...</p>
 </ol-read-more>

<ol-read-more max-lines="4">
  <p>Long content here...</p>
</ol-read-more>

Testing

  • Navigate to a book/edition page with a long description
  • Verify the description is truncated to ~4 lines with a "Read More" button
  • Toggle button to collapse and expand

Screenshot

image

Stakeholders

lokesh and others added 6 commits January 5, 2026 13:05
…e and package.json; update package-lock.json to include lit dependencies.
- Introduced a new web component, OLReadMore, that supports height-based and line-based truncation.
- Updated index.js to import the new component for registration as a custom element.
- Included the new OL components script in the footer for enhanced functionality.
- Replaced the existing book description implementation with the OLReadMore component for better user experience with expandable/collapsible content.
- Changed 'Read more' and 'Read less' to 'Read More' and 'Read Less' for uniformity in capitalization.
- Removed unnecessary margin-left style from the chevron icon.
- Changed 'Read more' and 'Read less' to 'Read More' and 'Read Less' for uniformity in capitalization in the book description section.
@lokesh lokesh changed the title PoC: Add 'Read More' web component feat: Add 'Read More' web component Jan 6, 2026
@lokesh lokesh closed this Jan 6, 2026
lokesh added 3 commits January 5, 2026 21:59
…oved accessibility and functionality

- Replaced button elements with <details> and <summary> for better semantic structure.
- Updated styles for toggle behavior and chevron icon.
- Simplified the logic for handling content expansion and truncation.
- Enhanced user experience by managing scroll behavior when collapsing content.
@lokesh lokesh reopened this Jan 6, 2026
@RayBB
Copy link
Collaborator

RayBB commented Jan 6, 2026

@lokesh I didn't test this one but just looking how the code structure I feel it's a pretty nice improvement!

@lokesh lokesh requested a review from RayBB January 6, 2026 17:57
@RayBB
Copy link
Collaborator

RayBB commented Jan 6, 2026

@lokesh great work on this one. I'm starting here with a functional review and then will review the code shortly after.

To test this ssh into docker and run
npm i then make lit-components

Testing Without a Read More Button

I modified http://localhost:8080/works/OL61982W/Odyssey to have a short description so it doesn't have a read more button and it looks identical to how it looked before.

Testing The Read More Button

This book already has enough text for a read more button:

Videos

Before

Built-in.Retina.Display.2026-01-06.13.42.43.mp4

After

Built-in.Retina.Display.2026-01-06.13.40.47.mp4

Expanded side by side:

Before After
Before After

Collapsed side by side:

Before After
Before After

Mobile

Before After
Before After

⚠️ There is a minor visual difference (the read more button doesn't overlay). However, I personally think the new version looks better and more professional.
⚠️ There is also a small difference that in the new version when you tap/click on the text it expands/collapses it. Given that this is the web standard default I think this change should also be ok.

Copy link
Collaborator

@RayBB RayBB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, I think this is a really nice potential improvement. Great job @lokesh
I've left some feedback here.

However, I will note:

  1. Mek talked today a lot about prioritizing things. One could argue this PR is not very important to benefit the patrons. On the other hand, I'd argue it's a nice isolated starting point in a high visibility portion of the site. Getting the first piece out the door itself is important so that the more difficult ones can come later.
  2. I'm reviewing this based on the assumption that the staff are all onboard with the idea of doing these lit components. I don't remember if it was agreed with certainty while I was there but it certainly felt likely.
  3. A brief reminder that I am a volunteer. So while I've been here a while and can help staff by reviewing PRs and speed up the process a bit, sometimes, especially with new code like this, staff have quite different opinions on how to approach things. So staff might later ask that some things I suggested change and whatnot. Please be patient with that!
  4. Also, always feel free to push back on my suggestions as this is fairly new to me as well!

Comment on lines +35 to +47
components:
mkdir -p $(BUILD)/components_new
BUILD_DIR=$(BUILD)/components_new npx vite build -c openlibrary/components/vite.config.mjs
mkdir -p $(BUILD)/components
rm -rf $(BUILD)/components
mv $(BUILD)/components_new $(BUILD)/components

lit-components:
mkdir -p $(BUILD)/lit-components_new
BUILD_DIR=$(BUILD)/lit-components_new NODE_ENV=production npx vite build -c openlibrary/components/lit-vite.config.js
mkdir -p $(BUILD)/lit-components
rm -rf $(BUILD)/lit-components
mv $(BUILD)/lit-components_new $(BUILD)/lit-components
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm of the opinion (and staff might see it differently) that we should do this:

  1. lit-components (new)
  2. vue-components (what is currently components)
  3. components (runs the two above)

This way, it's one less new thing for people to figure out and keep in mind. Also the naming makes more sense.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lit-components (new)
vue-components (what is currently components)
components (runs the two above)

Your breakdown makes sense to me. I kept the components rule as-is in my PR to keep the impact to a minimum as this would entail a couple of additional doc updates, but I might have been overly cautious.

@@ -0,0 +1,54 @@
/* eslint-env node, es6 */
/**
* Vite configuration for building Lit web components
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this file be .mjs like https://github.com/internetarchive/openlibrary/blob/master/openlibrary/components/vite.config.mjs is ?

I think that it was recommended back when I first setup Vite but not entirely sure if it actually benefits us but we should be consistent.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency, I think this is a good change. I'll use the mjs extension.

?open="${this._expanded}"
@click="${this._handleToggle}"
>
<summary>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I originally created the issue suggesting to use summary/details for this because I saw it mentioned somewhere.

Unfortunately, as AI as kindly shared with me now, it's:

Misuse of <details> and <summary>
You are using the <details> element but putting all the content inside the <summary> tag.
The Issue: Semantically, <summary> is a label/legend. Putting paragraphs of text inside it creates an invalid accessibility tree. Screen readers treat <summary> like a button; they don't expect a document inside it.
The Hack: You are fighting the browser’s native behavior with e.preventDefault() to keep the "summary" open while simulating a state change.

We might want to use a div + button or something similar that's accessible. This area isn't my strong suit.
It might also simplify the component JS a bit more?

</div>
<ol-read-more max-lines="4" class="book-description" more-text="$_('Read More')" less-text="$_('Read Less')">
$:sanitize(format(overview_desc))
</ol-read-more>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are three total (two repeat) places we use the old readmore. Perhaps, we should set this up for all of those places so we can ensure it works consistently AND then in this very same PR we could delete all the old readmore code, that would make a nice show of the diff between old a new new then.

Image

Copy link
Collaborator Author

@lokesh lokesh Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will create a separate PR that updates the other instances of the ReadMore macro with the new component and removes the old code. I don't think there is much harm in chunking the work.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lokesh added 3 commits January 8, 2026 09:31
- Changed the Vite configuration file reference in the Makefile and package.json from `lit-vite.config.js` to `vite-lit.config.mjs`.
- Removed the obsolete `lit-vite.config.js` file.
- Updated the new Vite configuration file to include a comment indicating its purpose for Vue components.
…ling

- Replaced <details> and <summary> elements with button elements for improved control over expansion and collapse.
- Updated CSS class names for clarity and consistency.
- Simplified event handling for toggling content visibility.
- Enhanced button styles and added hover effects for better user interaction.
…ttribute to chevron icon

- Updated the chevron SVG icon in the OLReadMore component to include the aria-hidden attribute for improved screen reader compatibility.
Copy link
Collaborator

@RayBB RayBB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gave it another test to check the changes and I think it's fantastic.
As far as I'm concerned this is fully functional and works very well.

There's a separate PR to do the rest of readmore and rip out the old code.

I'd still really like to get a review from @cdrini or someone else on the team since this it totally new lands for us.

PS: I'll be away for the next ~10 days so I won't be able to review or follow up on things much in that time. Hopefully it's merged in by the time I'm back!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants