Skip to content

Add Interactive Star Rating Selector to Product Review Form #60213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: trunk
Choose a base branch
from

Conversation

dinhtungdu
Copy link
Member

Submission Review Guidelines

Changes proposed in this Pull Request

In an effort to reduce legacy scripts for block themes, this PR implements a rating selector powered by the Interactivity API. This removes the need for the legacy single-product.js file that transforms the dropdown selector into star ratings.

Screenshots or screen recordings

Before After
image image

How to test the changes in this Pull Request

Using the WooCommerce Testing Instructions Guide, include your detailed testing instructions:

  1. Add the Product Details block to the Single Product template.
  2. On the frontend, hover over the star selector in the form and verify that stars fill from left to right. Move the cursor away from the selector and verify all stars become unfilled.
  3. Select a rating star and verify that stars fill from left to right and remain filled when the cursor moves away from the selector.
  4. Type a review and submit to verify the review is recorded with the correct rating.
  5. Try submitting a review without selecting a rating and verify that an error message appears next to the stars. The message currently lacks style, I just wrap it inside a <small> tag.
  6. Test keyboard navigation by using Tab to focus on stars and Space to select ratings.

Changelog entry

  • Automatically create a changelog entry from the details below.
Changelog Entry Details

Significance

  • Patch
  • Minor
  • Major

Type

  • Fix - Fixes an existing bug
  • Add - Adds functionality
  • Update - Update existing functionality
  • Dev - Development related task
  • Tweak - A minor adjustment to the codebase
  • Performance - Address performance issues
  • Enhancement - Improvement to existing functionality

Message

Add Interactive Star Rating Selector to Product Review Form

@woocommercebot woocommercebot requested review from a team and gigitux and removed request for a team August 6, 2025 04:54
@github-actions github-actions bot added the plugin: woocommerce Issues related to the WooCommerce Core plugin. label Aug 6, 2025
Copy link
Contributor

github-actions bot commented Aug 6, 2025

Testing Guidelines

Hi @Aljullu ,

Apart from reviewing the code changes, please make sure to review the testing instructions (Guide) and verify that relevant tests (E2E, Unit, Integration, etc.) have been added or updated as needed.

Reminder: PR reviewers are required to document testing performed. This includes:

  • 🖼️ Screenshots or screen recordings.
  • 📝 List of functionality tested / steps followed.
  • 🌐 Site details (environment attributes such as hosting type, plugins, theme, store size, store age, and relevant settings).
  • 🔍 Any analysis performed, such as assessing potential impacts on environment attributes and other plugins, conducting performance profiling, or using LLM/AI-based analysis.

⚠️ Within the testing details you provide, please ensure that no sensitive information (such as API keys, passwords, user data, etc.) is included in this public issue.

Copy link
Contributor

coderabbitai bot commented Aug 6, 2025

📝 Walkthrough

Walkthrough

This change introduces an interactive star rating selector to the WooCommerce Product Review Form, replacing the previous static dropdown. It involves updates to PHP rendering logic, state management on the frontend using WordPress interactivity utilities, new and updated styles for the star rating component, and configuration changes to enable interactivity and associate scripts and styles with the block.

Changes

Cohort / File(s) Change Summary
Changelog Entry
plugins/woocommerce/changelog/60213-feat-product-form-rating-selector-iapi
Added a changelog entry describing the introduction of the interactive star rating selector feature to the product review form.
Block Configuration & Styles
plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json,
plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
Updated block.json to enable interactivity and link view script and styles. Added CSS rules to style the interactive star rating buttons, including hover and selection states.
Import Cleanup
plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/edit.tsx,
plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/index.tsx
Removed unused stylesheet imports from TypeScript files without logic changes.
Frontend State Management
plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
Introduced a new WordPress interactivity store managing star rating UI state, keyboard and mouse interactions, validation, and form submission handling for the product review form.
PHP Rendering & Interactivity Integration
plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
Refactored the ProductReviewForm class to use interactivity traits, replaced the rating dropdown with an accessible interactive star rating UI, added reactive state initialization and event bindings, improved accessibility, and included a new private method to render star buttons.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Browser (JS/CSS)
    participant WooCommerce Review Form (PHP)
    participant WP Interactivity Store

    User->>Browser (JS/CSS): Loads review form page
    Browser (JS/CSS)->>WooCommerce Review Form (PHP): Requests form HTML
    WooCommerce Review Form (PHP)->>Browser (JS/CSS): Renders form with interactive stars, data-wp-interactive, and state config
    User->>Browser (JS/CSS): Hovers/clicks stars
    Browser (JS/CSS)->>WP Interactivity Store: Updates hovered/selected star state
    User->>Browser (JS/CSS): Submits form
    Browser (JS/CSS)->>WP Interactivity Store: Validates rating, blocks submit if invalid, shows error if needed
    Browser (JS/CSS)->>WooCommerce Review Form (PHP): Submits valid form data
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Note

🔌 MCP (Model Context Protocol) integration is now available in Early Access!

Pro users can now connect to remote MCP servers under the Integrations page to get reviews and chat conversations that understand additional development context.


📜 Recent review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3f9b937 and 871194a.

📒 Files selected for processing (2)
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts (1 hunks)
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (27)
  • GitHub Check: Blocks e2e tests 10/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 6/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 7/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 8/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 5/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 9/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 1/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 2/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 6/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 3/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Metrics - @woocommerce/plugin-woocommerce [performance]
  • GitHub Check: Blocks e2e tests 4/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.3] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: Core API tests - @woocommerce/plugin-woocommerce [api]
  • GitHub Check: Core e2e tests 5/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 4/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 3/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 2/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: PHP: 8.4 WP: latest [WP latest] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: Core e2e tests 1/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: JavaScript - @woocommerce/block-library [unit]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.3] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 8.4 WP: latest [WP latest] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: Lint - @woocommerce/block-library
  • GitHub Check: Lint - @woocommerce/plugin-woocommerce
  • GitHub Check: build
  • GitHub Check: Check Asset Sizes
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/product-form-rating-selector-iapi

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

github-actions bot commented Aug 6, 2025

Size Change: +3.82 kB (+0.06%)

Total Size: 5.92 MB

Filename Size Change
./plugins/woocommerce/client/blocks/build/featured-category.js 15 kB +573 B (+3.98%)
./plugins/woocommerce/client/blocks/build/featured-product.js 15.1 kB +557 B (+3.84%)
./plugins/woocommerce/client/blocks/build/product-review-form-rtl.css 0 B -577 B (removed) 🏆
./plugins/woocommerce/client/blocks/build/product-review-form.css 0 B -576 B (removed) 🏆
./plugins/woocommerce/client/blocks/build/woocommerce/product-collection.js 1.43 kB +324 B (+29.4%) 🚨
./plugins/woocommerce/client/blocks/build/woocommerce/product-review-form-editor-rtl.css 161 B +161 B (new file) 🆕
./plugins/woocommerce/client/blocks/build/woocommerce/product-review-form-editor.css 161 B +161 B (new file) 🆕
./plugins/woocommerce/client/blocks/build/woocommerce/product-review-form-style-rtl.css 702 B +702 B (new file) 🆕
./plugins/woocommerce/client/blocks/build/woocommerce/product-review-form-style.css 702 B +702 B (new file) 🆕
./plugins/woocommerce/client/blocks/build/woocommerce/product-review-form.js 799 B +799 B (new file) 🆕

compressed-size-action

Copy link
Contributor

github-actions bot commented Aug 6, 2025

Test using WordPress Playground

The changes in this pull request can be previewed and tested using a WordPress Playground instance.
WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Test this pull request with WordPress Playground.

Note that this URL is valid for 30 days from when this comment was last updated. You can update it by closing/reopening the PR or pushing a new commit.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts (1)

35-44: Add radix parameter to parseInt calls for consistency

While modern JavaScript handles these cases correctly, it's a best practice to always specify the radix parameter explicitly.

 actions: {
   hoverStar() {
     const { starValue } = getContext< StarContext >();
-    state.hoveredStar = parseInt( starValue );
+    state.hoveredStar = parseInt( starValue, 10 );
   },
   leaveStar() {
     state.hoveredStar = 0;
   },
   selectStar() {
     const { starValue } = getContext< StarContext >();
-    state.selectedStar = parseInt( starValue );
+    state.selectedStar = parseInt( starValue, 10 );
   },
📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a7ac75c and 3fe51cb.

📒 Files selected for processing (7)
  • plugins/woocommerce/changelog/60213-feat-product-form-rating-selector-iapi (1 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json (2 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/edit.tsx (0 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts (1 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/index.tsx (0 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss (2 hunks)
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php (3 hunks)
💤 Files with no reviewable changes (2)
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/edit.tsx
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/index.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{php,js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/code-quality.mdc)

**/*.{php,js,jsx,ts,tsx}: Guard against unexpected inputs
Sanitize and validate any potentially dangerous inputs
Ensure code is backwards compatible
Write code that is readable and intuitive
Ensure code has unit or E2E tests where applicable

Files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
**/*.{php,js,ts,jsx,tsx}

⚙️ CodeRabbit Configuration File

**/*.{php,js,ts,jsx,tsx}: Don't trust that extension developers will follow the best practices, make sure the code:

  • Guards against unexpected inputs.
  • Sanitizes and validates any potentially dangerous inputs.
  • Is backwards compatible.
  • Is readable and intuitive.
  • Has unit or E2E tests where applicable.

Files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
🧠 Learnings (23)
📓 Common learnings
Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/generate-pr-description.mdc:0-0
Timestamp: 2025-07-21T05:22:46.426Z
Learning: Provide clear, step-by-step instructions for how to test the changes in the PR description.
Learnt from: dinhtungdu
PR: woocommerce/woocommerce#59900
File: plugins/woocommerce/client/blocks/assets/js/blocks/product-filters/inner-blocks/attribute-filter/inspector.tsx:0-0
Timestamp: 2025-07-24T05:37:00.907Z
Learning: The DisplayStyleSwitcher component in plugins/woocommerce/client/blocks/assets/js/blocks/product-filters/components/display-style-switcher/index.tsx has been updated so that its onChange prop accepts only a string type (not string | number | undefined), eliminating the need for type assertions when using this component.
Learnt from: kmanijak
PR: woocommerce/woocommerce#60154
File: plugins/woocommerce/client/blocks/assets/js/blocks/next-previous-buttons/edit.tsx:80-80
Timestamp: 2025-08-04T11:58:34.139Z
Learning: In WooCommerce block Edit components (like plugins/woocommerce/client/blocks/assets/js/blocks/next-previous-buttons/edit.tsx), buttons are preview/display elements for the block editor interface and are not meant to be interactive, so accessibility attributes like ARIA labels are not necessary for these non-functional preview buttons.
Learnt from: Aljullu
PR: woocommerce/woocommerce#58809
File: plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php:222-225
Timestamp: 2025-06-13T17:11:13.732Z
Learning: In `plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php`, the team intentionally relies on toggling the `disabled` CSS class (via `data-wp-class--disabled`) instead of binding the `disabled` attribute, to mirror the behavior of the classic WooCommerce template.
Learnt from: ralucaStan
PR: woocommerce/woocommerce#58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.
Learnt from: samueljseay
PR: woocommerce/woocommerce#58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.
Learnt from: mreishus
PR: woocommerce/woocommerce#58891
File: plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php:0-0
Timestamp: 2025-06-16T21:59:26.255Z
Learning: In WooCommerce's CartSchema::get_item_response() method, when called in the context of BlocksSharedState::register_cart_interactivity(), the method returns a plain array rather than a WP_REST_Response object, making it directly suitable for wp_interactivity_state() without needing to call ->get_data().
Learnt from: samueljseay
PR: woocommerce/woocommerce#59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be `if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; }` - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.
Learnt from: nerrad
PR: woocommerce/woocommerce#60176
File: plugins/woocommerce/client/legacy/css/admin.scss:9088-9105
Timestamp: 2025-08-04T00:21:51.440Z
Learning: WooCommerce is currently in the midst of an admin redesign project, so temporary/short-term CSS solutions for admin pages are preferred over long-term refactoring when addressing immediate needs.
Learnt from: gigitux
PR: woocommerce/woocommerce#58902
File: plugins/woocommerce/client/blocks/assets/js/blocks/product-specifications/edit.tsx:205-206
Timestamp: 2025-06-17T12:40:54.118Z
Learning: In WordPress blocks, when there's a styling mismatch between editor and frontend, check if the PHP renderer (like in `ProductSpecifications.php`) adds specific classes to the output. If so, add those same classes to the `useBlockProps` className in the editor component (like in `edit.tsx`) to ensure consistent styling. For example, adding `wp-block-table` class to both frontend and editor ensures core table styles and theme customizations apply consistently.
📚 Learning: the displaystyleswitcher component in plugins/woocommerce/client/blocks/assets/js/blocks/product-fil...
Learnt from: dinhtungdu
PR: woocommerce/woocommerce#59900
File: plugins/woocommerce/client/blocks/assets/js/blocks/product-filters/inner-blocks/attribute-filter/inspector.tsx:0-0
Timestamp: 2025-07-24T05:37:00.907Z
Learning: The DisplayStyleSwitcher component in plugins/woocommerce/client/blocks/assets/js/blocks/product-filters/components/display-style-switcher/index.tsx has been updated so that its onChange prop accepts only a string type (not string | number | undefined), eliminating the need for type assertions when using this component.

Applied to files:

  • plugins/woocommerce/changelog/60213-feat-product-form-rating-selector-iapi
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: in woocommerce core repository, changelog entries for all prs live in `plugins/woocommerce/changelog...
Learnt from: jorgeatorres
PR: woocommerce/woocommerce#59675
File: .github/workflows/release-bump-as-requirement.yml:48-65
Timestamp: 2025-07-15T15:39:21.856Z
Learning: In WooCommerce core repository, changelog entries for all PRs live in `plugins/woocommerce/changelog/` directory and are processed during releases, not at the repository root level.

Applied to files:

  • plugins/woocommerce/changelog/60213-feat-product-form-rating-selector-iapi
📚 Learning: in woocommerce blocks, bold styling for `.wc-block-components-product-details__name` should be scope...
Learnt from: ralucaStan
PR: woocommerce/woocommerce#58782
File: plugins/woocommerce/client/blocks/assets/js/base/components/cart-checkout/product-details/style.scss:21-26
Timestamp: 2025-06-13T15:24:45.923Z
Learning: In WooCommerce blocks, bold styling for `.wc-block-components-product-details__name` should be scoped only to the Cart block (`.wc-block-cart__main`); on the Checkout block, product names are not bold because prices are highlighted instead.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
📚 Learning: in woocommerce blocks css, prefer using standard css properties like `scrollbar-width` over vendor-s...
Learnt from: Aljullu
PR: woocommerce/woocommerce#59370
File: plugins/woocommerce/client/blocks/assets/js/blocks/product-gallery/style.scss:236-243
Timestamp: 2025-07-03T10:09:20.635Z
Learning: In WooCommerce blocks CSS, prefer using standard CSS properties like `scrollbar-width` over vendor-specific prefixes when the standard property has good browser support. As of late 2024, `scrollbar-width` is widely supported across all major browsers and doesn't require WebKit-specific workarounds.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
📚 Learning: in woocommerce block edit components (like plugins/woocommerce/client/blocks/assets/js/blocks/next-p...
Learnt from: kmanijak
PR: woocommerce/woocommerce#60154
File: plugins/woocommerce/client/blocks/assets/js/blocks/next-previous-buttons/edit.tsx:80-80
Timestamp: 2025-08-04T11:58:34.139Z
Learning: In WooCommerce block Edit components (like plugins/woocommerce/client/blocks/assets/js/blocks/next-previous-buttons/edit.tsx), buttons are preview/display elements for the block editor interface and are not meant to be interactive, so accessibility attributes like ARIA labels are not necessary for these non-functional preview buttons.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: in `plugins/woocommerce/src/blocks/blocktypes/productbutton.php`, the team intentionally relies on t...
Learnt from: Aljullu
PR: woocommerce/woocommerce#58809
File: plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php:222-225
Timestamp: 2025-06-13T17:11:13.732Z
Learning: In `plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php`, the team intentionally relies on toggling the `disabled` CSS class (via `data-wp-class--disabled`) instead of binding the `disabled` attribute, to mirror the behavior of the classic WooCommerce template.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: in woocommerce projects, formatting suggestions should respect the project's prettier configuration ...
Learnt from: lysyjan
PR: woocommerce/woocommerce#59632
File: packages/js/email-editor/src/layouts/flex-email.tsx:116-122
Timestamp: 2025-07-14T10:41:46.200Z
Learning: In WooCommerce projects, formatting suggestions should respect the project's Prettier configuration and linting rules. Changes that would break the lint job should be avoided, even if they appear to improve readability.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
📚 Learning: in wordpress blocks, when there's a styling mismatch between editor and frontend, check if the php r...
Learnt from: gigitux
PR: woocommerce/woocommerce#58902
File: plugins/woocommerce/client/blocks/assets/js/blocks/product-specifications/edit.tsx:205-206
Timestamp: 2025-06-17T12:40:54.118Z
Learning: In WordPress blocks, when there's a styling mismatch between editor and frontend, check if the PHP renderer (like in `ProductSpecifications.php`) adds specific classes to the output. If so, add those same classes to the `useBlockProps` className in the editor component (like in `edit.tsx`) to ensure consistent styling. For example, adding `wp-block-table` class to both frontend and editor ensures core table styles and theme customizations apply consistently.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: woocommerce is currently in the midst of an admin redesign project, so temporary/short-term css solu...
Learnt from: nerrad
PR: woocommerce/woocommerce#60176
File: plugins/woocommerce/client/legacy/css/admin.scss:9088-9105
Timestamp: 2025-08-04T00:21:51.440Z
Learning: WooCommerce is currently in the midst of an admin redesign project, so temporary/short-term CSS solutions for admin pages are preferred over long-term refactoring when addressing immediate needs.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
📚 Learning: in woocommerce blocks, when porting existing code patterns that have known issues (like parseint tru...
Learnt from: samueljseay
PR: woocommerce/woocommerce#58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: in woocommerce blocks typescript code, avoid type assertions (`as`) when accessing properties from u...
Learnt from: gigitux
PR: woocommerce/woocommerce#59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.528Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (`as`) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using `Partial<>` wrappers, and export the unified type to help third-party extenders. For example: `type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>`.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
📚 Learning: in woocommerce email editor store initialization (packages/js/email-editor/src/store/initial-state.t...
Learnt from: triple0t
PR: woocommerce/woocommerce#59186
File: packages/js/email-editor/src/store/initial-state.ts:9-10
Timestamp: 2025-06-26T12:13:32.062Z
Learning: In WooCommerce email editor store initialization (packages/js/email-editor/src/store/initial-state.ts), the current_post_id and current_post_type from window.WooCommerceEmailEditor are required parameters that should cause explicit errors if missing, rather than using fallback values or optional chaining. The design preference is to fail fast when critical initialization data is unavailable.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
📚 Learning: for woocommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, t...
Learnt from: samueljseay
PR: woocommerce/woocommerce#59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be `if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; }` - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: in plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-addres...
Learnt from: ralucaStan
PR: woocommerce/woocommerce#58782
File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx:76-90
Timestamp: 2025-06-13T13:37:35.793Z
Learning: In plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx, the `shouldAnimate` flag is expected to be `false` only on initial render and may remain `true` after the first edit; it does not need to be reset.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
📚 Learning: in woocommerce mini cart implementation, the cart state is server-populated before javascript initia...
Learnt from: samueljseay
PR: woocommerce/woocommerce#58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:78-96
Timestamp: 2025-06-18T06:05:25.472Z
Learning: In WooCommerce mini cart implementation, the cart state is server-populated before JavaScript initialization, so wooStoreState.cart and wooStoreState.cart.totals will be available on first render without requiring null-safe guards.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
📚 Learning: in woocommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings...
Learnt from: vladolaru
PR: woocommerce/woocommerce#59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
📚 Learning: in woocommerce taxonomy filter components like plugins/woocommerce/client/blocks/assets/js/blocks/pr...
Learnt from: dinhtungdu
PR: woocommerce/woocommerce#60144
File: plugins/woocommerce/client/blocks/assets/js/blocks/product-filters/inner-blocks/taxonomy-filter/edit.tsx:183-184
Timestamp: 2025-08-04T14:32:56.289Z
Learning: In WooCommerce taxonomy filter components like plugins/woocommerce/client/blocks/assets/js/blocks/product-filters/inner-blocks/taxonomy-filter/edit.tsx, taxonomy term objects fetched from WordPress core data APIs via getEntityRecords() have guaranteed structure and don't require additional validation for properties like term.id and term.parent since they come from trusted internal WordPress core data sources.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
📚 Learning: in woocommerce email editor (packages/js/email-editor/src/hacks/publish-save.tsx), the currentpost o...
Learnt from: lysyjan
PR: woocommerce/woocommerce#59931
File: packages/js/email-editor/src/hacks/publish-save.tsx:0-0
Timestamp: 2025-07-23T14:53:29.447Z
Learning: In WooCommerce email editor (packages/js/email-editor/src/hacks/publish-save.tsx), the currentPost obtained from select(editorStore).getCurrentPost() is guaranteed to always be a post object, so null safety checks are not required when accessing its properties like status.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
📚 Learning: wordpress block.json files support json schema pattern validation for string attributes using the "p...
Learnt from: Aljullu
PR: woocommerce/woocommerce#60045
File: plugins/woocommerce/src/Blocks/BlockTypes/ProductGalleryThumbnails.php:68-68
Timestamp: 2025-07-28T07:20:49.002Z
Learning: WordPress block.json files support JSON schema pattern validation for string attributes using the "pattern" property with regular expression syntax, which provides client-side validation in the block editor.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
📚 Learning: woocommerce block templates have a predictable structure where each block has one top-level div with...
Learnt from: samueljseay
PR: woocommerce/woocommerce#59142
File: plugins/woocommerce/src/Blocks/BlockTypes/MiniCart.php:594-602
Timestamp: 2025-06-25T06:51:41.381Z
Learning: WooCommerce block templates have a predictable structure where each block has one top-level div with wp-block-woocommerce- class containing arbitrary nested content that should be preserved.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: in woocommerce's cartschema::get_item_response() method, when called in the context of blocksshareds...
Learnt from: mreishus
PR: woocommerce/woocommerce#58891
File: plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php:0-0
Timestamp: 2025-06-16T21:59:26.255Z
Learning: In WooCommerce's CartSchema::get_item_response() method, when called in the context of BlocksSharedState::register_cart_interactivity(), the method returns a plain array rather than a WP_REST_Response object, making it directly suitable for wp_interactivity_state() without needing to call ->get_data().

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: the core/spacer block in the woocommerce email editor intentionally does not have a dedicated render...
Learnt from: lysyjan
PR: woocommerce/woocommerce#59070
File: packages/php/email-editor/src/Integrations/Core/class-initializer.php:103-141
Timestamp: 2025-06-23T16:55:58.246Z
Learning: The core/spacer block in the WooCommerce email editor intentionally does not have a dedicated renderer class and is handled by the fallback renderer instead of having an explicit render_email_callback assigned in the switch statement.

Applied to files:

  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
🔇 Additional comments (8)
plugins/woocommerce/changelog/60213-feat-product-form-rating-selector-iapi (1)

1-4: LGTM!

The changelog entry follows the standard WooCommerce format and accurately describes the new feature.

plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss (1)

17-20: Well-structured star rating styles

The CSS implementation properly handles button resets, uses modern flexbox with gap for spacing, and leverages currentColor for theme compatibility. The hover and selected state classes integrate well with the Interactivity API.

Also applies to: 91-111

plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts (1)

22-29: Add radix parameter to parseInt calls

The parseInt calls should explicitly specify the radix (base 10) to avoid potential issues with leading zeros or different number formats.

 state: {
   get isStarHovered(): boolean {
     const { starValue } = getContext< StarContext >();
-    return state.hoveredStar >= parseInt( starValue, 10 );
+    return state.hoveredStar >= parseInt( starValue, 10 );
   },
   get isStarSelected(): boolean {
     const { starValue } = getContext< StarContext >();
-    return state.selectedStar >= parseInt( starValue, 10 );
+    return state.selectedStar >= parseInt( starValue, 10 );
   },

Wait, I see the radix is already specified. Let me re-examine...

⛔ Skipped due to learnings
Learnt from: dinhtungdu
PR: woocommerce/woocommerce#59900
File: plugins/woocommerce/client/blocks/assets/js/blocks/product-filters/inner-blocks/attribute-filter/inspector.tsx:0-0
Timestamp: 2025-07-24T05:37:00.907Z
Learning: The DisplayStyleSwitcher component in plugins/woocommerce/client/blocks/assets/js/blocks/product-filters/components/display-style-switcher/index.tsx has been updated so that its onChange prop accepts only a string type (not string | number | undefined), eliminating the need for type assertions when using this component.
Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/code-quality.mdc:0-0
Timestamp: 2025-07-18T14:54:36.232Z
Learning: Applies to **/*.{php,js,jsx,ts,tsx} : Write code that is readable and intuitive
Learnt from: triple0t
PR: woocommerce/woocommerce#59186
File: packages/js/email-editor/src/store/initial-state.ts:9-10
Timestamp: 2025-06-26T12:13:32.062Z
Learning: In WooCommerce email editor store initialization (packages/js/email-editor/src/store/initial-state.ts), the current_post_id and current_post_type from window.WooCommerceEmailEditor are required parameters that should cause explicit errors if missing, rather than using fallback values or optional chaining. The design preference is to fail fast when critical initialization data is unavailable.
Learnt from: samueljseay
PR: woocommerce/woocommerce#58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.
plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json (1)

16-16: Block configuration properly enables interactivity

The configuration correctly enables the Interactivity API and links the necessary frontend scripts and styles for both editor and frontend contexts.

Also applies to: 59-62

plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php (4)

48-63: Proper initialization of interactivity state

The interactivity state and config are correctly initialized with safe default values and properly escaped localized strings.


93-129: Well-structured form fields generation

The refactored approach with the fields array improves maintainability and properly handles escaping for all user inputs and field attributes.


161-167: Correct use of WP_HTML_Tag_Processor for form modification

Good use of the WordPress HTML API to safely add the submit handler attribute to the form element.


173-201: Verify wp_interactivity_data_wp_context escapes its output

I wasn’t able to locate the definition of wp_interactivity_data_wp_context in the codebase to confirm its implementation. Please ensure that this helper:

  • JSON-encodes its input (e.g. via wp_json_encode)
  • Escapes the result for HTML attributes (e.g. via esc_attr)

Although $i is a controlled integer (1–5), we need to be certain that arbitrary data can’t slip through unescaped into the data-wp-… attributes.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts (1)

64-70: Consider the implications of using a private store.

The lock acknowledgment message suggests this is using WordPress private/internal APIs that may break in future releases. This could lead to maintenance issues when WordPress updates.

Consider documenting why a private store is necessary here, or investigate if there's a public API alternative that would be more stable.

📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a7ac75c and 3fe51cb.

📒 Files selected for processing (7)
  • plugins/woocommerce/changelog/60213-feat-product-form-rating-selector-iapi (1 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json (2 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/edit.tsx (0 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts (1 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/index.tsx (0 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss (2 hunks)
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php (3 hunks)
💤 Files with no reviewable changes (2)
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/index.tsx
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/edit.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{php,js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/code-quality.mdc)

**/*.{php,js,jsx,ts,tsx}: Guard against unexpected inputs
Sanitize and validate any potentially dangerous inputs
Ensure code is backwards compatible
Write code that is readable and intuitive
Ensure code has unit or E2E tests where applicable

Files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
**/*.{php,js,ts,jsx,tsx}

⚙️ CodeRabbit Configuration File

**/*.{php,js,ts,jsx,tsx}: Don't trust that extension developers will follow the best practices, make sure the code:

  • Guards against unexpected inputs.
  • Sanitizes and validates any potentially dangerous inputs.
  • Is backwards compatible.
  • Is readable and intuitive.
  • Has unit or E2E tests where applicable.

Files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
🧠 Learnings (23)
📓 Common learnings
Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/generate-pr-description.mdc:0-0
Timestamp: 2025-07-21T05:22:46.426Z
Learning: Provide clear, step-by-step instructions for how to test the changes in the PR description.
Learnt from: dinhtungdu
PR: woocommerce/woocommerce#59900
File: plugins/woocommerce/client/blocks/assets/js/blocks/product-filters/inner-blocks/attribute-filter/inspector.tsx:0-0
Timestamp: 2025-07-24T05:37:00.907Z
Learning: The DisplayStyleSwitcher component in plugins/woocommerce/client/blocks/assets/js/blocks/product-filters/components/display-style-switcher/index.tsx has been updated so that its onChange prop accepts only a string type (not string | number | undefined), eliminating the need for type assertions when using this component.
Learnt from: kmanijak
PR: woocommerce/woocommerce#60154
File: plugins/woocommerce/client/blocks/assets/js/blocks/next-previous-buttons/edit.tsx:80-80
Timestamp: 2025-08-04T11:58:34.139Z
Learning: In WooCommerce block Edit components (like plugins/woocommerce/client/blocks/assets/js/blocks/next-previous-buttons/edit.tsx), buttons are preview/display elements for the block editor interface and are not meant to be interactive, so accessibility attributes like ARIA labels are not necessary for these non-functional preview buttons.
Learnt from: ralucaStan
PR: woocommerce/woocommerce#58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.
Learnt from: nerrad
PR: woocommerce/woocommerce#60176
File: plugins/woocommerce/client/legacy/css/admin.scss:9088-9105
Timestamp: 2025-08-04T00:21:51.440Z
Learning: WooCommerce is currently in the midst of an admin redesign project, so temporary/short-term CSS solutions for admin pages are preferred over long-term refactoring when addressing immediate needs.
Learnt from: Aljullu
PR: woocommerce/woocommerce#58809
File: plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php:222-225
Timestamp: 2025-06-13T17:11:13.732Z
Learning: In `plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php`, the team intentionally relies on toggling the `disabled` CSS class (via `data-wp-class--disabled`) instead of binding the `disabled` attribute, to mirror the behavior of the classic WooCommerce template.
Learnt from: samueljseay
PR: woocommerce/woocommerce#58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.
Learnt from: NeosinneR
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-26T14:25:08.421Z
Learning: In WooCommerce transactional emails, product images have historically had display issues due to lazy loading attributes being applied, which email clients cannot process since they don't execute JavaScript. This issue existed in both old and new email templates, but became more visible with the new email template system. The fix involves preventing lazy loading on attachment images specifically during email generation by adding skip classes and data attributes.
Learnt from: opr
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-20T17:38:16.565Z
Learning: WooCommerce legacy JavaScript files in plugins/woocommerce/client/legacy/js/ must use older JavaScript syntax and cannot use modern features like optional chaining (?.) due to browser compatibility requirements. Explicit null checking with && operators should be used instead.
Learnt from: prettyboymp
PR: woocommerce/woocommerce#59048
File: .github/workflows/cherry-pick-milestoned-prs.yml:60-83
Timestamp: 2025-06-26T12:45:40.709Z
Learning: WooCommerce uses WordPress versioning conventions where minor versions in X.Y.Z format are constrained to 0-9 (Y cannot exceed 9). This means version increment logic should reset minor to 0 and increment major when minor reaches 9, rather than allowing two-digit minor versions like 9.10 or 9.11.
📚 Learning: the displaystyleswitcher component in plugins/woocommerce/client/blocks/assets/js/blocks/product-fil...
Learnt from: dinhtungdu
PR: woocommerce/woocommerce#59900
File: plugins/woocommerce/client/blocks/assets/js/blocks/product-filters/inner-blocks/attribute-filter/inspector.tsx:0-0
Timestamp: 2025-07-24T05:37:00.907Z
Learning: The DisplayStyleSwitcher component in plugins/woocommerce/client/blocks/assets/js/blocks/product-filters/components/display-style-switcher/index.tsx has been updated so that its onChange prop accepts only a string type (not string | number | undefined), eliminating the need for type assertions when using this component.

Applied to files:

  • plugins/woocommerce/changelog/60213-feat-product-form-rating-selector-iapi
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: in woocommerce core repository, changelog entries for all prs live in `plugins/woocommerce/changelog...
Learnt from: jorgeatorres
PR: woocommerce/woocommerce#59675
File: .github/workflows/release-bump-as-requirement.yml:48-65
Timestamp: 2025-07-15T15:39:21.856Z
Learning: In WooCommerce core repository, changelog entries for all PRs live in `plugins/woocommerce/changelog/` directory and are processed during releases, not at the repository root level.

Applied to files:

  • plugins/woocommerce/changelog/60213-feat-product-form-rating-selector-iapi
📚 Learning: in woocommerce blocks, bold styling for `.wc-block-components-product-details__name` should be scope...
Learnt from: ralucaStan
PR: woocommerce/woocommerce#58782
File: plugins/woocommerce/client/blocks/assets/js/base/components/cart-checkout/product-details/style.scss:21-26
Timestamp: 2025-06-13T15:24:45.923Z
Learning: In WooCommerce blocks, bold styling for `.wc-block-components-product-details__name` should be scoped only to the Cart block (`.wc-block-cart__main`); on the Checkout block, product names are not bold because prices are highlighted instead.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: in woocommerce blocks css, prefer using standard css properties like `scrollbar-width` over vendor-s...
Learnt from: Aljullu
PR: woocommerce/woocommerce#59370
File: plugins/woocommerce/client/blocks/assets/js/blocks/product-gallery/style.scss:236-243
Timestamp: 2025-07-03T10:09:20.635Z
Learning: In WooCommerce blocks CSS, prefer using standard CSS properties like `scrollbar-width` over vendor-specific prefixes when the standard property has good browser support. As of late 2024, `scrollbar-width` is widely supported across all major browsers and doesn't require WebKit-specific workarounds.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
📚 Learning: in `plugins/woocommerce/src/blocks/blocktypes/productbutton.php`, the team intentionally relies on t...
Learnt from: Aljullu
PR: woocommerce/woocommerce#58809
File: plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php:222-225
Timestamp: 2025-06-13T17:11:13.732Z
Learning: In `plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php`, the team intentionally relies on toggling the `disabled` CSS class (via `data-wp-class--disabled`) instead of binding the `disabled` attribute, to mirror the behavior of the classic WooCommerce template.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: in woocommerce block edit components (like plugins/woocommerce/client/blocks/assets/js/blocks/next-p...
Learnt from: kmanijak
PR: woocommerce/woocommerce#60154
File: plugins/woocommerce/client/blocks/assets/js/blocks/next-previous-buttons/edit.tsx:80-80
Timestamp: 2025-08-04T11:58:34.139Z
Learning: In WooCommerce block Edit components (like plugins/woocommerce/client/blocks/assets/js/blocks/next-previous-buttons/edit.tsx), buttons are preview/display elements for the block editor interface and are not meant to be interactive, so accessibility attributes like ARIA labels are not necessary for these non-functional preview buttons.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: in woocommerce projects, formatting suggestions should respect the project's prettier configuration ...
Learnt from: lysyjan
PR: woocommerce/woocommerce#59632
File: packages/js/email-editor/src/layouts/flex-email.tsx:116-122
Timestamp: 2025-07-14T10:41:46.200Z
Learning: In WooCommerce projects, formatting suggestions should respect the project's Prettier configuration and linting rules. Changes that would break the lint job should be avoided, even if they appear to improve readability.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
📚 Learning: in wordpress blocks, when there's a styling mismatch between editor and frontend, check if the php r...
Learnt from: gigitux
PR: woocommerce/woocommerce#58902
File: plugins/woocommerce/client/blocks/assets/js/blocks/product-specifications/edit.tsx:205-206
Timestamp: 2025-06-17T12:40:54.118Z
Learning: In WordPress blocks, when there's a styling mismatch between editor and frontend, check if the PHP renderer (like in `ProductSpecifications.php`) adds specific classes to the output. If so, add those same classes to the `useBlockProps` className in the editor component (like in `edit.tsx`) to ensure consistent styling. For example, adding `wp-block-table` class to both frontend and editor ensures core table styles and theme customizations apply consistently.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: woocommerce is currently in the midst of an admin redesign project, so temporary/short-term css solu...
Learnt from: nerrad
PR: woocommerce/woocommerce#60176
File: plugins/woocommerce/client/legacy/css/admin.scss:9088-9105
Timestamp: 2025-08-04T00:21:51.440Z
Learning: WooCommerce is currently in the midst of an admin redesign project, so temporary/short-term CSS solutions for admin pages are preferred over long-term refactoring when addressing immediate needs.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
📚 Learning: in woocommerce blocks, when porting existing code patterns that have known issues (like parseint tru...
Learnt from: samueljseay
PR: woocommerce/woocommerce#58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: for woocommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, t...
Learnt from: samueljseay
PR: woocommerce/woocommerce#59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be `if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; }` - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: wordpress block.json files support json schema pattern validation for string attributes using the "p...
Learnt from: Aljullu
PR: woocommerce/woocommerce#60045
File: plugins/woocommerce/src/Blocks/BlockTypes/ProductGalleryThumbnails.php:68-68
Timestamp: 2025-07-28T07:20:49.002Z
Learning: WordPress block.json files support JSON schema pattern validation for string attributes using the "pattern" property with regular expression syntax, which provides client-side validation in the block editor.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
📚 Learning: woocommerce block templates have a predictable structure where each block has one top-level div with...
Learnt from: samueljseay
PR: woocommerce/woocommerce#59142
File: plugins/woocommerce/src/Blocks/BlockTypes/MiniCart.php:594-602
Timestamp: 2025-06-25T06:51:41.381Z
Learning: WooCommerce block templates have a predictable structure where each block has one top-level div with wp-block-woocommerce- class containing arbitrary nested content that should be preserved.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: in woocommerce's cartschema::get_item_response() method, when called in the context of blocksshareds...
Learnt from: mreishus
PR: woocommerce/woocommerce#58891
File: plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php:0-0
Timestamp: 2025-06-16T21:59:26.255Z
Learning: In WooCommerce's CartSchema::get_item_response() method, when called in the context of BlocksSharedState::register_cart_interactivity(), the method returns a plain array rather than a WP_REST_Response object, making it directly suitable for wp_interactivity_state() without needing to call ->get_data().

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: in woocommerce blocks typescript code, avoid type assertions (`as`) when accessing properties from u...
Learnt from: gigitux
PR: woocommerce/woocommerce#59659
File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/frontend.ts:136-147
Timestamp: 2025-07-22T09:30:43.528Z
Learning: In WooCommerce blocks TypeScript code, avoid type assertions (`as`) when accessing properties from unified stores. Instead, create proper union types that combine all the different store component types using `Partial<>` wrappers, and export the unified type to help third-party extenders. For example: `type UnifiedStore = BaseStore & Partial<StoreA> & Partial<StoreB>`.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
📚 Learning: in woocommerce email editor store initialization (packages/js/email-editor/src/store/initial-state.t...
Learnt from: triple0t
PR: woocommerce/woocommerce#59186
File: packages/js/email-editor/src/store/initial-state.ts:9-10
Timestamp: 2025-06-26T12:13:32.062Z
Learning: In WooCommerce email editor store initialization (packages/js/email-editor/src/store/initial-state.ts), the current_post_id and current_post_type from window.WooCommerceEmailEditor are required parameters that should cause explicit errors if missing, rather than using fallback values or optional chaining. The design preference is to fail fast when critical initialization data is unavailable.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
📚 Learning: in plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-addres...
Learnt from: ralucaStan
PR: woocommerce/woocommerce#58782
File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx:76-90
Timestamp: 2025-06-13T13:37:35.793Z
Learning: In plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-address-block/customer-address.tsx, the `shouldAnimate` flag is expected to be `false` only on initial render and may remain `true` after the first edit; it does not need to be reset.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
📚 Learning: in woocommerce mini cart implementation, the cart state is server-populated before javascript initia...
Learnt from: samueljseay
PR: woocommerce/woocommerce#58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:78-96
Timestamp: 2025-06-18T06:05:25.472Z
Learning: In WooCommerce mini cart implementation, the cart state is server-populated before JavaScript initialization, so wooStoreState.cart and wooStoreState.cart.totals will be available on first render without requiring null-safe guards.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
📚 Learning: in woocommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings...
Learnt from: vladolaru
PR: woocommerce/woocommerce#59160
File: plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx:0-0
Timestamp: 2025-06-26T14:56:54.917Z
Learning: In WooCommerce payments onboarding components (like plugins/woocommerce/client/admin/client/settings-payments/onboarding/providers/woopayments/steps/payment-methods-selection/index.tsx), when updating local React state based on API calls, the local state should only be updated after the API call succeeds to prevent inconsistent state if the save operation fails. The pattern is to move setPaymentMethodsState calls inside the .then() callback of the API promise.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
📚 Learning: in woocommerce taxonomy filter components like plugins/woocommerce/client/blocks/assets/js/blocks/pr...
Learnt from: dinhtungdu
PR: woocommerce/woocommerce#60144
File: plugins/woocommerce/client/blocks/assets/js/blocks/product-filters/inner-blocks/taxonomy-filter/edit.tsx:183-184
Timestamp: 2025-08-04T14:32:56.289Z
Learning: In WooCommerce taxonomy filter components like plugins/woocommerce/client/blocks/assets/js/blocks/product-filters/inner-blocks/taxonomy-filter/edit.tsx, taxonomy term objects fetched from WordPress core data APIs via getEntityRecords() have guaranteed structure and don't require additional validation for properties like term.id and term.parent since they come from trusted internal WordPress core data sources.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
📚 Learning: in woocommerce email editor (packages/js/email-editor/src/hacks/publish-save.tsx), the currentpost o...
Learnt from: lysyjan
PR: woocommerce/woocommerce#59931
File: packages/js/email-editor/src/hacks/publish-save.tsx:0-0
Timestamp: 2025-07-23T14:53:29.447Z
Learning: In WooCommerce email editor (packages/js/email-editor/src/hacks/publish-save.tsx), the currentPost obtained from select(editorStore).getCurrentPost() is guaranteed to always be a post object, so null safety checks are not required when accessing its properties like status.

Applied to files:

  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
📚 Learning: the core/spacer block in the woocommerce email editor intentionally does not have a dedicated render...
Learnt from: lysyjan
PR: woocommerce/woocommerce#59070
File: packages/php/email-editor/src/Integrations/Core/class-initializer.php:103-141
Timestamp: 2025-06-23T16:55:58.246Z
Learning: The core/spacer block in the WooCommerce email editor intentionally does not have a dedicated renderer class and is handled by the fallback renderer instead of having an explicit render_email_callback assigned in the switch statement.

Applied to files:

  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
🧬 Code Graph Analysis (1)
plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php (2)
plugins/woocommerce/src/Blocks/BlockTypes/AbstractBlock.php (1)
  • AbstractBlock (14-516)
plugins/woocommerce/includes/wc-conditional-functions.php (2)
  • wc_review_ratings_required (505-507)
  • wc_review_ratings_enabled (495-497)
🔇 Additional comments (5)
plugins/woocommerce/changelog/60213-feat-product-form-rating-selector-iapi (1)

1-4: LGTM!

The changelog entry is properly formatted and accurately describes the feature addition.

plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss (1)

17-20: LGTM! Well-structured styles for the interactive star rating.

The CSS implementation follows best practices:

  • Proper use of currentColor for themability
  • Clean button reset styles
  • Appropriate use of flexbox for layout
  • Consistent use of SCSS variables

Also applies to: 91-111

plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/block.json (1)

16-16: LGTM! Proper configuration for WordPress Interactivity API.

The block.json changes correctly:

  • Enable interactivity support for the block
  • Register the view script module for frontend functionality
  • Link appropriate style files for both frontend and editor

Also applies to: 60-62

plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php (2)

173-201: Well-implemented accessible star rating UI.

The render_stars() method properly handles:

  • Internationalization with proper pluralization
  • Accessibility with descriptive aria-labels
  • WordPress Interactivity API data binding
  • Clean SVG implementation

The phpcs ignore on line 187 is justified as wp_interactivity_data_wp_context returns pre-escaped output.


161-167: Proper use of WP_HTML_Tag_Processor for DOM manipulation.

Good implementation using WordPress's recommended approach for modifying HTML. The submit handler is correctly bound to the form element.

Copy link
Contributor

@gigitux gigitux left a comment

Choose a reason for hiding this comment

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

Thanks @dinhtungdu for working on this! Overall, this PR looks great! I noticed two issues that I think that we need to fix before merging this PR:

No Hover Icon

The cursor doesn't change when it hovers over the stars.

Before After
Screen.Capture.on.2025-08-08.at.10-06-05.mp4
Screen.Capture.on.2025-08-08.at.10-05-28.mp4

Select number of stars via arrow keys

It is not possible to select the number of stars via arrow keys. I guess that this is needed for accessibility reasons:

Before After
Screen.Capture.on.2025-08-08.at.10-11-59.mov
Screen.Capture.on.2025-08-08.at.10-11-40.mp4

if ( wc_review_ratings_enabled() ) {
$comment_form['comment_field'] = '<div class="comment-form-rating"><label for="rating-input" id="comment-form-rating-label">' .
esc_html__( 'Your rating', 'woocommerce' ) . ( wc_review_ratings_required() ? '&nbsp;<span class="required">*</span>' : '' ) .
'</label><input type="hidden" name="rating" id="rating-input" data-wp-bind--value="state.selectedStar">' .
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we add required to this input?

Copy link
Member Author

Choose a reason for hiding this comment

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

No. The required attribute has no effect on HTML <input type="hidden"> fields. Hidden inputs are never validated as required by browsers and do not prevent form submission if they are empty.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🔭 Outside diff range comments (1)
plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php (1)

34-36: Return type consistency: replace bare return; with return '';

render() is documented to return a string. Returning null (bare return;) can cause type inconsistencies downstream.

Apply this diff:

-		if ( post_password_required( $block->context['postId'] ) ) {
-			return;
-		}
+		if ( post_password_required( $block->context['postId'] ) ) {
+			return '';
+		}
🧹 Nitpick comments (2)
plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php (2)

48-63: Nit: avoid pre-escaping i18n config values; escape at render sites

i18n_required_rating_text is used as text (not HTML/attribute) by the frontend, so __() or esc_html__() (preferably the former) is enough; escape at output. Current esc_attr__() is harmless but slightly misleading.

Apply this diff:

-				'i18n_required_rating_text' => esc_attr__( 'Please select a rating', 'woocommerce' ),
+				'i18n_required_rating_text' => __( 'Please select a rating', 'woocommerce' ),

145-154: Add E2E coverage for interactions and validation (incl. keyboard)

Please add tests to cover:

  • Selecting a rating via mouse and keyboard (Tab/Space).
  • Validation error shown when required and no rating selected; error announcement is surfaced (role=alert).
  • No-JS fallback path (can be a non-JS Playwright context verifying the select).

I can draft Playwright specs targeting the rendered form, including keyboard flows and a non-JS context. Want me to push a test scaffold?

📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3fe51cb and 3f9b937.

📒 Files selected for processing (3)
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts (1 hunks)
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss (2 hunks)
  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/style.scss
  • plugins/woocommerce/client/blocks/assets/js/blocks/product-reviews/inner-blocks/review-form/frontend.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{php,js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/code-quality.mdc)

**/*.{php,js,jsx,ts,tsx}: Guard against unexpected inputs
Sanitize and validate any potentially dangerous inputs
Ensure code is backwards compatible
Write code that is readable and intuitive
Ensure code has unit or E2E tests where applicable

Files:

  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
**/*.{php,js,ts,jsx,tsx}

⚙️ CodeRabbit Configuration File

**/*.{php,js,ts,jsx,tsx}: Don't trust that extension developers will follow the best practices, make sure the code:

  • Guards against unexpected inputs.
  • Sanitizes and validates any potentially dangerous inputs.
  • Is backwards compatible.
  • Is readable and intuitive.
  • Has unit or E2E tests where applicable.

Files:

  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
PR: woocommerce/woocommerce#0
File: .cursor/rules/generate-pr-description.mdc:0-0
Timestamp: 2025-07-21T05:22:46.426Z
Learning: Provide clear, step-by-step instructions for how to test the changes in the PR description.
Learnt from: dinhtungdu
PR: woocommerce/woocommerce#59900
File: plugins/woocommerce/client/blocks/assets/js/blocks/product-filters/inner-blocks/attribute-filter/inspector.tsx:0-0
Timestamp: 2025-07-24T05:37:00.907Z
Learning: The DisplayStyleSwitcher component in plugins/woocommerce/client/blocks/assets/js/blocks/product-filters/components/display-style-switcher/index.tsx has been updated so that its onChange prop accepts only a string type (not string | number | undefined), eliminating the need for type assertions when using this component.
Learnt from: kmanijak
PR: woocommerce/woocommerce#60154
File: plugins/woocommerce/client/blocks/assets/js/blocks/next-previous-buttons/edit.tsx:80-80
Timestamp: 2025-08-04T11:58:34.139Z
Learning: In WooCommerce block Edit components (like plugins/woocommerce/client/blocks/assets/js/blocks/next-previous-buttons/edit.tsx), buttons are preview/display elements for the block editor interface and are not meant to be interactive, so accessibility attributes like ARIA labels are not necessary for these non-functional preview buttons.
Learnt from: ralucaStan
PR: woocommerce/woocommerce#58782
File: plugins/woocommerce/client/blocks/assets/js/base/utils/render-frontend.tsx:0-0
Timestamp: 2025-06-16T16:12:12.148Z
Learning: For WooCommerce checkout blocks, lazy loading was removed in favor of direct imports to prevent sequential "popping" effects during component loading. This approach prioritizes user experience over code splitting, with minimal bundle size impact and improved performance (1.7s to 1.1s speed score improvement). The checkout flow benefits from having all components load together rather than incrementally.
Learnt from: nerrad
PR: woocommerce/woocommerce#60176
File: plugins/woocommerce/client/legacy/css/admin.scss:9088-9105
Timestamp: 2025-08-04T00:21:51.440Z
Learning: WooCommerce is currently in the midst of an admin redesign project, so temporary/short-term CSS solutions for admin pages are preferred over long-term refactoring when addressing immediate needs.
Learnt from: Aljullu
PR: woocommerce/woocommerce#58809
File: plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php:222-225
Timestamp: 2025-06-13T17:11:13.732Z
Learning: In `plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php`, the team intentionally relies on toggling the `disabled` CSS class (via `data-wp-class--disabled`) instead of binding the `disabled` attribute, to mirror the behavior of the classic WooCommerce template.
Learnt from: samueljseay
PR: woocommerce/woocommerce#58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.
Learnt from: NeosinneR
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-26T14:25:08.421Z
Learning: In WooCommerce transactional emails, product images have historically had display issues due to lazy loading attributes being applied, which email clients cannot process since they don't execute JavaScript. This issue existed in both old and new email templates, but became more visible with the new email template system. The fix involves preventing lazy loading on attachment images specifically during email generation by adding skip classes and data attributes.
Learnt from: opr
PR: woocommerce/woocommerce#0
File: :0-0
Timestamp: 2025-06-20T17:38:16.565Z
Learning: WooCommerce legacy JavaScript files in plugins/woocommerce/client/legacy/js/ must use older JavaScript syntax and cannot use modern features like optional chaining (?.) due to browser compatibility requirements. Explicit null checking with && operators should be used instead.
Learnt from: prettyboymp
PR: woocommerce/woocommerce#59048
File: .github/workflows/cherry-pick-milestoned-prs.yml:60-83
Timestamp: 2025-06-26T12:45:40.709Z
Learning: WooCommerce uses WordPress versioning conventions where minor versions in X.Y.Z format are constrained to 0-9 (Y cannot exceed 9). This means version increment logic should reset minor to 0 and increment major when minor reaches 9, rather than allowing two-digit minor versions like 9.10 or 9.11.
📚 Learning: 2025-06-13T17:11:13.732Z
Learnt from: Aljullu
PR: woocommerce/woocommerce#58809
File: plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php:222-225
Timestamp: 2025-06-13T17:11:13.732Z
Learning: In `plugins/woocommerce/src/Blocks/BlockTypes/ProductButton.php`, the team intentionally relies on toggling the `disabled` CSS class (via `data-wp-class--disabled`) instead of binding the `disabled` attribute, to mirror the behavior of the classic WooCommerce template.

Applied to files:

  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: 2025-07-24T05:37:00.907Z
Learnt from: dinhtungdu
PR: woocommerce/woocommerce#59900
File: plugins/woocommerce/client/blocks/assets/js/blocks/product-filters/inner-blocks/attribute-filter/inspector.tsx:0-0
Timestamp: 2025-07-24T05:37:00.907Z
Learning: The DisplayStyleSwitcher component in plugins/woocommerce/client/blocks/assets/js/blocks/product-filters/components/display-style-switcher/index.tsx has been updated so that its onChange prop accepts only a string type (not string | number | undefined), eliminating the need for type assertions when using this component.

Applied to files:

  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: 2025-08-04T11:58:34.139Z
Learnt from: kmanijak
PR: woocommerce/woocommerce#60154
File: plugins/woocommerce/client/blocks/assets/js/blocks/next-previous-buttons/edit.tsx:80-80
Timestamp: 2025-08-04T11:58:34.139Z
Learning: In WooCommerce block Edit components (like plugins/woocommerce/client/blocks/assets/js/blocks/next-previous-buttons/edit.tsx), buttons are preview/display elements for the block editor interface and are not meant to be interactive, so accessibility attributes like ARIA labels are not necessary for these non-functional preview buttons.

Applied to files:

  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: 2025-06-17T12:40:54.118Z
Learnt from: gigitux
PR: woocommerce/woocommerce#58902
File: plugins/woocommerce/client/blocks/assets/js/blocks/product-specifications/edit.tsx:205-206
Timestamp: 2025-06-17T12:40:54.118Z
Learning: In WordPress blocks, when there's a styling mismatch between editor and frontend, check if the PHP renderer (like in `ProductSpecifications.php`) adds specific classes to the output. If so, add those same classes to the `useBlockProps` className in the editor component (like in `edit.tsx`) to ensure consistent styling. For example, adding `wp-block-table` class to both frontend and editor ensures core table styles and theme customizations apply consistently.

Applied to files:

  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: 2025-06-16T21:59:26.255Z
Learnt from: mreishus
PR: woocommerce/woocommerce#58891
File: plugins/woocommerce/src/Blocks/Utils/BlocksSharedState.php:0-0
Timestamp: 2025-06-16T21:59:26.255Z
Learning: In WooCommerce's CartSchema::get_item_response() method, when called in the context of BlocksSharedState::register_cart_interactivity(), the method returns a plain array rather than a WP_REST_Response object, making it directly suitable for wp_interactivity_state() without needing to call ->get_data().

Applied to files:

  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: 2025-06-23T05:47:52.696Z
Learnt from: samueljseay
PR: woocommerce/woocommerce#59051
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-footer-block/index.tsx:66-70
Timestamp: 2025-06-23T05:47:52.696Z
Learning: For WooCommerce mini-cart blocks in plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/, the standardized conditional pattern for experimental features should be `if ( isExperimentalMiniCartEnabled() ) { blockSettings.save = () => <InnerBlocks.Content />; }` - defaulting to the traditional Save component and only overriding when the experimental feature is enabled.

Applied to files:

  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: 2025-08-08T10:17:51.893Z
Learnt from: MaggieCabrera
PR: woocommerce/woocommerce#59940
File: plugins/woocommerce/client/blocks/assets/js/blocks/product-template/style.scss:28-28
Timestamp: 2025-08-08T10:17:51.893Z
Learning: In WooCommerce blocks, follow WordPress core’s approach for spacing: use the standard CSS gap property on flex containers without adding negative-margin fallbacks. This is acceptable for .wc-block-product-template.is-flex-container in plugins/woocommerce/client/blocks/assets/js/blocks/product-template/style.scss, while grid may include a simple supports fallback (gap → grid-gap). Align with WP’s browserslist baseline and Autoprefixer setup.

Applied to files:

  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: 2025-06-17T07:07:53.443Z
Learnt from: samueljseay
PR: woocommerce/woocommerce#58716
File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/iapi-frontend.ts:83-101
Timestamp: 2025-06-17T07:07:53.443Z
Learning: In WooCommerce blocks, when porting existing code patterns that have known issues (like parseInt truncating decimal money values), maintain consistency with existing implementation rather than making isolated fixes. The preference is for systematic refactoring approaches (like broader Dinero adoption) over piecemeal changes.

Applied to files:

  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: 2025-06-13T15:24:45.923Z
Learnt from: ralucaStan
PR: woocommerce/woocommerce#58782
File: plugins/woocommerce/client/blocks/assets/js/base/components/cart-checkout/product-details/style.scss:21-26
Timestamp: 2025-06-13T15:24:45.923Z
Learning: In WooCommerce blocks, bold styling for `.wc-block-components-product-details__name` should be scoped only to the Cart block (`.wc-block-cart__main`); on the Checkout block, product names are not bold because prices are highlighted instead.

Applied to files:

  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: 2025-06-23T16:55:58.246Z
Learnt from: lysyjan
PR: woocommerce/woocommerce#59070
File: packages/php/email-editor/src/Integrations/Core/class-initializer.php:103-141
Timestamp: 2025-06-23T16:55:58.246Z
Learning: The core/spacer block in the WooCommerce email editor intentionally does not have a dedicated renderer class and is handled by the fallback renderer instead of having an explicit render_email_callback assigned in the switch statement.

Applied to files:

  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
📚 Learning: 2025-06-25T06:51:41.381Z
Learnt from: samueljseay
PR: woocommerce/woocommerce#59142
File: plugins/woocommerce/src/Blocks/BlockTypes/MiniCart.php:594-602
Timestamp: 2025-06-25T06:51:41.381Z
Learning: WooCommerce block templates have a predictable structure where each block has one top-level div with wp-block-woocommerce- class containing arbitrary nested content that should be preserved.

Applied to files:

  • plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (27)
  • GitHub Check: Blocks e2e tests 1/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core API tests - @woocommerce/plugin-woocommerce [api]
  • GitHub Check: Blocks e2e tests 10/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 3/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 7/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 9/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 8/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 3/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 4/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 1/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Metrics - @woocommerce/plugin-woocommerce [performance]
  • GitHub Check: Core e2e tests 2/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 4/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Core e2e tests 6/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: PHP: 8.4 WP: latest [WP latest] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: Blocks e2e tests 2/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 5/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: Blocks e2e tests 6/10 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.3] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: Core e2e tests 5/6 - @woocommerce/plugin-woocommerce [e2e]
  • GitHub Check: PHP: 8.4 WP: latest [WP latest] 1/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: PHP: 7.4 WP: latest - 1 [WP 6.7.3] 2/2 - @woocommerce/plugin-woocommerce [unit:php]
  • GitHub Check: JavaScript - @woocommerce/block-library [unit]
  • GitHub Check: Lint - @woocommerce/plugin-woocommerce
  • GitHub Check: Lint - @woocommerce/block-library
  • GitHub Check: build
  • GitHub Check: Check Asset Sizes
🔇 Additional comments (1)
plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php (1)

5-13: Trait adoption LGTM

Using EnableBlockJsonAssetsTrait is the right move to wire block.json assets; nothing else needed here.

Comment on lines +131 to +138
if ( wc_review_ratings_enabled() ) {
$comment_form['comment_field'] = '<div class="comment-form-rating"><label for="rating-input" id="comment-form-rating-label">' .
esc_html__( 'Your rating', 'woocommerce' ) . ( wc_review_ratings_required() ? '&nbsp;<span class="required">*</span>' : '' ) .
'</label><input type="hidden" name="rating" id="rating-input" data-wp-bind--value="state.selectedStar">' .
'<p role="group" aria-labelledby="comment-form-rating-label" class="stars-wrapper">' . $this->render_stars() .
( wc_review_ratings_required() ? '<small data-wp-text="state.ratingError" class="rating-error" data-wp-bind--hidden="!state.hasError" aria-live="polite"></small>' : '' ) .
'</p></div>';
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add a no-JS fallback so users can select a rating without JavaScript

Currently, only the interactive UI can set the rating. With JS disabled, the hidden input remains “0” and users can't select a rating (blocking submission when ratings are required). Add a <noscript> fallback <select> to preserve progressive enhancement.

Apply this diff to inject a noscript fallback right after the hidden input:

-				'</label><input type="hidden" name="rating" id="rating-input" data-wp-bind--value="state.selectedStar">' .
+				'</label><input type="hidden" name="rating" id="rating-input" data-wp-bind--value="state.selectedStar">' .
+				'<noscript>' .
+				'<label class="screen-reader-text" for="rating-input-noscript">' . esc_html__( 'Your rating', 'woocommerce' ) . '</label>' .
+				'<select id="rating-input-noscript" name="rating"' . ( wc_review_ratings_required() ? ' required' : '' ) . '>' .
+					'<option value="">' . esc_html__( 'Rate&hellip;', 'woocommerce' ) . '</option>' .
+					'<option value="5">5</option><option value="4">4</option><option value="3">3</option><option value="2">2</option><option value="1">1</option>' .
+				'</select>' .
+				'</noscript>' .
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if ( wc_review_ratings_enabled() ) {
$comment_form['comment_field'] = '<div class="comment-form-rating"><label for="rating-input" id="comment-form-rating-label">' .
esc_html__( 'Your rating', 'woocommerce' ) . ( wc_review_ratings_required() ? '&nbsp;<span class="required">*</span>' : '' ) .
'</label><input type="hidden" name="rating" id="rating-input" data-wp-bind--value="state.selectedStar">' .
'<p role="group" aria-labelledby="comment-form-rating-label" class="stars-wrapper">' . $this->render_stars() .
( wc_review_ratings_required() ? '<small data-wp-text="state.ratingError" class="rating-error" data-wp-bind--hidden="!state.hasError" aria-live="polite"></small>' : '' ) .
'</p></div>';
}
if ( wc_review_ratings_enabled() ) {
$comment_form['comment_field'] = '<div class="comment-form-rating"><label for="rating-input" id="comment-form-rating-label">' .
esc_html__( 'Your rating', 'woocommerce' ) . ( wc_review_ratings_required() ? '&nbsp;<span class="required">*</span>' : '' ) .
'</label><input type="hidden" name="rating" id="rating-input" data-wp-bind--value="state.selectedStar">' .
'<noscript>' .
'<label class="screen-reader-text" for="rating-input-noscript">' . esc_html__( 'Your rating', 'woocommerce' ) . '</label>' .
'<select id="rating-input-noscript" name="rating"' . ( wc_review_ratings_required() ? ' required' : '' ) . '>' .
'<option value="">' . esc_html__( 'Rate&hellip;', 'woocommerce' ) . '</option>' .
'<option value="5">5</option><option value="4">4</option><option value="3">3</option><option value="2">2</option><option value="1">1</option>' .
'</select>' .
'</noscript>' .
'<p role="group" aria-labelledby="comment-form-rating-label" class="stars-wrapper">' . $this->render_stars() .
( wc_review_ratings_required() ? '<small data-wp-text="state.ratingError" class="rating-error" data-wp-bind--hidden="!state.hasError" aria-live="polite"></small>' : '' ) .
'</p></div>';
}
🤖 Prompt for AI Agents
In plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
around lines 131 to 138, the rating input uses a hidden field bound to
JavaScript state, which prevents users without JS from selecting a rating. To
fix this, add a <noscript> fallback containing a <select> dropdown for rating
selection immediately after the hidden input element. This ensures users without
JavaScript can still provide a rating, preserving progressive enhancement and
allowing form submission when ratings are required.

Comment on lines +135 to +137
'<p role="group" aria-labelledby="comment-form-rating-label" class="stars-wrapper">' . $this->render_stars() .
( wc_review_ratings_required() ? '<small data-wp-text="state.ratingError" class="rating-error" data-wp-bind--hidden="!state.hasError" aria-live="polite"></small>' : '' ) .
'</p></div>';
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve a11y semantics: use radiogroup, wire error to group, and expose invalid/required state

Convey single-selection semantics to assistive tech and announce validation errors properly.

Apply this diff:

-				'<p role="group" aria-labelledby="comment-form-rating-label" class="stars-wrapper">' . $this->render_stars() .
-				( wc_review_ratings_required() ? '<small data-wp-text="state.ratingError" class="rating-error" data-wp-bind--hidden="!state.hasError" aria-live="polite"></small>' : '' ) .
+				'<p role="radiogroup" aria-labelledby="comment-form-rating-label" class="stars-wrapper" data-wp-bind--aria-invalid="state.hasError"' . ( wc_review_ratings_required() ? ' aria-required="true"' : '' ) . ' aria-describedby="rating-error">' . $this->render_stars() .
+				( wc_review_ratings_required() ? '<small id="rating-error" data-wp-text="state.ratingError" class="rating-error" data-wp-bind--hidden="!state.hasError" role="alert"></small>' : '' ) .
🤖 Prompt for AI Agents
In plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
around lines 135 to 137, the current markup uses a paragraph with role="group"
for the rating stars, which does not fully convey single-selection semantics or
properly expose validation errors and required state to assistive technologies.
Update the container element to use role="radiogroup" instead of role="group",
associate the error message with the radiogroup using aria-describedby, and add
aria-invalid and aria-required attributes to reflect validation state. This will
improve accessibility by correctly signaling the input type and validation
status.

Comment on lines 178 to 199
<button
type="button"
<?php /* translators: %d is the rating value from 1 to 5 */ ?>
aria-label='<?php echo esc_attr( sprintf( _n( '%d of 5 star', '%d of 5 stars', $i, 'woocommerce' ), $i ) ); ?>'
data-wp-on-async--mouseenter="actions.hoverStar"
data-wp-on-async--mouseleave="actions.leaveStar"
data-wp-on-async--click="actions.selectStar"
data-wp-on-async--keyup="actions.changeRatingWithKeyboard"
data-wp-class--is-hovered="state.isStarHovered"
data-wp-class--is-selected="state.isStarSelected"
<?php echo wp_interactivity_data_wp_context( array( 'starValue' => $i ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
>
<svg
width='24'
height='24'
viewBox='0 0 24 24'
>
<path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z" fill="none" stroke="currentColor" stroke-width="1.5"/>
</svg>
</button>
<?php
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Mark each star as a radio and expose selection via aria-checked; hide decorative SVG from AT

This clarifies the control as a 1-of-5 choice and avoids SRs announcing the SVG.

Apply this diff:

 			<button
 				type="button"
+				role="radio"
+				data-wp-bind--aria-checked="state.isStarSelected"
 				<?php /* translators: %d is the rating value from 1 to 5 */ ?>
 				aria-label='<?php echo esc_attr( sprintf( _n( '%d of 5 star', '%d of 5 stars', $i, 'woocommerce' ), $i ) ); ?>'
 				data-wp-on-async--mouseenter="actions.hoverStar"
 				data-wp-on-async--mouseleave="actions.leaveStar"
 				data-wp-on-async--click="actions.selectStar"
 				data-wp-on-async--keyup="actions.changeRatingWithKeyboard"
 				data-wp-class--is-hovered="state.isStarHovered"
 				data-wp-class--is-selected="state.isStarSelected"
 				<?php echo wp_interactivity_data_wp_context( array( 'starValue' => $i ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
 			>
 				<svg
 					width='24'
 					height='24'
 					viewBox='0 0 24 24'
+					aria-hidden="true"
+					focusable="false"
 				>
🤖 Prompt for AI Agents
In plugins/woocommerce/src/Blocks/BlockTypes/Reviews/ProductReviewForm.php
between lines 178 and 199, update each star button to have role="radio" and add
aria-checked attribute reflecting whether the star is selected. Also, add
aria-hidden="true" to the SVG element to hide it from assistive technologies.
This will mark the stars as radio options and prevent screen readers from
announcing the decorative SVG.

@dinhtungdu dinhtungdu requested review from a team and Aljullu and removed request for a team August 11, 2025 00:18
@dinhtungdu dinhtungdu marked this pull request as draft August 11, 2025 00:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
plugin: woocommerce Issues related to the WooCommerce Core plugin.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants