shadcn.io is not affiliated with official shadcn/ui
Latest Posts Blog Block for React
Just published: the newest post as a lead band in large type with a pulsing dot and a New mark, three earlier posts as rows with unread dots, and a Mark all as read button.
Installation
Overview
A just-published section for React with Base UI, written for Stackwake, a developer-tools daily. The header carries a live count ("3 new") and a ghost Mark all as read button. Under it the newest post is a lead band set in large type with no cover: a status dot that pulses three times, a New mark, the title as the link, the dek and a byline. Three earlier posts follow as compact rows, each with an unread dot. Opening a post marks it read; Mark all as read clears every dot and the count, and then offers to mark them unread again. The read state lives on the page only: it is lost on reload, and nothing is sent anywhere. It's built from Guides, Status, Badge, Avatar and Button, with CSS for the pulse. For daily publications, release feeds and inboxes of posts.
FAQ
Where is the read state kept?
In one useState array of post ids on the page, so a reload brings back the starting state (the oldest post read, the other three unread). Opening a post marks it read; Mark all as read marks all four. To keep the state, store the ids in localStorage or your API and pass them in as the starting value.
How does a screen reader hear the count?
The count is a role="status" region, so a change is announced politely: "3 new" becomes "All caught up". Each row also carries a hidden "Unread" or "Read" before its details, because a dot is not text. The dots and the "New" mark are drawn, and their space is always reserved, so marking a post read never moves the layout.
Does the dot keep pulsing?
No: it pulses three times when the page loads and then rests, and with reduced motion it doesn't pulse at all. Nothing loops.
How do I change the posts?
Edit LEAD and ROWS at the top of the file. Each post has an id, a title, an author, a category, an ISO date, a reading time in minutes and an href; the lead also has a dek. START_READ lists the ids that begin as read. Dates are fixed and formatted in UTC.
How does it fit on a phone?
The count and the button sit under the heading, the lead's title wraps in large type, and each row stacks its category, date and reading time under its title. The block is about one and a half screens and nothing scrolls sideways at 320 pixels.
Related
- Pro
Featured Post Blog
Featured storyOne lead post as a split, its copy beside a drawn greyscale cover behind a divider, with three more posts as cells on shared hairlines under it.
- Pro
Hero Featured Blog
Featured storyA blog landing: the lead story as a framed drawn cover with its copy on a raised panel overlapping the cover's corner, and a numbered rail of the four latest posts beside it.
- Pro
Rectangular Cards Blog
Card gridsFour horizontal post cards in rows from rail to rail, the drawn cover at one end and the text at the other, mirroring row by row, each row numbered.
- Pro
Announcement Blog
Featured storyA notice board: the lead announcement as a split with a framed card-in-card panel and a Shine Button, and the past announcements as a description list band.
- Pro
Cards Grid Blog
Card gridsThe six latest posts of an engineering blog as cards on shared hairlines: drawn greyscale covers, a category, the title as the card's one link, a one-line dek and a byline with the date and reading time.
- Pro
Cover Story Blog
Featured storyA printed magazine cover drawn in greyscale beside the cover story's copy, a Shine Button and an ordered list of the issue's pieces with leader dots and page numbers.