Skip to content

Plugins window: expandable rows with rich plugin details#208

Merged
AllTerrainDeveloper merged 1 commit into
trunkfrom
feat-plugins-view-improvements
May 14, 2026
Merged

Plugins window: expandable rows with rich plugin details#208
AllTerrainDeveloper merged 1 commit into
trunkfrom
feat-plugins-view-improvements

Conversation

@AllTerrainDeveloper
Copy link
Copy Markdown
Collaborator

@AllTerrainDeveloper AllTerrainDeveloper commented May 14, 2026

Closes #200

plugins.improvements.mov

Why

The new Installed-plugins table had no way to see plugin details — description, changelog, FAQ, reviews, links, requirements, file metadata. The Browse tab has a slide-in flyout for that, but the Installed tab was just rows of names with no path to "tell me more about this plugin." Users were left guessing.

What ships

Expandable row detail panel — src/plugins-window/installed-detail.ts

Click any row in the Installed tab (or its chevron) and a rich detail panel slides out below it.

  • Compact hero — 44 px icon tile + title + author byline + inline <wpd-badge>s for version, Active/Inactive status, and pending updates. No banner image (early iterations rendered the wp.org banner full-bleed; it looked like a billboard).
  • Tab strip (<wpd-tabs>):
    • Overview — meta-chip strip (rating + stars, active installs, last updated, tested-up-to, WP/PHP requirements), the plugin description (preferring wp.org's rich version), and action buttons linking out to WordPress.org, the plugin website, and the author site.
    • Details<wpd-grid columns="2"> of compact <wpd-card>s, one fact per card (file path, version, size on disk, requires WP/PHP, text domain, plugin/author URLs, network-only flag, status).
    • Changelog — version-grouped cards. Parser recognises both <h*>1.2.3</h*> and = 1.2.3 = heading styles, groups the following nodes under each version, badges the newest with "Latest".
    • FAQ — accordion of <details> cards. First question opens by default. Animated chevron rotates 180° and flips to admin-theme-color on open. prefers-reduced-motion respected.
    • Reviews<wpd-rating-summary> on top, then a 2-column grid of review cards.
  • Lazy fetch + caching — wp.org plugin_information and reviews are fetched on first tab activation only, cached at module scope keyed by slug. Collapsing and re-expanding a row never refetches.

New <wpd-rating-summary> component — src/ui/components/wpd-rating-summary/

Replaces an ASCII-feeling histogram with a proper component:

  • Attributes: rating (0–100, wp.org convention), total (auto-summed from ratings when omitted).
  • Property: ratings ({ '5': n, … }).
  • Renders a two-pane card: big tabular-num average + SVG star cluster (proper filled / half / empty paths) on the left, animated histogram bars on the right (transform: scaleX(--ratio) with 600 ms easing).
  • CSS-variable surface for theming (--wpd-rating-fill, --wpd-rating-star, etc.).
  • prefers-reduced-motion respected.
  • ARIA-labelled.
  • 5 vitest cases. Registered in src/ui/components/index.ts + WPD_COMPONENT_TAGS.

The bugs found along the way

Shadow-DOM CSS doesn't pierce — the "huge icon" bug

<wpd-table> appends sub-rows into its own shadow DOM. Document-level CSS doesn't cross shadow boundaries, so every .desktop-mode-plugins__detail-* rule in plugins-window.css was silently ignored. The hero icon wrapper had no styling, the SVG inside expanded to fill its container, and the expanded row looked like a Times Square ad.

Fix: ship the panel stylesheet as a <style> element appended inside the panel root, so the rules live in the same shadow tree as the markup. ~300 lines of rules moved out of plugins-window.css and into a PANEL_STYLES constant.

wp.org ships malformed FAQ HTML — the empty-accordion bug

Verified by curling api.wordpress.org/plugins/info/1.0/<slug>.json for WooCommerce, Yoast, Elementor, Fluent Support, Jetpack, WPForms. Every FAQ ships as:

<dt id="">
Question text
</h4>                       <!-- bogus close tag, ignored -->
<p>
<p>Real answer paragraph</p>  <!-- inner P closes outer P (HTML5: P can't nest) -->
</p>
<dt id="">                   <!-- auto-closes the previous <dt> -->

When the browser parses this, the question text and every answer paragraph end up as children of <dt>, not as siblings. My first parser walked top-level siblings and found nothing — the accordion opened to an empty body.

Fix: three-strategy parser, tried in order — (1) :scope > dt (the wp.org default; split each <dt> on its first substantive child element), (2) real <dl><dt>…</dt><dd>…</dd></dl> pairs, (3) conventional <h*>Q</h*><p>A</p> siblings. Strips empty <p></p> debris from the broken nesting. Wraps bare text answers in <p>. Verified live against 6 plugins: WooCommerce 12 pairs, Yoast 7, Elementor 13, Fluent Support 6, Jetpack 8, WPForms 10.

Inline <img> in plugin descriptions

Some plugins ship a banner-style <img> at the top of their description HTML. max-width: 100% let it dominate. Now capped at max-height: 220px; object-fit: contain so descriptions read like documentation, not landing pages.

Misleading reviews empty state

The original copy said "No recent reviews" when the wp.org scraper returned zero items — but the scraper fails for many reasons (HTML drift, rate limit, locale redirect) and a histogram with hundreds of ratings could be sitting right above it, contradicting the claim. Now:

  • parsed: false (scrape failed) → honest "Reviews live on WordPress.org" empty state with an "Open reviews on WordPress.org" button.
  • parsed: true, items: [] (genuinely no scraped items) → just a centered "Write a review on WordPress.org" button. No misleading heading, no descriptive text. The CTA links to the actual write-a-review deep link (/support/plugin/<slug>/reviews/#new-post).
  • Reviews loaded successfully → cards plus a footer "Read all reviews on WordPress.org" link.

Files touched

  • src/plugins-window/installed-view.ts — wires table.subTable = buildInstalledDetail, toggles expansion on wpd-table-row-click.
  • src/plugins-window/installed-detail.tsnew, ~1300 lines.
  • src/ui/components/wpd-rating-summary/{wpd-rating-summary.ts,.styles.ts,.test.ts}new component.
  • src/ui/components/index.ts — registered.
  • assets/css/plugins-window.css — added the row-cursor cue; the rest of the panel styles live inline in the TS module (see shadow-DOM note).

Tests

npm run lint, npm run build, tsc --noEmit, npm run test:js — all green. 1160 tests passing (5 new for <wpd-rating-summary>).

Out of scope / follow-ups

  • A separate "stale update count" issue surfaced during review: the dock badge for the Plugins icon can stay at the pre-update value after a successful update. That's the live menu-refresh pipeline (bindMenuRefresh + refreshFrameworkMenu), unrelated to this change. To investigate in a follow-up PR.
Open WordPress Playground Preview
- Implemented the `<wpd-rating-summary>` component to display a rating summary with a two-pane layout.
- Added styles for the component to ensure proper layout and theming capabilities.
- Created smoke tests to verify functionality, including rendering of histogram rows, automatic total calculation, and correct star rating conversion.
@github-actions
Copy link
Copy Markdown
Contributor

✅ WordPress Plugin Check Report

✅ Status: Passed

📊 Report

All checks passed! No errors or warnings found.


🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check

@AllTerrainDeveloper AllTerrainDeveloper merged commit 0b41c34 into trunk May 14, 2026
5 checks passed
@AllTerrainDeveloper AllTerrainDeveloper deleted the feat-plugins-view-improvements branch May 14, 2026 08:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant