Skip to content

feat(accessibility): enhance screen reader support with ARIA attributes and hidden elements#28

Closed
marloonline123 wants to merge 3 commits into
chetanupare:masterfrom
marloonline123:add-aria-labels-and-accessibility-10
Closed

feat(accessibility): enhance screen reader support with ARIA attributes and hidden elements#28
marloonline123 wants to merge 3 commits into
chetanupare:masterfrom
marloonline123:add-aria-labels-and-accessibility-10

Conversation

@marloonline123

@marloonline123 marloonline123 commented Jan 30, 2026

Copy link
Copy Markdown

📋 Pull Request Description

Enhance screen reader support with ARIA attributes and hidden elements

🎯 What does this PR do?

Enhance screen reader support with ARIA attributes and hidden elements

🔗 Related Issues

🔄 Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📚 Documentation update
  • 🎨 Code style/formatting
  • ♻️ Code refactoring
  • ⚡ Performance improvement
  • 🔒 Security improvement
  • 🧪 Test addition/improvement

🧪 Testing

✅ Test Environment

  • WordPress Version:
  • WooCommerce Version:
  • PHP Version:
  • Browser(s) tested:

🔍 Testing Steps

📸 Screenshots/Videos

📝 Code Quality

✅ Code Standards

  • Code follows WordPress coding standards
  • Code is properly documented (PHPDoc comments)
  • All functions and classes have appropriate access modifiers
  • No PHP errors or warnings
  • Code passes PHPCS validation
  • Variables are properly sanitized/escaped

🛡️ Security

  • All user inputs are sanitized
  • All outputs are properly escaped
  • Nonces are used for forms/AJAX requests
  • Capability checks are in place
  • No SQL injection vulnerabilities
  • No XSS vulnerabilities

⚡ Performance

  • No performance regressions introduced
  • Database queries are optimized
  • Caching is used where appropriate
  • No memory leaks

📖 Documentation

📚 Documentation Updates

  • README.md updated (if needed)
  • CHANGELOG.md updated
  • Code comments added/updated
  • PHPDoc blocks added/updated
  • User documentation updated (if needed)

💡 Usage Examples

// Example usage

🔄 Backward Compatibility

🔒 Compatibility Check

  • ✅ Fully backward compatible
  • ⚠️ Deprecates old functionality (with proper notices)
  • 💥 Breaking change (requires major version bump)

📋 Migration Notes

🚀 Deployment

📦 Release Notes

🎯 Target Version

  • Patch release (x.x.X)
  • Minor release (x.X.x)
  • Major release (X.x.x)

✅ Checklist

🔍 Pre-submission

  • I have read the CONTRIBUTING.md guidelines
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings or errors
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

🧪 Testing

  • I have tested on a fresh WordPress installation
  • I have tested with different themes
  • I have tested with common plugins
  • I have tested the import/export functionality (if applicable)
  • I have tested on mobile devices (if frontend changes)

📋 Final Review

  • My code follows the project's style guidelines
  • I have squashed unnecessary commits
  • My commit messages are clear and descriptive
  • I have updated version numbers where appropriate

💬 Additional Notes

👀 Review Requests

@chetanupare


Thank you for contributing to WooHSN Pro! 🙏

Summary by CodeRabbit

  • Accessibility

    • Live regions added for status updates on HSN code and GST fields
    • Improved keyboard navigation for HSN suggestions (arrow keys, Enter/Space)
    • Added descriptive labels and guidance text for form fields
    • Accessible suggestion list with clear selection feedback and dynamic status updates
  • Style

    • Added screen-reader-specific CSS to hide visual elements while preserving assistive access

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Jan 30, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds accessibility features to the admin UI: a new .screen-reader-text CSS class and extensive ARIA/live-region enhancements, keyboard navigation, and AJAX-driven HSN suggestion handling in the product meta box. No public method signatures were changed.

Changes

Cohort / File(s) Summary
Accessibility Styles
assets/css/admin.css
Added .screen-reader-text block to hide text visually while keeping it accessible to assistive technologies.
Product Meta Box Accessibility & Behavior
includes/class-woohsn-product.php
Refactored meta box markup and JS behavior to add ARIA attributes, descriptive screen-reader text, an aria-live status region, accessible suggestion list (click + keyboard: Arrow keys, Enter/Space), accessible Show/Hide for custom GST field, and a loadHsnInfo AJAX flow for fetching HSN descriptions and GST rates. No public class/method signatures changed.

Sequence Diagram(s)

sequenceDiagram
  participant Editor as Admin UI (Browser)
  participant Ajax as AJAX Handler (Server)
  participant ProductStore as Product Data (DB / WP API)

  Editor->>Editor: User clicks "Suggest" (HSN)
  Editor->>Ajax: POST /wp-admin/admin-ajax.php (hsn_suggest)
  note right of Ajax: Server resolves suggestions
  Ajax->>ProductStore: Query HSN data
  ProductStore-->>Ajax: HSN suggestions/metadata
  Ajax-->>Editor: JSON suggestions
  Editor->>Editor: Render accessible list, update aria-live region ("Suggestions loaded")
  Editor->>Editor: User navigates list (Arrow keys) and selects (Enter/Space)
  Editor->>Ajax: Optional POST to loadHsnInfo (HSN details)
  Ajax-->>Editor: HSN description and GST rate
  Editor->>Editor: Populate fields and announce via aria-live
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

"I nibble tags and polish ARIA,
I hop through code to make it merry.
Live regions sing, suggestions bloom,
Screen-reader friends find room to zoom.
Hoppy access—cheers from me! 🐇"

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding screen reader support through ARIA attributes and hidden elements, which aligns perfectly with the changeset.
Description check ✅ Passed The description covers core requirements (what, type, related issue #10) but leaves many template sections incomplete: test environment details, testing steps, code quality checks, security checks, performance checks, documentation updates, compatibility assessment, and deployment target are mostly blank or unchecked.
Linked Issues check ✅ Passed The PR successfully addresses all key objectives from issue #10: adds ARIA labels/descriptions to form fields, implements keyboard navigation for HSN suggestions, provides screen reader announcements via live regions, and introduces accessible list structures meeting WCAG compliance.
Out of Scope Changes check ✅ Passed All changes are directly related to issue #10 accessibility improvements: CSS adds screen-reader-text class, PHP adds ARIA attributes, live regions, keyboard navigation, and accessible form elements. No unrelated changes detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🤖 Fix all issues with AI agents
In `@includes/class-woohsn-product.php`:
- Around line 158-163: The HTML string concatenation that builds suggestion
items inserts unescaped values (item.hsn_code, item.description, item.gst_rate)
directly into the DOM; change this to escape user-controlled content before
inserting by adding a small helper (e.g., escapeHtml) or using DOM/jQuery text
APIs instead of raw string concatenation when constructing the suggestion list
in the block that builds html (the lines creating woohsn-suggestion li and
concatenating item.hsn_code/item.description/item.gst_rate); ensure you call the
escape helper (or set textContent/.text()) for each of those fields so no
unescaped HTML can be injected.
- Around line 144-189: The AJAX call that builds suggestions (the $.ajax in the
woohsn_suggest_hsn request) lacks an error handler: add an error callback to
that $.ajax to set the live region '#woohsn-status' to a meaningful failure
message (e.g., "Failed to load HSN suggestions. Please try again."), hide
'#woohsn-suggestions', set '#woohsn-suggest-btn' aria-expanded to false, and
ensure suggestion aria-selected states are reset; do the same for the AJAX
inside loadHsnInfo (the loadHsnInfo request block) so any failure updates
'#woohsn-status' with a clear error and leaves the UI in a consistent,
accessible state.
- Line 169: The jQuery selector incorrectly uses '#woohsn_status' (underscore)
so the live region update fails; change the selector in the snippet that sets
$('#woohsn_status').text(...) to match the actual live region id 'woohsn-status'
(use '#woohsn-status') so the announcement for productTitle is applied to the
correct element (or replace with
document.getElementById('woohsn-status').textContent = ... if preferring vanilla
DOM).
- Around line 129-132: The screen-reader announcement strings set via
$('#woohsn-status').text(...) have subject-verb agreement errors; update the two
messages used in the conditional that manipulates $('#woohsn-custom-gst-field')
so they read correctly (e.g., change "Custom GST field are shown to enter a
custom GST rate." to "Custom GST field is shown. Enter a custom GST rate." and
"Custom GST field are hidden." to "Custom GST field is hidden.") — locate the
jQuery .text(...) calls that set '#woohsn-status' and update the string literals
accordingly.
- Around line 166-168: The JS currently uses jQuery .show()/.hide() which
conflicts with the element's use of the HTML hidden attribute; update the code
that manipulates '#woohsn-suggestions' (and where you update
'#woohsn-suggestions-list' and '#woohsn-suggest-btn') to remove the hidden
attribute when revealing (use removeAttr('hidden')) and set the hidden attribute
when hiding (use attr('hidden', true)), and continue to update
'#woohsn-suggest-btn' aria-expanded accordingly so semantics and visual state
remain consistent.
- Around line 79-81: Replace the hardcoded English screen-reader texts with
WordPress translation functions: locate the <p id="woohsn-code-description">
element (and the other two similar <p> elements noted in the review) in
class-woohsn-product.php and output the strings via esc_html_e( 'Enter the HSN
code for the product.', 'your-text-domain' ) (and the corresponding translated
strings for the other two descriptions) instead of plain text so i18n is
supported; ensure you use the same text domain used elsewhere in this file.
- Around line 228-229: The code injects info.description and info.gst_rate into
the DOM with .html(), creating an XSS risk; change the logic that updates
'#woohsn-hsn-description' and '#woohsn-hsn-gst-rate' to escape/encode the values
instead of inserting raw HTML — e.g., create the label markup separately and set
the dynamic parts with text-safe insertion (use .text() or equivalent escaping
for info.description and info.gst_rate) so info.description and info.gst_rate
are never interpreted as HTML.
- Around line 157-164: The suggestion items rendering in suggestions.forEach
currently sets tabindex to the numeric index which produces a non-standard tab
order; change the generation in the suggestions.forEach loop that builds
elements with id "woohsn-suggestion-" and class "woohsn-suggestion" so the first
item receives tabindex="0" and all other items receive tabindex="-1", then rely
on the existing arrow-key focus management logic (the code around the arrow key
handlers) to move focus and update tabindex values programmatically.
- Line 29: Two classes register the same AJAX hook causing duplicate callbacks:
remove one add_action registration for 'wp_ajax_woohsn_get_hsn_info'. Locate the
duplicate add_action call that registers 'wp_ajax_woohsn_get_hsn_info' (the one
inside the class that should not own the handler) and delete that line so only
the class that implements the ajax_get_hsn_info method (the class that actually
defines ajax_get_hsn_info) keeps the add_action; ensure the remaining
registration points to the correct callback (array($this, 'ajax_get_hsn_info'))
and that ajax_get_hsn_info remains defined in that class (e.g., methods in
Woohsn_Product vs Woohsn_Database).
🧹 Nitpick comments (4)
includes/class-woohsn-product.php (3)

97-97: Inconsistent PHP echo syntax.

Line 97 uses the shorthand <?= ?> while the rest of the file uses <?php echo ?> or <?php esc_attr() ?>. For consistency with WordPress coding standards and the rest of this file, use the long form.

♻️ Proposed fix
-aria-expanded="<?= $enable_custom_gst === 'yes' ? 'true' : 'false' ?>" />
+aria-expanded="<?php echo $enable_custom_gst === 'yes' ? 'true' : 'false'; ?>" />

83-91: Consider removing aria-live from suggestions region.

The suggestions container has aria-live="polite" (line 86), but you're already announcing via the dedicated status region (#woohsn-status). This could cause duplicate announcements. Since the suggestions appear after user-initiated action (clicking "Suggest"), the live region on the status div is sufficient.

♻️ Proposed simplification
 <div
     id="woohsn-suggestions"
     role="region"
-    aria-live="polite"
     aria-label="HSN code suggestions"
     hidden>

200-213: Keyboard navigation could be enhanced.

Good implementation of arrow key navigation and Enter/Space selection. Consider adding:

  1. Escape key to close suggestions without selection
  2. Focus management after selection - return focus to the HSN input field
♻️ Proposed enhancement
 $('#woohsn-suggestions-list').on('keydown', '.woohsn-suggestion', function(e) {
     var $current = $(this);
     if (e.key === 'ArrowDown') {
         e.preventDefault();
         $current.next().focus();
     } else if (e.key === 'ArrowUp') {
         e.preventDefault();
         $current.prev().focus();
     } else if (e.key === 'Enter' || e.key === ' ') {
         e.preventDefault();
         $current.click(); // select
+    } else if (e.key === 'Escape') {
+        e.preventDefault();
+        $('#woohsn-suggestions').attr('hidden', true);
+        $('#woohsn-suggest-btn').attr('aria-expanded', 'false');
+        $('#woohsn_code').focus();
     }
 });

Also add focus return after selection in the click handler (around line 186):

$('#woohsn_code').focus();
assets/css/admin.css (1)

378-392: Consider removing the duplicate .screen-reader-text class.

WordPress core already provides a .screen-reader-text class in wp-admin, which this plugin inherits automatically. Since this stylesheet is loaded only in the WordPress admin context and all usages are within admin meta boxes, the custom definition is unnecessary and can be removed. The plugin will automatically use WordPress's core implementation without this duplication.

@@ -25,11 +28,12 @@ public function __construct() {
add_action('wp_ajax_woohsn_suggest_hsn', array($this, 'ajax_suggest_hsn'));
add_action('wp_ajax_woohsn_get_hsn_info', array($this, 'ajax_get_hsn_info'));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find all occurrences of the AJAX action
rg -n "wp_ajax_woohsn_get_hsn_info" --type php

Repository: chetanupare/product-hsn-code

Length of output: 318


Remove duplicate AJAX action registration.

Both class-woohsn-product.php (line 29) and class-woohsn-database.php (line 21) register the same AJAX action wp_ajax_woohsn_get_hsn_info. When the same action hook is registered multiple times, WordPress executes all callbacks, leading to duplicate processing and potential conflicts. Remove one of these registrations.

🤖 Prompt for AI Agents
In `@includes/class-woohsn-product.php` at line 29, Two classes register the same
AJAX hook causing duplicate callbacks: remove one add_action registration for
'wp_ajax_woohsn_get_hsn_info'. Locate the duplicate add_action call that
registers 'wp_ajax_woohsn_get_hsn_info' (the one inside the class that should
not own the handler) and delete that line so only the class that implements the
ajax_get_hsn_info method (the class that actually defines ajax_get_hsn_info)
keeps the add_action; ensure the remaining registration points to the correct
callback (array($this, 'ajax_get_hsn_info')) and that ajax_get_hsn_info remains
defined in that class (e.g., methods in Woohsn_Product vs Woohsn_Database).

Comment thread includes/class-woohsn-product.php
Comment thread includes/class-woohsn-product.php Outdated
Comment on lines +129 to +132
$('#woohsn-status').text('Custom GST field are shown to enter a custom GST rate.');
} else {
$('#woohsn-custom-gst-field').hide();
$('#woohsn-status').text('Custom GST field are hidden.');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Grammar errors in screen reader announcements.

The announcements have subject-verb agreement issues that may confuse screen reader users.

📝 Proposed fix
-$('#woohsn-status').text('Custom GST field are shown to enter a custom GST rate.');
+$('#woohsn-status').text('Custom GST field is now shown. Enter a custom GST rate.');
...
-$('#woohsn-status').text('Custom GST field are hidden.');
+$('#woohsn-status').text('Custom GST field is now hidden.');
📝 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
$('#woohsn-status').text('Custom GST field are shown to enter a custom GST rate.');
} else {
$('#woohsn-custom-gst-field').hide();
$('#woohsn-status').text('Custom GST field are hidden.');
$('#woohsn-status').text('Custom GST field is now shown. Enter a custom GST rate.');
} else {
$('#woohsn-custom-gst-field').hide();
$('#woohsn-status').text('Custom GST field is now hidden.');
🤖 Prompt for AI Agents
In `@includes/class-woohsn-product.php` around lines 129 - 132, The screen-reader
announcement strings set via $('#woohsn-status').text(...) have subject-verb
agreement errors; update the two messages used in the conditional that
manipulates $('#woohsn-custom-gst-field') so they read correctly (e.g., change
"Custom GST field are shown to enter a custom GST rate." to "Custom GST field is
shown. Enter a custom GST rate." and "Custom GST field are hidden." to "Custom
GST field is hidden.") — locate the jQuery .text(...) calls that set
'#woohsn-status' and update the string literals accordingly.

Comment on lines +144 to +189
$.ajax({
url: ajaxurl,
type: 'POST',
data: {
action: 'woohsn_suggest_hsn',
product_title: productTitle,
nonce: '<?php echo wp_create_nonce('woohsn_nonce'); ?>'
},
success: function(response) {
if (response.success) {
var suggestions = response.data;
var html = '';

suggestions.forEach(function(item, index) {
html += '<li role="option" tabindex="' + index + '" aria-selected="false" id="woohsn-suggestion-' + index + '" class="woohsn-suggestion" style="margin: 5px 0; padding: 8px; border: 1px solid #ddd; cursor: pointer;">';
html += '<strong>' + item.hsn_code + '</strong> - ' + item.description;
if (item.gst_rate) {
html += ' (GST: ' + item.gst_rate + '%)';
}
html += '</li>';
});

$('#woohsn-suggestions-list').html(html);
$('#woohsn-suggestions').show();
$('#woohsn-suggest-btn').attr('aria-expanded', 'true');
$('#woohsn_status').text('Suggested HSN codes for "' + productTitle + '" are Loaded.');

// Handle suggestion clicks
$('.woohsn-suggestion').click(function() {
var hsnCode = $(this).find('strong').text();
$('#woohsn_code').val(hsnCode);
$('#woohsn-suggestions').hide();
$('#woohsn-suggest-btn').attr('aria-expanded', 'false');

// Update live region
$('#woohsn-status').text('HSN code ' + hsnCode + ' selected.');

// Optional: mark selected suggestion for screen readers
$('.woohsn-suggestion').attr('aria-selected', 'false'); // reset others
$(this).attr('aria-selected', 'true');

loadHsnInfo(hsnCode);
});
}
}
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing AJAX error handling.

Neither AJAX call has an error callback. If the request fails, users (especially screen reader users) receive no feedback. Consider adding error handling that updates the live region.

🛠️ Proposed enhancement
$.ajax({
    // ... existing options ...
    success: function(response) { /* ... */ },
    error: function() {
        $('#woohsn-status').text('Failed to load HSN suggestions. Please try again.');
    }
});

Apply similar pattern to loadHsnInfo (lines 217-235).

🤖 Prompt for AI Agents
In `@includes/class-woohsn-product.php` around lines 144 - 189, The AJAX call that
builds suggestions (the $.ajax in the woohsn_suggest_hsn request) lacks an error
handler: add an error callback to that $.ajax to set the live region
'#woohsn-status' to a meaningful failure message (e.g., "Failed to load HSN
suggestions. Please try again."), hide '#woohsn-suggestions', set
'#woohsn-suggest-btn' aria-expanded to false, and ensure suggestion
aria-selected states are reset; do the same for the AJAX inside loadHsnInfo (the
loadHsnInfo request block) so any failure updates '#woohsn-status' with a clear
error and leaves the UI in a consistent, accessible state.

Comment thread includes/class-woohsn-product.php
Comment thread includes/class-woohsn-product.php Outdated
Comment on lines +166 to +168
$('#woohsn-suggestions-list').html(html);
$('#woohsn-suggestions').show();
$('#woohsn-suggest-btn').attr('aria-expanded', 'true');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Inconsistent use of hidden attribute vs. jQuery .show()/.hide().

The container uses the HTML hidden attribute (line 88), but the JS uses jQuery's .show() which only sets inline display styles without removing the hidden attribute. For consistency and proper semantics, use .removeAttr('hidden') and .attr('hidden', true) instead.

🛠️ Proposed fix
-$('#woohsn-suggestions').show();
+$('#woohsn-suggestions').removeAttr('hidden');

And for hiding (line 175):

-$('#woohsn-suggestions').hide();
+$('#woohsn-suggestions').attr('hidden', true);
📝 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
$('#woohsn-suggestions-list').html(html);
$('#woohsn-suggestions').show();
$('#woohsn-suggest-btn').attr('aria-expanded', 'true');
$('#woohsn-suggestions-list').html(html);
$('#woohsn-suggestions').removeAttr('hidden');
$('#woohsn-suggest-btn').attr('aria-expanded', 'true');
🤖 Prompt for AI Agents
In `@includes/class-woohsn-product.php` around lines 166 - 168, The JS currently
uses jQuery .show()/.hide() which conflicts with the element's use of the HTML
hidden attribute; update the code that manipulates '#woohsn-suggestions' (and
where you update '#woohsn-suggestions-list' and '#woohsn-suggest-btn') to remove
the hidden attribute when revealing (use removeAttr('hidden')) and set the
hidden attribute when hiding (use attr('hidden', true)), and continue to update
'#woohsn-suggest-btn' aria-expanded accordingly so semantics and visual state
remain consistent.

Comment thread includes/class-woohsn-product.php Outdated
Comment thread includes/class-woohsn-product.php Outdated
All user-facing strings within HTML paragraphs (`<p>`) are now wrapped in `esc_html_e()` for proper internationalization. Similarly, JavaScript strings are wrapped in `esc_js_e()`.

Dynamic content like HSN codes, descriptions, and GST rates displayed in suggestion lists are now explicitly escaped using `escapeHtml()` to mitigate cross-site scripting risks.

navigation:** The `tabindex` for HSN suggestions is adjusted, setting the first suggestion to `0` and subsequent ones to `-1`, which improves keyboard focus management for screen readers and keyboard users.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@includes/class-woohsn-product.php`:
- Around line 178-180: Replace the hardcoded JS live-region update for
'#woohsn-status' so the announcement is localized: instead of "HSN code " +
hsnCode + " selected." use a localized string emitted with esc_js_e() (with a
placeholder like "%s" for the HSN) and inject hsnCode into that placeholder
(e.g., via sprintf or similar) before setting the element text; update the code
that sets $('#woohsn-status').text(...) to use esc_js_e() with a placeholder and
the hsnCode variable so the message follows the file's existing localization
pattern.
- Around line 83-88: Replace the hard-coded aria-label on the element with id
"woohsn-suggestions" by outputting a localized, escaped string using
esc_attr_e() and the 'woohsn' text domain (matching the pattern used for the
input placeholder); specifically, remove the static "HSN code suggestions" value
and echo the translated/escaped label via esc_attr_e('HSN code suggestions',
'woohsn') so the aria-label is translatable and properly escaped.
- Around line 125-133: The change handler for the checkbox
'#woohsn_enable_custom_gst' toggles visibility of '#woohsn-custom-gst-field' but
does not update its aria-expanded state for assistive tech; modify the handler
inside the change callback to set
$('#woohsn-custom-gst-field').attr('aria-expanded', 'true') when showing and
.attr('aria-expanded', 'false') when hiding, and ensure the checkbox element
'#woohsn_enable_custom_gst' (or the target container) has the matching
aria-expanded attribute updated in both branches so screen readers receive the
state change.
🧹 Nitpick comments (1)
includes/class-woohsn-product.php (1)

200-213: Update roving tabindex on arrow navigation.

Focus moves, but tabindex stays unchanged; update it so the tab stop follows the focused option.

🛠️ Suggested fix
                     if (e.key === 'ArrowDown') {
                         e.preventDefault();
-                        $current.next().focus();
+                        var $next = $current.next();
+                        if ($next.length) {
+                            $current.attr('tabindex', '-1');
+                            $next.attr('tabindex', '0').focus();
+                        }
                     } else if (e.key === 'ArrowUp') {
                         e.preventDefault();
-                        $current.prev().focus();
+                        var $prev = $current.prev();
+                        if ($prev.length) {
+                            $current.attr('tabindex', '-1');
+                            $prev.attr('tabindex', '0').focus();
+                        }
                     } else if (e.key === 'Enter' || e.key === ' ') {

Comment on lines +83 to +88
<div
id="woohsn-suggestions"
role="region"
aria-live="polite"
aria-label="HSN code suggestions"
hidden>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's locate and examine the file
find . -name "class-woohsn-product.php" -type f

Repository: chetanupare/product-hsn-code

Length of output: 107


🏁 Script executed:

# Check if the file exists and examine lines 83-88
if [ -f "includes/class-woohsn-product.php" ]; then
  echo "=== File found. Showing lines 83-88 ==="
  sed -n '83,88p' includes/class-woohsn-product.php
  echo ""
  echo "=== Context: lines 75-95 ==="
  sed -n '75,95p' includes/class-woohsn-product.php
fi

Repository: chetanupare/product-hsn-code

Length of output: 1177


🏁 Script executed:

# Search for other aria-label usage in the codebase to see if there's a pattern
rg 'aria-label' --type php -B 2 -A 2

Repository: chetanupare/product-hsn-code

Length of output: 475


🏁 Script executed:

# Check if text domain 'woohsn' is used elsewhere in the codebase
rg "'woohsn'" --type php | head -20

Repository: chetanupare/product-hsn-code

Length of output: 2819


Localize and escape the aria-label.

The aria-label value is user-facing and should be translatable and escaped to match the localization pattern used throughout this file. Use esc_attr_e() with the 'woohsn' text domain, similar to the placeholder attribute on the input field above.

-                aria-label="HSN code suggestions"
+                aria-label="<?php esc_attr_e('HSN code suggestions', 'woohsn'); ?>"
🤖 Prompt for AI Agents
In `@includes/class-woohsn-product.php` around lines 83 - 88, Replace the
hard-coded aria-label on the element with id "woohsn-suggestions" by outputting
a localized, escaped string using esc_attr_e() and the 'woohsn' text domain
(matching the pattern used for the input placeholder); specifically, remove the
static "HSN code suggestions" value and echo the translated/escaped label via
esc_attr_e('HSN code suggestions', 'woohsn') so the aria-label is translatable
and properly escaped.

Comment on lines +125 to 133
// Toggle custom GST field
$('#woohsn_enable_custom_gst').change(function() {
if ($(this).is(':checked')) {
$('#woohsn-custom-gst-field').show();
$('#woohsn-status').text('<?php esc_js_e('Custom GST field are shown to enter a custom GST rate.', 'woohsn'); ?>');
} else {
$('#woohsn-custom-gst-field').hide();
$('#woohsn-status').text('<?php esc_js_e('Custom GST field are hidden.', 'woohsn'); ?>');
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

find . -name "class-woohsn-product.php" -type f

Repository: chetanupare/product-hsn-code

Length of output: 107


🏁 Script executed:

wc -l ./includes/class-woohsn-product.php

Repository: chetanupare/product-hsn-code

Length of output: 111


🏁 Script executed:

sed -n '100,150p' ./includes/class-woohsn-product.php

Repository: chetanupare/product-hsn-code

Length of output: 2864


🏁 Script executed:

sed -n '1,100p' ./includes/class-woohsn-product.php | grep -A 5 -B 5 "woohsn_enable_custom_gst"

Repository: chetanupare/product-hsn-code

Length of output: 1426


Update aria-expanded when toggling the custom GST checkbox.

The aria-expanded attribute is set correctly at render time, but the change handler doesn't update it when the user toggles the checkbox. Screen readers won't see the state change. Add aria-expanded updates to both branches of the toggle:

Suggested fix
                    if ($(this).is(':checked')) {
                        $('#woohsn-custom-gst-field').show();
+                       $(this).attr('aria-expanded', 'true');
                        $('#woohsn-status').text('<?php esc_js_e('Custom GST field are shown to enter a custom GST rate.', 'woohsn'); ?>');
                    } else {
                        $('#woohsn-custom-gst-field').hide();
+                       $(this).attr('aria-expanded', 'false');
                        $('#woohsn-status').text('<?php esc_js_e('Custom GST field are hidden.', 'woohsn'); ?>');
                    }
🤖 Prompt for AI Agents
In `@includes/class-woohsn-product.php` around lines 125 - 133, The change handler
for the checkbox '#woohsn_enable_custom_gst' toggles visibility of
'#woohsn-custom-gst-field' but does not update its aria-expanded state for
assistive tech; modify the handler inside the change callback to set
$('#woohsn-custom-gst-field').attr('aria-expanded', 'true') when showing and
.attr('aria-expanded', 'false') when hiding, and ensure the checkbox element
'#woohsn_enable_custom_gst' (or the target container) has the matching
aria-expanded attribute updated in both branches so screen readers receive the
state change.

Comment on lines +178 to +180
// Update live region
$('#woohsn-status').text('HSN code ' + hsnCode + ' selected.');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

wc -l includes/class-woohsn-product.php

Repository: chetanupare/product-hsn-code

Length of output: 109


🏁 Script executed:

sed -n '160,200p' includes/class-woohsn-product.php

Repository: chetanupare/product-hsn-code

Length of output: 2146


🏁 Script executed:

rg -n "woohsn-status" includes/ -A 2 -B 2

Repository: chetanupare/product-hsn-code

Length of output: 2384


🏁 Script executed:

rg -n "__\(" includes/class-woohsn-product.php | head -20

Repository: chetanupare/product-hsn-code

Length of output: 425


Localize the selection announcement.

The live-region text is hardcoded English. Other status messages in this file use esc_js_e() for localization (see lines 129, 132, 169); apply the same pattern here.

🤖 Prompt for AI Agents
In `@includes/class-woohsn-product.php` around lines 178 - 180, Replace the
hardcoded JS live-region update for '#woohsn-status' so the announcement is
localized: instead of "HSN code " + hsnCode + " selected." use a localized
string emitted with esc_js_e() (with a placeholder like "%s" for the HSN) and
inject hsnCode into that placeholder (e.g., via sprintf or similar) before
setting the element text; update the code that sets
$('#woohsn-status').text(...) to use esc_js_e() with a placeholder and the
hsnCode variable so the message follows the file's existing localization
pattern.

@chetanupare

Copy link
Copy Markdown
Owner

@marloonline123 Looks like the branch is out of sync — please pull the latest changes locally and recreate the PR. Thanks!

@marloonline123

Copy link
Copy Markdown
Author

ok @chetanupare

@marloonline123

Copy link
Copy Markdown
Author

@chetanupare hoping everything is good now

@chetanupare chetanupare left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

fix

@chetanupare

Copy link
Copy Markdown
Owner

Thank you for your contribution @marloonline123 !
The accessibility features have been merged into master via a synchronized branch.
Closing this PR as the changes are now included in the main codebase.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add ARIA labels and accessibility improvements

2 participants