Skip to content

feat: Enhance Sticky Menu Block with Improved Inspector Controls, UX, and Keyboard Accessibility#773

Merged
krugazul merged 6 commits into2.1-trunkfrom
feature/771-sticky-menu-design-ux-improvements
Nov 21, 2025
Merged

feat: Enhance Sticky Menu Block with Improved Inspector Controls, UX, and Keyboard Accessibility#773
krugazul merged 6 commits into2.1-trunkfrom
feature/771-sticky-menu-design-ux-improvements

Conversation

@tibiii
Copy link
Copy Markdown
Contributor

@tibiii tibiii commented Nov 20, 2025


name: "Sticky Menu Block Enhancement"
about: "Refactor sticky menu block with improved inspector controls, color management, and accessibility"
title: "feat: Enhance Sticky Menu Block with Improved Inspector Controls, UX, and Keyboard Accessibility"

Summary

This PR enhances the Sticky Menu Block with comprehensive improvements to its design, user experience, and accessibility. The changes include a complete refactor of the inspector controls, improved color management for active and hover states, enhanced keyboard navigation, and better handling of non-existent sections.

Linked issues: Closes #771

Changes

Inspector Controls & Color Management

  • Created new inspector.js file to centralize and organize all block inspector controls
  • Added custom color controls for menu button active and hover states, providing better design flexibility
  • Removed unused color settings from block.json to streamline block configuration
  • Integrated custom attributes for customActiveTextColor, customActiveBackgroundColor, customHoverTextColor, and customHoverBackgroundColor

Accessibility & Keyboard Navigation

  • Fixed keyboard navigation (Space and Enter keys) for menu buttons on desktop
    • Moved event listeners from menu item containers directly to buttons
    • Added event.stopPropagation() to prevent browser default scrolling behavior
    • Ensured consistent behavior between click and keyboard interactions
  • Implemented scroll spy prevention during programmatic scrolling
    • Added is_scrolling_programmatically flag to prevent interference when navigating via keyboard
    • Ensures active menu item remains on target section when scrolling to previous sections
    • Timeout-based reset after scroll animation completes
  • Enhanced ARIA attributes and screen reader announcements for better accessibility
  • Improved focus management with proper tabindex handling for keyboard users

Mobile & Section Handling

  • Enhanced mobile section toggling with proper event handling for Enter, Space, and Escape keys
  • Improved section header styling by inheriting colors and styles from sticky menu block
  • Added section visibility logic to hide menu buttons when corresponding sections don't exist in the DOM
  • Prevents empty menu display when all sections are missing

Visual & Structural Improvements

  • Replaced caret icon with inline SVG in render.php for better accessibility and maintainability
  • Updated SCSS to support new color states and improve overall styling structure
  • Applied design system patterns for better visual consistency
  • Fixed CSS class selectors from .lsx-to-menu-item to .lsx-to-sticky-menu-item for consistency

Code Quality & Maintainability

  • Refactored view.js with improved function organization and better documentation
  • Enhanced error handling and edge case management
  • Added comprehensive JSDoc comments throughout JavaScript files
  • Improved code modularity by separating inspector controls into dedicated file
  • Better event listener management to prevent memory leaks and duplicate handlers

Bug Fixes

  • Fixed keyboard navigation not working with Space key on desktop
  • Fixed scroll spy interfering with programmatic navigation to previous sections
  • Fixed mobile section toggle event handling
  • Fixed menu buttons displaying for non-existent sections

Screenshots / Before–After (if UI)

Inspector Controls - Before

  • Basic color controls mixed with other settings
  • Limited customization options for active/hover states

Inspector Controls - After

  • Dedicated color controls panel
  • Separate controls for active text/background colors
  • Separate controls for hover text/background colors
  • Clean, organized interface

Keyboard Navigation - Before

  • Space key would scroll the page instead of navigating
  • Navigating to previous sections would cause active menu item to jump

Keyboard Navigation - After

  • Both Space and Enter keys work consistently
  • Active menu item stays on target section during navigation
  • Smooth scrolling with proper scroll spy prevention

Test Notes

  • Desktop keyboard navigation (Space and Enter keys):
    • Navigate to any section using Space or Enter
    • Navigate to previous sections (scrolling up)
    • Navigate to next sections (scrolling down)
    • Verify active menu item stays on target section
  • Mobile functionality:
    • Section headers toggle correctly with Space/Enter/Escape
    • Collapsible sections expand/collapse properly
    • Touch interactions work as expected
  • Section visibility:
    • Menu buttons hidden when sections don't exist
    • Menu hidden completely when all sections are missing
    • Visible buttons displayed correctly
  • Accessibility:
    • Screen reader announcements work correctly
    • ARIA attributes properly set and updated
    • Focus management works as expected
    • Color contrast meets WCAG standards
  • Inspector controls:
    • Color pickers work for all states (active, hover)
    • Custom colors apply correctly in both editor and frontend
    • Settings persist correctly when saving

Edge cases covered:

  • Sections that don't exist in the DOM
  • All sections missing (entire menu hidden)
  • Rapid keyboard navigation (scroll spy properly disabled)
  • Browser with prefers-reduced-motion enabled
  • Resize between mobile and desktop breakpoints
  • Multiple sticky menus on the same page

Risk & Rollback

  • Risk level: Low
  • Rollback plan: Revert commit c73f7510 if issues arise. No database migrations or breaking changes introduced. All changes are backward compatible with existing block instances.

Checklist (Global DoD / PR)

  • All AC met and demonstrated
  • Tests added/updated (manual testing performed for UI/UX changes)
  • A11y considerations addressed where relevant
    • Enhanced keyboard navigation
    • Improved ARIA attributes
    • Screen reader announcements
    • Focus management
  • Docs/readme/changelog updated (changelog.md updated)
  • Security/perf impact reviewed where relevant
    • Event listener cleanup to prevent memory leaks
    • Efficient scroll spy with IntersectionObserver
    • Minimal performance impact from new features
  • Code/design reviews approved (ready for review)
  • CI green; linked issues closed; release notes prepared (pending CI run)

Additional Notes

This PR builds upon the original sticky menu implementation from #684 and addresses the design system requirements outlined in #771. The changes maintain full backward compatibility while providing enhanced functionality and better user experience.

The refactored code follows WordPress coding standards and accessibility best practices, ensuring the sticky menu block is production-ready with improved maintainability for future enhancements.

Summary by CodeRabbit

  • New Features

    • Block editor adds Inspector color controls for active/hover background and text.
    • Mobile header caret replaced with an inline SVG.
  • Improvements

    • Improved scroll detection and active-section highlighting.
    • Better mobile menu interactions, keyboard support and per-button padding handling.
    • Visual styling refined: hover/active now use background & color; wrapper padding reset.
  • Style / Accessibility

    • Reduced-motion respected.
    • Removed gradient and link colour options from block colour supports.

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

…gement

- Updated block.json to remove unused color settings.
- Refactored index.js to integrate custom color attributes for active and hover states.
- Created a new inspector.js file to manage color controls for menu button states.
- Modified render.php to replace caret icon with SVG for better accessibility.
- Updated view.js to ensure proper functionality of mobile section toggling and event handling.
- Improved JavaScript functions for better accessibility and maintainability.
…o feature/771-sticky-menu-design-ux-improvements
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Nov 20, 2025

Warning

CodeRabbit GitHub Action detected

The repository is using both CodeRabbit Pro and CodeRabbit Open Source (via GitHub Actions), which is not recommended as it may lead to duplicate comments and extra noise. Please remove the CodeRabbit GitHub Action.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key(s) in object: 'commands', 'linked_issues', 'plugin_context'
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Walkthrough

Removes two color support flags from the block manifest; adds a new Inspector with four color attributes; wires CSS custom properties and per-button padding handling; replaces caret placeholder with an inline SVG; renames caret/menu selectors; updates SCSS; and refactors frontend view logic and function signatures.

Changes

Cohort / File(s) Summary
Block Configuration
src/blocks/sticky-menu/block.json
Removed color.gradients and color.link from supports; color.background remains.
Editor entry & Save
src/blocks/sticky-menu/index.js
Import/use new Inspector; Edit now receives clientId; added attributes customActiveBackgroundColor, customActiveTextColor, customHoverBackgroundColor, customHoverTextColor; apply CSS variables (--active-bg-color, --active-text-color, --hover-bg-color, --hover-text-color); extract wrapper padding into wrapperStyle and per-button buttonStyle; strip wrapper className in favor of inline wrapperStyle; Save applies same CSS variables and wrapper/button styles.
Inspector UI
src/blocks/sticky-menu/inspector.js
New file exporting default Inspector component that renders InspectorControls with color settings for active/hover background and text and updates block attributes via setAttributes.
Frontend template
src/blocks/sticky-menu/render.php
Replaced empty caret span with inline SVG inside .lsx-to-sticky-caret span (visual change only).
Styling
src/blocks/sticky-menu/style.scss
Added .wp-block-lsx-tour-operator-sticky-menu wrapper reset; removed hardcoded padding/gap; changed .lsx-to-sticky-menu-button transition to all with prefers-reduced-motion guard; switched hover/active visuals to background/color; renamed .lsx-to-caret.lsx-to-sticky-caret.
Frontend logic / View
src/blocks/sticky-menu/view.js
Widespread function signature formatting and spacing changes; renamed selectors (e.g., .lsx-to-menu-item.lsx-to-sticky-menu-item); updated mobile init/cleanup, scroll-spy offset calc (admin bar, masthead, sticky menu), IntersectionObserver rootMargin/threshold, event handlers and element queries; no intended behavioral change but many structural adjustments.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant BE as Block Editor
    participant I as InspectorControls
    participant B as Sticky Menu Block (Edit/Save)
    participant FE as Frontend JS/CSS

    U->>BE: Open Sticky Menu block
    BE->>I: Mount InspectorControls
    I->>U: Render colour pickers (active/hover text & bg)
    U->>I: Select colours
    I->>B: setAttributes(custom*Color)
    B->>BE: Apply CSS custom properties in editor preview

    Note over B,FE: Save -> Frontend rendering
    B->>FE: Persist attributes and wrapper/button styles
    FE->>FE: Apply wrapperStyle (outer padding stripped)
    FE->>FE: Apply per-button buttonStyle (inline padding)
    FE->>FE: Use CSS variables for hover/active colours
    FE->>FE: Render inline SVG caret (.lsx-to-sticky-caret)
    FE->>U: Display updated Sticky Menu
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Areas needing extra attention:
    • src/blocks/sticky-menu/view.js — scroll-spy offset calculations, IntersectionObserver config, selector renames and event binding correctness.
    • src/blocks/sticky-menu/index.js & src/blocks/sticky-menu/inspector.js — attribute wiring, editor ↔ save CSS variable propagation, clientId usage.
    • src/blocks/sticky-menu/style.scss — visual state changes and reduced-motion handling.

Possibly related PRs

Suggested labels

[Type] Enhancement, comp:block-editor, comp:block-supports, comp:block-json

Suggested reviewers

  • krugazul

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately summarizes the main changes: enhanced inspector controls, improved UX, and keyboard accessibility for the Sticky Menu Block.
Description check ✅ Passed The PR description follows the template with all required sections: Summary with linked issues, comprehensive Changes section, Screenshots/Before-After, detailed Test Notes with checkboxes, Risk & Rollback assessment, and completed Checklist. Minor: CI status pending but documentation is complete.
Linked Issues check ✅ Passed The PR successfully addresses issue #771 requirements: visual design alignment via SCSS updates, button styling for hover/active states, responsive behaviour, design system patterns, custom color controls, accessibility preservation, and cross-browser compatibility. All AC from #771 are met.
Out of Scope Changes check ✅ Passed All changes are directly aligned with #771 objectives: inspector controls redesign, color management, keyboard accessibility enhancements, mobile improvements, SCSS updates for design system alignment, and maintainability refactoring. No out-of-scope changes detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/771-sticky-menu-design-ux-improvements

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

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

@github-actions github-actions bot added status:needs-review Awaiting code review meta:needs-changelog Requires a changelog entry before merge labels Nov 20, 2025
@github-actions
Copy link
Copy Markdown

github-actions bot commented Nov 20, 2025

Image description CodeRabbit


Uplevel your code reviews with CodeRabbit Pro

CodeRabbit Pro

If you like this project, please support us by purchasing the Pro version. The Pro version has advanced context, superior noise reduction and several proprietary improvements compared to the open source version. Moreover, CodeRabbit Pro is free for open source projects.

@github-actions github-actions bot added status:needs-review Awaiting code review and removed status:needs-review Awaiting code review labels Nov 20, 2025
Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Image description CodeRabbit

Commits Files that changed from the base of the PR and between 07a6786 and 62d60f5 commits.
Files selected (5)
  • src/blocks/sticky-menu/index.js (6)
  • src/blocks/sticky-menu/inspector.js (1)
  • src/blocks/sticky-menu/render.php (1)
  • src/blocks/sticky-menu/style.scss (7)
  • src/blocks/sticky-menu/view.js (22)
Files ignored due to filter (2)
  • build/blocks/sticky-menu/block.json
  • src/blocks/sticky-menu/block.json
Files not summarized due to errors (5)
  • src/blocks/sticky-menu/view.js (diff tokens exceeds limit)
  • src/blocks/sticky-menu/index.js (nothing obtained from openai)
  • src/blocks/sticky-menu/style.scss (nothing obtained from openai)
  • src/blocks/sticky-menu/inspector.js (nothing obtained from openai)
  • src/blocks/sticky-menu/render.php (nothing obtained from openai)
Files not reviewed due to errors (5)
  • src/blocks/sticky-menu/render.php (no response)
  • src/blocks/sticky-menu/inspector.js (no response)
  • src/blocks/sticky-menu/style.scss (no response)
  • src/blocks/sticky-menu/index.js (no response)
  • src/blocks/sticky-menu/view.js (no response)
Review comments generated (0)
  • Review: 0
  • LGTM: 0

Tips

Chat with Image description CodeRabbit Bot (@coderabbitai)

  • Reply on review comments left by this bot to ask follow-up questions. A review comment is a comment on a diff or a file.
  • Invite the bot into a review comment chain by tagging @coderabbitai in a reply.

Code suggestions

  • The bot may make code suggestions, but please review them carefully before committing since the line number ranges may be misaligned.
  • You can edit the comment made by the bot and manually tweak the suggestion if it is slightly off.

Pausing incremental reviews

  • Add @coderabbitai: ignore anywhere in the PR description to pause further reviews from the bot.

Copy link
Copy Markdown
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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/blocks/sticky-menu/view.js (1)

428-443: Localize the aria-label string in view.js via wp_localize_script().

The hard-coded English string at line 469 must use WordPress localization. The React component in index.js correctly localizes this string using __('Navigate to %s section', 'tour-operator'), but view.js bypasses translation entirely.

To fix: expose the translation template to view.js via script localization in PHP (the sticky-menu registration file), then use the localized string instead of the hard-coded literal.

🧹 Nitpick comments (3)
src/blocks/sticky-menu/index.js (2)

26-38: Keep the Edit docblock in sync with the function signature.

Edit now accepts { attributes, setAttributes, clientId }, but the docblock only documents attributes and setAttributes. Please add a @param {string} props.clientId entry so the docs match the actual props.


141-147: Avoid javascript:void(0); in the editor anchor href.

For the editor preview button, href="javascript:void(0);" is unnecessary and generally discouraged. Consider mirroring the frontend and using href={#${item.id}} (or at least '#') while relying on your JS to call preventDefault() where appropriate.

src/blocks/sticky-menu/style.scss (1)

1-5: Reconsider !important on the wrapper padding.

The new wrapper rule forces padding: 0 !important;, while your JS already removes padding via wrapperStyle. To stay in line with the “avoid !important” guideline and keep specificity manageable, it would be better to drop !important here unless you have a concrete conflict that cannot be resolved otherwise.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 07a6786 and 62d60f5.

⛔ Files ignored due to path filters (7)
  • build/blocks/sticky-menu/block.json is excluded by !build/**
  • build/blocks/sticky-menu/index.asset.php is excluded by !build/**
  • build/blocks/sticky-menu/index.js is excluded by !build/**
  • build/blocks/sticky-menu/style-index-rtl.css is excluded by !build/**
  • build/blocks/sticky-menu/style-index.css is excluded by !build/**
  • build/blocks/sticky-menu/view.asset.php is excluded by !build/**
  • build/blocks/sticky-menu/view.js is excluded by !build/**
📒 Files selected for processing (6)
  • src/blocks/sticky-menu/block.json (1 hunks)
  • src/blocks/sticky-menu/index.js (6 hunks)
  • src/blocks/sticky-menu/inspector.js (1 hunks)
  • src/blocks/sticky-menu/render.php (1 hunks)
  • src/blocks/sticky-menu/style.scss (6 hunks)
  • src/blocks/sticky-menu/view.js (22 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,ts,tsx,jsx}

⚙️ CodeRabbit configuration file

**/*.{js,ts,tsx,jsx}: Perform a detailed review of the provided code with following key aspects in mind:

  • Review the code to ensure it is well-structured and adheres to best practices.
  • Verify compliance with WordPress coding standards and @wordpress/eslint-plugin rules.
  • Ensure the code is well-documented with proper JSDoc comments.
  • Check for security vulnerabilities and confirm the code is secure.
  • Optimize the code for performance, removing any unnecessary elements.
  • Validate JSDoc comments for accuracy, currency, and adherence to WordPress coding standards.
  • Ensure each line comment concludes with a period.
  • Confirm every JSDoc comment includes a @SInCE tag indicating the next version of the plugin to include the code.
  • Guarantee compatibility with the latest version of WordPress, avoiding deprecated functions or features.
  • Follow WordPress JavaScript coding standards and use WordPress script localization.
  • Use WordPress script dependencies and enqueue properly.
  • Ensure React/JSX best practices for blocks and modern JavaScript/TypeScript patterns.
  • Implement proper error handling and loading states.
  • Use WordPress components and design system where applicable.
  • For Tour Operator: Focus on tour booking interfaces, search functionality, and tour display components.

Files:

  • src/blocks/sticky-menu/inspector.js
  • src/blocks/sticky-menu/index.js
  • src/blocks/sticky-menu/view.js
src/blocks/**/*.{js,jsx,ts,tsx}

⚙️ CodeRabbit configuration file

src/blocks/**/*.{js,jsx,ts,tsx}: - Follow WordPress JavaScript coding standards and @wordpress/scripts configuration.

  • Use WordPress components from @wordpress/components and design system.
  • Implement proper React/JSX patterns for WordPress blocks.
  • Ensure proper WordPress script dependencies and localization.
  • Use WordPress data store patterns with @wordpress/data.
  • Implement proper error boundaries and loading states.
  • Follow modern JavaScript/TypeScript patterns with proper typing.
  • Ensure accessibility in interactive block components.
  • Use WordPress block editor APIs correctly (useBlockProps, InspectorControls, etc.).
  • Implement proper block validation and save/edit functionality.

Files:

  • src/blocks/sticky-menu/inspector.js
  • src/blocks/sticky-menu/index.js
  • src/blocks/sticky-menu/view.js
**/*.{html,php}

⚙️ CodeRabbit configuration file

**/*.{html,php}: Perform a detailed review of the provided code with following key aspects in mind:

  • Review the HTML and PHP code to ensure it is well-structured and adheres to best practices.
  • Ensure the code follows WordPress coding standards (WPCS) and is well-documented.
  • Confirm the code is secure and free from vulnerabilities using proper sanitization and validation.
  • Escape all outputs using esc_html, esc_attr, wp_kses_post appropriately.
  • Use WordPress functions instead of native PHP where available.
  • Optimize the code for performance, removing any unnecessary elements.
  • Validate comments for accuracy, currency, and adherence to WordPress coding standards.
  • Ensure each line comment concludes with a period.
  • Add proper DocBlocks with @param, @return, @SInCE tags.
  • Use meaningful variable and function names with tour_operator_ prefix.
  • Follow WordPress naming conventions (snake_case for functions/variables).
  • Verify code compatibility with the latest version of WordPress, avoiding deprecated functions.
  • Ensure proper template hierarchy usage and WordPress block theme patterns.
  • Validate HTML semantics and accessibility (WCAG 2.2 AA compliance).

Files:

  • src/blocks/sticky-menu/render.php
**/*.{css,scss}

⚙️ CodeRabbit configuration file

**/*.{css,scss}: Perform a detailed review of the provided code with following key aspects in mind:

  • Review the SCSS code to ensure it is well-structured and adheres to best practices.
  • Convert dimensions greater than or equal to 3px to rem units using the to_rem function.
  • Utilize variables for sizes and colors defined in src/content-helper/common/css/variables.scss instead of hardcoding values.
  • Follow WordPress CSS coding standards and use semantic class naming with tour-operator- prefix.
  • Ensure responsive design for all tour displays and booking forms.
  • Check for accessibility compliance (WCAG 2.2 AA).
  • Style complex tour layouts, booking forms, and destination galleries.
  • Use CSS custom properties and modern CSS features.
  • Ensure proper mobile-first responsive design for tourism content.

Files:

  • src/blocks/sticky-menu/style.scss
src/**/*.{css,scss}

⚙️ CodeRabbit configuration file

src/**/*.{css,scss}: - Follow WordPress CSS coding standards and BEM methodology.

  • Use semantic class naming with tour-operator- prefix consistently.
  • Ensure responsive design for all tour displays and booking interfaces.
  • Check for accessibility compliance (WCAG 2.2 AA) including color contrast.
  • Style complex tour layouts, booking forms, and destination galleries effectively.
  • Use CSS custom properties and modern CSS features (Grid, Flexbox).
  • Implement proper mobile-first responsive design approach.
  • Use theme.json compatible styling where applicable.
  • Avoid !important declarations and maintain specificity hierarchy.
  • Ensure RTL (right-to-left) language support.

Files:

  • src/blocks/sticky-menu/style.scss
🧬 Code graph analysis (3)
src/blocks/sticky-menu/inspector.js (1)
src/blocks/videos/index.js (1)
  • InspectorControls (64-64)
src/blocks/sticky-menu/index.js (2)
src/blocks/sticky-menu/sticky-menu-editor-extension.js (1)
  • attributes (274-274)
src/blocks/sticky-menu/inspector.js (1)
  • Inspector (31-96)
src/blocks/sticky-menu/view.js (1)
src/js/custom.js (1)
  • lsx_to (8-8)
🪛 Biome (2.1.2)
src/blocks/sticky-menu/view.js

[error] 224-224: Other switch clauses can erroneously access this declaration.
Wrap the declaration in a block to restrict its access to the switch clause.

The declaration is defined in this switch clause:

Safe fix: Wrap the declaration in a block.

(lint/correctness/noSwitchDeclarations)

⏰ 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). (2)
  • GitHub Check: review
  • GitHub Check: Summary
🔇 Additional comments (12)
src/blocks/sticky-menu/render.php (1)

40-50: Inline SVG caret is correctly integrated and accessible.

The new .lsx-to-sticky-caret SVG is static, uses aria-hidden="true" and does not affect the existing accessible name from the button text, so this change looks sound from both security and a11y perspectives.

src/blocks/sticky-menu/block.json (1)

17-19: Colour support narrowing is consistent with custom Inspector-based colours.

Limiting supports.color to background here is consistent with handling active/hover colours via explicit attributes in the Inspector, and should avoid conflicting UI in the core colour panel.

src/blocks/sticky-menu/inspector.js (1)

31-95: Inspector colour wiring looks correct and matches the new attributes.

Destructuring the four custom colour attributes and feeding them into ColorGradientSettingsDropdown, with panelId={clientId} and useMultipleOriginColorsAndGradients() spread in, is consistent with WordPress patterns and should behave as expected. Any further DRYing of the repeated setAttributes handlers would be purely cosmetic.

src/blocks/sticky-menu/index.js (1)

38-55: CSS variable and padding refactor for buttons is sound.

Using useBlockProps to define the four CSS custom properties for active/hover colours, then stripping padding from the wrapper into a dedicated buttonStyle applied per button (with wrapperStyle passed back into the outer <div>) is a clean way to keep spacing on the interactive target while preserving other block styles and theme.json-driven output. This looks correct in both Edit and Save.

Also applies to: 58-74, 188-205, 208-224, 226-238

src/blocks/sticky-menu/style.scss (2)

48-63: Button transition and reduced‑motion handling look good.

Expanding the button transition to all 0.2s and guarding it with a prefers-reduced-motion media query is a sensible balance between design and accessibility.


117-118: Caret selector rename is consistent across mobile wrappers and headers.

Updating the rotation rules to .lsx-to-sticky-caret in both .lsx-to-sticky-menu-section-wrapper and .lsx-to-sticky-menu-section, plus the transition on button.lsx-to-section-header .lsx-to-sticky-caret with a reduced‑motion override, keeps the visual behaviour aligned with the new markup from render.php.

Also applies to: 125-127, 153-154, 191-198

src/blocks/sticky-menu/view.js (6)

50-97: Scroll handling, offsets, and focus management are robust.

scroll_to_section correctly accounts for admin bar, fixed masthead, and navigation offsets, respects prefers-reduced-motion, and then updates the sticky-menu state, announces the change, and briefly focuses the target section with a temporary tabindex. This is a solid pattern for keyboard and screen-reader users.


108-143: Mobile section toggling handles both new wrappers and legacy sections.

Normalising the target to a .lsx-to-sticky-menu-section-wrapper when present, falling back to [data-sticky-menu-section] for legacy, and synchronising aria-expanded and the collapsed class gives predictable behaviour across both markup variants.


242-256: Scroll‑spy and IntersectionObserver logic is coherent and desktop‑only.

update_active_menu_item, get_active_section_on_scroll, and initialize_scroll_spy work together to keep the active state in sync with scroll position, while correctly short‑circuiting on mobile via is_mobile. The IntersectionObserver setup with a dynamic rootMargin based on header offsets, and the initial “first visible section” check, should yield stable highlighting across various header heights.

Also applies to: 267-320, 330-418


503-532: Mobile section initialisation and cleanup are aligned with the new wrapper.

initialize_mobile_sections now consistently applies collapsed/aria-expanded="false" to the wrapper (or legacy section) and delegates header behaviour to add_mobile_header, while cleanup_mobile_sections reverses those changes when switching back to desktop. This keeps mobile and desktop states in sync without removing the PHP‑rendered headers.

Also applies to: 542-562


572-585: Sticky‑menu cleanup covers the key runtime resources.

Removing the scroll listener, disconnecting the IntersectionObserver, and resetting the basic sticky‑menu state on beforeunload is sufficient to avoid leaks in the typical WordPress page lifecycle.


631-662: Initialisation logic correctly hides invalid items and avoids empty menus.

initialize_sticky_menu now:

  • Bails out entirely if there are no [data-sticky-menu-section] elements (keeping opacity at 0 so the block stays hidden).
  • Iterates the .lsx-to-sticky-menu-button elements, showing only those with a matching DOM section and hiding the rest.
  • Sets the sticky menu’s opacity to 1 only when at least one section exists, then defers initialize_scroll_spy() slightly to wait for the DOM.

This matches the intent to hide the menu when sections are missing and reduce scroll‑spy race conditions.

Also applies to: 672-686

@tibiii tibiii self-assigned this Nov 20, 2025
@tibiii tibiii added this to the v2.1.0 milestone Nov 20, 2025
@github-project-automation github-project-automation bot moved this to Needs Triage in Tour Operator Nov 20, 2025
@github-actions github-actions bot added status:needs-review Awaiting code review and removed status:needs-review Awaiting code review labels Nov 20, 2025
Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Image description CodeRabbit

Commits Files that changed from the base of the PR and between 62d60f5 and 9732a81 commits.
Files selected (1)
  • src/blocks/sticky-menu/view.js (22)
Files not summarized due to errors (1)
  • src/blocks/sticky-menu/view.js (diff tokens exceeds limit)
Files not reviewed due to errors (1)
  • src/blocks/sticky-menu/view.js (no response)
Review comments generated (0)
  • Review: 0
  • LGTM: 0

Tips

Chat with Image description CodeRabbit Bot (@coderabbitai)

  • Reply on review comments left by this bot to ask follow-up questions. A review comment is a comment on a diff or a file.
  • Invite the bot into a review comment chain by tagging @coderabbitai in a reply.

Code suggestions

  • The bot may make code suggestions, but please review them carefully before committing since the line number ranges may be misaligned.
  • You can edit the comment made by the bot and manually tweak the suggestion if it is slightly off.

Pausing incremental reviews

  • Add @coderabbitai: ignore anywhere in the PR description to pause further reviews from the bot.

@github-actions github-actions bot added status:needs-review Awaiting code review and removed status:needs-review Awaiting code review labels Nov 20, 2025
@github-actions github-actions bot added status:needs-review Awaiting code review and removed status:needs-review Awaiting code review labels Nov 20, 2025
Copy link
Copy Markdown
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 (6)
src/blocks/sticky-menu/view.js (6)

155-235: Tidy up unused context parameter and comment punctuation in add_mobile_header.

  • The context argument is constructed in initialize_mobile_sections but not used in add_mobile_header. Either wire it into the header (e.g. for labels/analytics) or remove it to avoid dead parameters.
  • The inline comment on Line 224 (// Always collapse on Escape if expanded) is missing a trailing full stop, which is required by the stated commenting guideline.

Example diff for the unused parameter (if you opt to remove it):

-lsx_to.add_mobile_header = function (section, context) {
+lsx_to.add_mobile_header = function (section) {
@@
-        const context = {
-            section_id: section.id,
-            section_title: section_title,
-            is_collapsed: true
-        };
+        // Context no longer needed here; section metadata can be read directly when required.

And for the comment punctuation:

-                    // Always collapse on Escape if expanded
+                    // Always collapse on Escape if expanded.

334-422: Guard IntersectionObserver usage and consider mobile/resize behaviour.

The IntersectionObserver‑based scroll spy is a good performance optimisation, but there are two edge cases worth tightening up:

  • Feature detection: If this script runs in an environment without IntersectionObserver, new IntersectionObserver(...) will throw. Even if you only target modern browsers, a defensive guard is low‑cost.

  • Resize from desktop to mobile: When the page starts on desktop, the observer remains active even after check_mobile switches to mobile mode. This means the observer callback can still update current_section and active menu state on mobile, contrary to the doc comment that scroll spy is “desktop only”.

A minimal hardening could look like:

-    // Initialize Intersection Observer for scroll spy (desktop only)
-    if (!lsx_to.sticky_menu.is_mobile) {
+    // Initialize Intersection Observer for scroll spy (desktop only, where supported).
+    if (!lsx_to.sticky_menu.is_mobile && typeof window.IntersectionObserver !== 'undefined') {
@@
-            lsx_to.sticky_menu.observer = new IntersectionObserver(function (entries) {
+            lsx_to.sticky_menu.observer = new IntersectionObserver(function (entries) {
+                if (lsx_to.sticky_menu.is_mobile) {
+                    return;
+                }
@@
             }, observer_options);

If you need to support starting on mobile then resizing up, you may also want to (re)create or reconnect the observer inside check_mobile when transitioning from mobile to desktop.


457-497: Attach handlers to the actual button element and improve ARIA/i18n for menu items.

The current implementation binds click/keydown handlers to the .lsx-to-sticky-menu-item container, while the interactive control is .lsx-to-sticky-menu-button. This works via event bubbling but is less precise for accessibility and future refactors. Also, the ARIA label string is hard‑coded in English.

Consider:

  • Targeting the button where present to keep semantics aligned and avoid surprises if container markup changes.
  • Adding event.stopPropagation() in the handlers if the menu ever sits inside another clickable container, to avoid double navigation.
  • Making the ARIA label translatable, using your existing localisation mechanism rather than a hard‑coded English string.

Illustrative refactor:

-    menu_items.forEach(function (item) {
-        // Enhance button accessibility
-        const button = item.querySelector('.lsx-to-sticky-menu-button');
-        if (button) {
-            const section_id = item.getAttribute('data-section-id');
-            const section_title = button.textContent.trim();
-
-            // Add descriptive aria-label
-            button.setAttribute('aria-label', `Navigate to ${section_title} section`);
-            // Add role and aria-current for active state
-            button.setAttribute('role', 'tab');
-            button.setAttribute('aria-current', 'false');
-        }
-
-        item.addEventListener('click', function (event) {
+    menu_items.forEach(function (item) {
+        const button = item.querySelector('.lsx-to-sticky-menu-button') || item;
+        const section_id = item.getAttribute('data-section-id');
+        const section_title = button.textContent.trim();
+
+        // Add descriptive aria-label (ideally from a localised string).
+        button.setAttribute('aria-label', `Navigate to ${section_title} section`);
+        button.setAttribute('role', 'tab');
+        button.setAttribute('aria-current', 'false');
+
+        button.addEventListener('click', function (event) {
             event.preventDefault();
-            const section_id = this.getAttribute('data-section-id');
-            if (section_id) {
-                lsx_to.scroll_to_section(section_id);
-            }
+            event.stopPropagation();
+            if (section_id) {
+                lsx_to.scroll_to_section(section_id);
+            }
         });
@@
-        item.addEventListener('keydown', function (event) {
-            const section_id = this.getAttribute('data-section-id');
+        button.addEventListener('keydown', function (event) {
             if (section_id && (event.key === 'Enter' || event.key === ' ')) {
                 event.preventDefault();
+                event.stopPropagation();
                 lsx_to.scroll_to_section(section_id);
             }
         });

576-589: Optional: also clean up the resize listener if re‑initialisation on the same page is expected.

cleanup_sticky_menu removes the scroll listener and disconnects the observer, which covers the main leak risks. If this block can be initialised/cleaned up multiple times on a long‑lived page (AJAX navigation, partial reloads), you may also want to remove the resize listener that initialize_scroll_spy adds, by storing the check_mobile reference on lsx_to.sticky_menu and calling window.removeEventListener('resize', ...) here.


600-625: Localise the screen‑reader announcement string.

The announcement message (Navigated to ${section_title} section) is currently hard‑coded in English. To align with WordPress localisation practices, consider sourcing this base phrase from your translation mechanism so that ARIA messages are available in all supported languages.


676-690: General: DOM ready/unload wiring is fine; consider normalising inline comment punctuation.

The DOMContentLoaded hook to initialize_sticky_menu and the beforeunload hook to cleanup_sticky_menu are straightforward and match the lifecycle described in the docblocks.

One minor style point: several single‑line comments in this file (for example on Lines 54, 64, 73, 80, 88, 91, 111, 118, 128, 131, 163, 169, 188, 194, 199, 207, 213, 224, 372, 399, 404, 420, 533, 556, 577, 586) do not end with a full stop, which your guidelines call for. It might be worth normalising these in a follow‑up pass for consistency.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 62d60f5 and 9732a81.

📒 Files selected for processing (1)
  • src/blocks/sticky-menu/view.js (22 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{js,ts,tsx,jsx}

⚙️ CodeRabbit configuration file

**/*.{js,ts,tsx,jsx}: Perform a detailed review of the provided code with following key aspects in mind:

  • Review the code to ensure it is well-structured and adheres to best practices.
  • Verify compliance with WordPress coding standards and @wordpress/eslint-plugin rules.
  • Ensure the code is well-documented with proper JSDoc comments.
  • Check for security vulnerabilities and confirm the code is secure.
  • Optimize the code for performance, removing any unnecessary elements.
  • Validate JSDoc comments for accuracy, currency, and adherence to WordPress coding standards.
  • Ensure each line comment concludes with a period.
  • Confirm every JSDoc comment includes a @SInCE tag indicating the next version of the plugin to include the code.
  • Guarantee compatibility with the latest version of WordPress, avoiding deprecated functions or features.
  • Follow WordPress JavaScript coding standards and use WordPress script localization.
  • Use WordPress script dependencies and enqueue properly.
  • Ensure React/JSX best practices for blocks and modern JavaScript/TypeScript patterns.
  • Implement proper error handling and loading states.
  • Use WordPress components and design system where applicable.
  • For Tour Operator: Focus on tour booking interfaces, search functionality, and tour display components.

Files:

  • src/blocks/sticky-menu/view.js
src/blocks/**/*.{js,jsx,ts,tsx}

⚙️ CodeRabbit configuration file

src/blocks/**/*.{js,jsx,ts,tsx}: - Follow WordPress JavaScript coding standards and @wordpress/scripts configuration.

  • Use WordPress components from @wordpress/components and design system.
  • Implement proper React/JSX patterns for WordPress blocks.
  • Ensure proper WordPress script dependencies and localization.
  • Use WordPress data store patterns with @wordpress/data.
  • Implement proper error boundaries and loading states.
  • Follow modern JavaScript/TypeScript patterns with proper typing.
  • Ensure accessibility in interactive block components.
  • Use WordPress block editor APIs correctly (useBlockProps, InspectorControls, etc.).
  • Implement proper block validation and save/edit functionality.

Files:

  • src/blocks/sticky-menu/view.js
🧬 Code graph analysis (1)
src/blocks/sticky-menu/view.js (1)
src/js/custom.js (1)
  • lsx_to (8-8)
⏰ 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). (2)
  • GitHub Check: review
  • GitHub Check: Summary
🔇 Additional comments (6)
src/blocks/sticky-menu/view.js (6)

50-97: scroll_to_section behaviour is robust and accessible.

Offset calculation, reduced‑motion handling, and focus management on the target section are all sensible and align with accessibility goals. No changes needed here.


108-143: toggle_mobile_section wrapper resolution and ARIA updates look correct.

The wrapper detection (new vs legacy structure), aria-expanded toggling, and collapsed class handling are coherent and should behave well across both markup variants. No functional issues spotted.


246-324: Active‑section tracking and scroll spy logic are consistent.

update_active_menu_item, get_active_section_on_scroll, and handle_scroll_spy integrate cleanly: scrolling updates current_section and the active button, with a reasonable offset model and a safe fallback to the first section. No functional or accessibility regressions evident here.


432-447: update_menu_items correctly mirrors DOM sections into internal state.

The mapping from [data-sticky-menu-section] elements into { id, title } objects with an empty‑state guard is straightforward and matches the documented behaviour.


507-566: Mobile section initialisation and cleanup are consistent with wrapper model.

initialize_mobile_sections and cleanup_mobile_sections correctly handle both the new wrapper structure and legacy sections, apply/remove the collapsed class, and manage aria-expanded consistently on the wrapper and header. Apart from the (currently unused) context argument already noted in add_mobile_header, there are no functional concerns here.


635-666: Initialisation logic for missing sections/menu items behaves sensibly.

Guarding on the presence of both the sticky menu block and [data-sticky-menu-section] sections, hiding per‑button controls when their corresponding section is missing, and only then revealing the menu via opacity = 1 matches the described UX goals and avoids showing a sticky menu when there are no sections. The delayed call to initialize_scroll_spy is reasonable for allowing the page layout to settle.

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Image description CodeRabbit

Commits Files that changed from the base of the PR and between 9732a81 and d130f06 commits.
Files selected (2)
  • src/blocks/sticky-menu/index.js (6)
  • src/blocks/sticky-menu/style.scss (7)
Files not summarized due to errors (2)
  • src/blocks/sticky-menu/style.scss (nothing obtained from openai)
  • src/blocks/sticky-menu/index.js (nothing obtained from openai)
Files not reviewed due to errors (2)
  • src/blocks/sticky-menu/style.scss (no response)
  • src/blocks/sticky-menu/index.js (no response)
Review comments generated (0)
  • Review: 0
  • LGTM: 0

Tips

Chat with Image description CodeRabbit Bot (@coderabbitai)

  • Reply on review comments left by this bot to ask follow-up questions. A review comment is a comment on a diff or a file.
  • Invite the bot into a review comment chain by tagging @coderabbitai in a reply.

Code suggestions

  • The bot may make code suggestions, but please review them carefully before committing since the line number ranges may be misaligned.
  • You can edit the comment made by the bot and manually tweak the suggestion if it is slightly off.

Pausing incremental reviews

  • Add @coderabbitai: ignore anywhere in the PR description to pause further reviews from the bot.

@github-actions github-actions bot added status:needs-review Awaiting code review and removed status:needs-review Awaiting code review labels Nov 20, 2025
@github-actions github-actions bot added status:needs-review Awaiting code review and removed status:needs-review Awaiting code review labels Nov 20, 2025
Copy link
Copy Markdown
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: 1

🧹 Nitpick comments (4)
src/blocks/sticky-menu/style.scss (4)

66-67: Use colour variables instead of hardcoded rgba fallbacks.

Lines 66–67 and 71–72 use hardcoded rgba(0, 0, 0, 0.1) and #fff fallbacks instead of leveraging the colour variables defined in src/content-helper/common/css/variables.scss. Define semantic colour variables (e.g., --hover-overlay-color, --button-text-light) and use them consistently throughout.

 .lsx-to-sticky-menu-button:hover {
-	background-color: var(--hover-bg-color, rgba(0, 0, 0, 0.1));
-	color: var(--hover-text-color, inherit);
+	background-color: var(--hover-bg-color, var(--hover-overlay-color, rgba(0, 0, 0, 0.1)));
+	color: var(--hover-text-color, inherit);
 }

 .lsx-to-sticky-menu-button.active {
-	background-color: var(--active-bg-color, currentColor);
-	color: var(--active-text-color, var(--wp--preset--color--background, #fff));
+	background-color: var(--active-bg-color, var(--active-overlay-color, currentColor));
+	color: var(--active-text-color, var(--wp--preset--color--background));
 }

Also applies to: 71-72


116-116: Use colour variables for border colours instead of hardcoded values.

Lines 116, 141, and 184 use hardcoded rgba(0, 0, 0, 0.1) for borders. Define a semantic border-colour variable (e.g., --border-subtle-color) in variables.scss and reference it throughout to maintain consistency and enable theme-wide adjustments.

 .lsx-to-sticky-menu-section-wrapper {
-	border-bottom: 1px solid rgba(0, 0, 0, 0.1);
+	border-bottom: 1px solid var(--border-subtle-color, rgba(0, 0, 0, 0.1));

Also applies to: 141-141, 184-184


176-176: Remove duplicate padding declaration.

The padding: 1rem; property is declared twice in the button.lsx-to-section-header rule (lines 176 and 185). Keep only one declaration to improve code clarity and maintainability.

 button.lsx-to-section-header {
 	background: none;
 	border: none;
 	cursor: pointer;
 	font-family: inherit;
 	font-size: inherit;
 	color: inherit;
 	text-decoration: none;
 	transition: all 0.2s ease;
 	padding: 1rem;
 	border-radius: 0;
 	width: 100%;
 	display: none;
 	align-items: center;
 	justify-content: space-between;
 	text-align: left;
 	font-weight: 600;
 	border-bottom: 1px solid rgba(0, 0, 0, 0.1);
-	padding: 1rem;

Also applies to: 185-185


114-114: Consider using em units for media query breakpoints for consistency.

Line 114 uses max-width: 767px for the mobile breakpoint. For improved accessibility and consistency with modern practices, consider using em units (e.g., 48em ≈ 768px when base font size is 16px). This ensures the breakpoint scales with user-defined font sizes.

-@media (max-width: 767px) {
+@media (max-width: 48em) {
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d130f06 and f3255eb.

⛔ Files ignored due to path filters (2)
  • build/blocks/sticky-menu/style-index-rtl.css is excluded by !build/**
  • build/blocks/sticky-menu/style-index.css is excluded by !build/**
📒 Files selected for processing (1)
  • src/blocks/sticky-menu/style.scss (6 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{css,scss}

⚙️ CodeRabbit configuration file

**/*.{css,scss}: Perform a detailed review of the provided code with following key aspects in mind:

  • Review the SCSS code to ensure it is well-structured and adheres to best practices.
  • Convert dimensions greater than or equal to 3px to rem units using the to_rem function.
  • Utilize variables for sizes and colors defined in src/content-helper/common/css/variables.scss instead of hardcoding values.
  • Follow WordPress CSS coding standards and use semantic class naming with tour-operator- prefix.
  • Ensure responsive design for all tour displays and booking forms.
  • Check for accessibility compliance (WCAG 2.2 AA).
  • Style complex tour layouts, booking forms, and destination galleries.
  • Use CSS custom properties and modern CSS features.
  • Ensure proper mobile-first responsive design for tourism content.

Files:

  • src/blocks/sticky-menu/style.scss
src/**/*.{css,scss}

⚙️ CodeRabbit configuration file

src/**/*.{css,scss}: - Follow WordPress CSS coding standards and BEM methodology.

  • Use semantic class naming with tour-operator- prefix consistently.
  • Ensure responsive design for all tour displays and booking interfaces.
  • Check for accessibility compliance (WCAG 2.2 AA) including color contrast.
  • Style complex tour layouts, booking forms, and destination galleries effectively.
  • Use CSS custom properties and modern CSS features (Grid, Flexbox).
  • Implement proper mobile-first responsive design approach.
  • Use theme.json compatible styling where applicable.
  • Avoid !important declarations and maintain specificity hierarchy.
  • Ensure RTL (right-to-left) language support.

Files:

  • src/blocks/sticky-menu/style.scss
⏰ 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). (2)
  • GitHub Check: review
  • GitHub Check: Summary
🔇 Additional comments (2)
src/blocks/sticky-menu/style.scss (2)

71-72: Verify colour contrast for active button state fallback.

The active state fallback (line 72) uses var(--wp--preset--color--background, #fff) for text colour on a currentColor background. If the background inherits a light colour, this could violate WCAG 2.2 AA colour contrast requirements (4.5:1 for normal text). Ensure the CSS variables passed at runtime guarantee sufficient contrast, or provide a more accessible fallback.


56-56: Approve transition and reduced-motion handling.

The transition from opacity-only to all 0.2s ease provides better visual feedback, and the @media (prefers-reduced-motion: reduce) guard ensures accessibility for users who prefer reduced motion. Well done on this improvement.

Also applies to: 60-62

Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Image description CodeRabbit

Commits Files that changed from the base of the PR and between d130f06 and f3255eb commits.
Files selected (1)
  • src/blocks/sticky-menu/style.scss (7)
Files not summarized due to errors (1)
  • src/blocks/sticky-menu/style.scss (nothing obtained from openai)
Files not reviewed due to errors (1)
  • src/blocks/sticky-menu/style.scss (no response)
Review comments generated (0)
  • Review: 0
  • LGTM: 0

Tips

Chat with Image description CodeRabbit Bot (@coderabbitai)

  • Reply on review comments left by this bot to ask follow-up questions. A review comment is a comment on a diff or a file.
  • Invite the bot into a review comment chain by tagging @coderabbitai in a reply.

Code suggestions

  • The bot may make code suggestions, but please review them carefully before committing since the line number ranges may be misaligned.
  • You can edit the comment made by the bot and manually tweak the suggestion if it is slightly off.

Pausing incremental reviews

  • Add @coderabbitai: ignore anywhere in the PR description to pause further reviews from the bot.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR enhances the Sticky Menu block with improved inspector controls, custom color management for active/hover states, better keyboard accessibility, and refined mobile interactions. The changes include creating a dedicated inspector component, restructuring CSS to use custom properties for colors, updating JavaScript for cleaner code formatting, and replacing the caret icon with an inline SVG.

Key Changes:

  • New inspector controls for customizable active and hover colors (background and text)
  • Removed gradient and link color support from block.json, keeping only background color
  • Refactored JavaScript with consistent formatting (function expressions, spacing)
  • Enhanced mobile header styling by inheriting padding from menu buttons
  • Updated caret icon from CSS-based to inline SVG

Reviewed Changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 17 comments.

Show a summary per file
File Description
src/blocks/sticky-menu/view.js Reformatted code with consistent function expression syntax and spacing; fixed CSS selector from .lsx-to-menu-item to .lsx-to-sticky-menu-item; added default case to switch statement
src/blocks/sticky-menu/style.scss Added wrapper padding reset; removed gap from menu list; updated button hover/active styles to use CSS custom properties; replaced caret class name
src/blocks/sticky-menu/render.php Replaced CSS-based caret with inline SVG icon for better maintainability and accessibility
src/blocks/sticky-menu/inspector.js New file providing color controls for active and hover states (background and text colors)
src/blocks/sticky-menu/index.js Integrated Inspector component; added custom color attributes; implemented padding extraction logic to apply wrapper padding to buttons instead
src/blocks/sticky-menu/block.json Removed gradients and link color support, keeping only background color
build/blocks/sticky-menu/* Compiled/minified versions of the source changes
Comments suppressed due to low confidence (6)

src/blocks/sticky-menu/view.js:495

  • The PR description mentions implementing event.stopPropagation() to prevent browser default scrolling behavior for keyboard navigation, and adding an is_scrolling_programmatically flag to prevent scroll spy interference. However, these features are not present in the updated view.js file. The keyboard event handlers at lines 489-495 only call event.preventDefault(), but don't include event.stopPropagation() or any programmatic scrolling flag management. This means the described keyboard navigation fixes may not be fully implemented.
        item.addEventListener('keydown', function (event) {
            const section_id = this.getAttribute('data-section-id');
            if (section_id && (event.key === 'Enter' || event.key === ' ')) {
                event.preventDefault();
                lsx_to.scroll_to_section(section_id);
            }
        });

src/blocks/sticky-menu/view.js:495

  • Event listeners are being added to the .lsx-to-sticky-menu-item container (lines 480-495), but according to the PR description, these should be attached directly to the .lsx-to-sticky-menu-button elements for proper keyboard navigation. The current implementation attaches click and keydown handlers to the parent <li> element rather than the <a> button element, which could cause issues with keyboard focus and event handling. The button is already retrieved at line 467 for accessibility enhancements - the event listeners should be attached to it instead.
        item.addEventListener('click', function (event) {
            event.preventDefault();
            const section_id = this.getAttribute('data-section-id');
            if (section_id) {
                lsx_to.scroll_to_section(section_id);
            }
        });

        // Add keyboard support for menu items
        item.addEventListener('keydown', function (event) {
            const section_id = this.getAttribute('data-section-id');
            if (section_id && (event.key === 'Enter' || event.key === ' ')) {
                event.preventDefault();
                lsx_to.scroll_to_section(section_id);
            }
        });

src/blocks/sticky-menu/index.js:41

  • Unused variable backgroundColor.
    backgroundColor,

src/blocks/sticky-menu/index.js:42

  • Unused variable textColor.
    textColor,

src/blocks/sticky-menu/index.js:191

  • Unused variable backgroundColor.
    backgroundColor,

src/blocks/sticky-menu/index.js:192

  • Unused variable textColor.
    textColor,

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Tibi Buzdugan <buzdugan.tiberiu@gmail.com>
@github-actions github-actions bot added status:needs-review Awaiting code review and removed status:needs-review Awaiting code review labels Nov 20, 2025
@tibiii tibiii requested a review from krugazul November 20, 2025 19:35
Copy link
Copy Markdown

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Image description CodeRabbit

Commits Files that changed from the base of the PR and between f3255eb and 763f4f5 commits.
Files selected (1)
  • src/blocks/sticky-menu/view.js (22)
Files not summarized due to errors (1)
  • src/blocks/sticky-menu/view.js (diff tokens exceeds limit)
Files not reviewed due to errors (1)
  • src/blocks/sticky-menu/view.js (no response)
Review comments generated (0)
  • Review: 0
  • LGTM: 0

Tips

Chat with Image description CodeRabbit Bot (@coderabbitai)

  • Reply on review comments left by this bot to ask follow-up questions. A review comment is a comment on a diff or a file.
  • Invite the bot into a review comment chain by tagging @coderabbitai in a reply.

Code suggestions

  • The bot may make code suggestions, but please review them carefully before committing since the line number ranges may be misaligned.
  • You can edit the comment made by the bot and manually tweak the suggestion if it is slightly off.

Pausing incremental reviews

  • Add @coderabbitai: ignore anywhere in the PR description to pause further reviews from the bot.

@tibiii tibiii moved this from Needs Triage to 🔎 In Review in Tour Operator Nov 20, 2025
Copy link
Copy Markdown
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/blocks/sticky-menu/view.js (1)

635-666: Initialisation is single‑instance; multi‑sticky‑menu pages may not behave independently.

initialize_sticky_menu operates on document.querySelector('.wp-block-lsx-tour-operator-sticky-menu'), so only the first sticky‑menu block is considered when:

  • Toggling visibility of .lsx-to-sticky-menu-button elements based on matching sections.
  • Changing the block’s opacity once ready.

Combined with other global queries (for example in update_active_menu_item and add_mobile_header), multiple sticky‑menu instances on the same page will share state and styles rather than behaving independently.

If supporting more than one sticky menu per page is a requirement (as suggested in the PR objectives), consider:

  • Iterating document.querySelectorAll('.wp-block-lsx-tour-operator-sticky-menu').
  • Scoping menu‑item and section queries to each block.
  • Tracking per‑instance state in lsx_to.sticky_menu keyed by block or ID.

This would avoid cross‑talk between instances.

♻️ Duplicate comments (1)
src/blocks/sticky-menu/view.js (1)

155-235: Tidy add_mobile_header: unused context param and comment punctuation.

  • The context parameter is never used in this function, but is documented in the JSDoc. This is likely to trigger no-unused-vars in the WordPress ESLint config. Either remove the parameter (and update the JSDoc and caller in initialize_mobile_sections) or use it meaningfully (for example, to derive accessible names or IDs).
  • Several newly added line comments here (for example lines 159, 163, 188, 199, 205) and in the Escape branch comment below do not end with a full stop. The coding guidelines you supplied require each line comment to end with a period; please update them accordingly.

Example for the Escape branch:

-                    // Always collapse on Escape if expanded
+                    // Always collapse on Escape if expanded.
🧹 Nitpick comments (8)
src/blocks/sticky-menu/view.js (8)

50-97: scroll_to_section logic looks sound; consider sharing offset calculation.

The scrolling, reduced‑motion handling, and focus management are solid. You now compute admin‑bar/masthead/sticky‑menu offsets here, in get_active_section_on_scroll, and in initialize_scroll_spy; extracting a small helper (e.g. getStickyOffset()) would keep the behaviour consistent and make future design‑token changes safer.


108-143: Use braces for the early return in toggle_mobile_section for clarity.

if (!element) return; is terse and out of step with the rest of the file and WordPress JS style, which prefers explicit blocks.

-    if (!element) return;
+    if (!element) {
+        return;
+    }

This improves readability without changing behaviour.


246-260: update_active_menu_item is global; consider scoping for multiple sticky menus.

This function currently queries .wp-block-lsx-tour-operator-sticky-menu .lsx-to-sticky-menu-button across the whole document and activates only the first button whose data-section-id matches. If multiple sticky‑menu blocks can exist on a page, one menu’s scroll state will clear the active state on all others.

Consider scoping the query to a specific sticky‑menu container (passed in or stored in state) so that each instance manages its own active button set independently.


271-422: Scroll‑spy and IntersectionObserver offsets are fine; consider a shared helper.

The scroll‑spy logic and IntersectionObserver configuration look correct and defensive (offsets include admin bar, masthead, and sticky menu; desktop/mobile switching is guarded). However, offset computation is now duplicated across scroll_to_section, get_active_section_on_scroll, and initialize_scroll_spy.

A small shared helper such as lsx_to.get_sticky_header_offset() would reduce drift and make it easier to keep behaviour aligned with future header or design‑system changes.


457-497: Prefer binding events to the actual button and consider stopping propagation.

Handlers are currently attached to .lsx-to-sticky-menu-item (the container) and then look up the inner .lsx-to-sticky-menu-button. For clearer semantics and keyboard behaviour, consider attaching both click and keydown handlers directly to the button element instead, and optionally stopping propagation to avoid interfering with outer handlers.

For example:

-    menu_items.forEach(function (item) {
-        // Enhance button accessibility
-        const button = item.querySelector('.lsx-to-sticky-menu-button');
-        if (button) {
-            const section_id = item.getAttribute('data-section-id');
-            const section_title = button.textContent.trim();
+    menu_items.forEach(function (item) {
+        const button = item.querySelector('.lsx-to-sticky-menu-button');
+        if (button) {
+            const section_id = item.getAttribute('data-section-id');
+            const section_title = button.textContent.trim();
@@
-        item.addEventListener('click', function (event) {
-            event.preventDefault();
-            const section_id = this.getAttribute('data-section-id');
-            if (section_id) {
-                lsx_to.scroll_to_section(section_id);
-            }
-        });
+        button.addEventListener('click', function (event) {
+            event.preventDefault();
+            event.stopPropagation();
+            if (section_id) {
+                lsx_to.scroll_to_section(section_id);
+            }
+        });
@@
-        item.addEventListener('keydown', function (event) {
-            const section_id = this.getAttribute('data-section-id');
-            if (section_id && (event.key === 'Enter' || event.key === ' ')) {
-                event.preventDefault();
-                lsx_to.scroll_to_section(section_id);
-            }
-        });
+        button.addEventListener('keydown', function (event) {
+            if (section_id && (event.key === 'Enter' || event.key === ' ')) {
+                event.preventDefault();
+                event.stopPropagation();
+                lsx_to.scroll_to_section(section_id);
+            }
+        });

This better aligns with the intent to have event listeners on the actual interactive control.


576-589: Consider removing the resize listener in cleanup_sticky_menu for completeness.

cleanup_sticky_menu removes the scroll listener and disconnects the IntersectionObserver, but the resize listener registered in initialize_scroll_spy is left in place. On normal full page loads this is harmless; on any AJAX‑driven or SPA‑style navigation it could lead to redundant listeners.

If you expect this script to live across navigations, consider also removing the resize listener there.


658-660: Ensure new line comments end with a period.

The new inline comment // change the opacity of the sticky menu to 1 does not end with a full stop. To match the coding guidelines you provided (every line comment should end with a period) and be consistent with other comments, please update it to:

-        // change the opacity of the sticky menu to 1
+        // Change the opacity of the sticky menu to 1.

600-625: Localise the screen-reader announcement string for WordPress localisation compliance.

The announce_section_change function at line 618 uses a hard-coded English string that should be wrapped with wp.i18n.__() and sprintf() to enable translation. WordPress JavaScript internationalisation best practices require using wp.i18n functions to wrap every user-visible string, e.g. sprintf( __( '%s items', 'my-text-domain' ), count ).

Update the announcement to:

const { __, sprintf } = wp.i18n;
announcer.textContent = sprintf( __( 'Navigated to %s section', 'tour-operator' ), section_title );

This approach mirrors your existing localisation pattern in index.js and ensures the script is enqueued with wp-i18n as a dependency so WordPress provides wp.i18n before your file runs. When using @wordpress/scripts, the import statement automatically declares the dependency for the built output.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f3255eb and 763f4f5.

📒 Files selected for processing (1)
  • src/blocks/sticky-menu/view.js (22 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{js,ts,tsx,jsx}

⚙️ CodeRabbit configuration file

**/*.{js,ts,tsx,jsx}: Perform a detailed review of the provided code with following key aspects in mind:

  • Review the code to ensure it is well-structured and adheres to best practices.
  • Verify compliance with WordPress coding standards and @wordpress/eslint-plugin rules.
  • Ensure the code is well-documented with proper JSDoc comments.
  • Check for security vulnerabilities and confirm the code is secure.
  • Optimize the code for performance, removing any unnecessary elements.
  • Validate JSDoc comments for accuracy, currency, and adherence to WordPress coding standards.
  • Ensure each line comment concludes with a period.
  • Confirm every JSDoc comment includes a @SInCE tag indicating the next version of the plugin to include the code.
  • Guarantee compatibility with the latest version of WordPress, avoiding deprecated functions or features.
  • Follow WordPress JavaScript coding standards and use WordPress script localization.
  • Use WordPress script dependencies and enqueue properly.
  • Ensure React/JSX best practices for blocks and modern JavaScript/TypeScript patterns.
  • Implement proper error handling and loading states.
  • Use WordPress components and design system where applicable.
  • For Tour Operator: Focus on tour booking interfaces, search functionality, and tour display components.

Files:

  • src/blocks/sticky-menu/view.js
src/blocks/**/*.{js,jsx,ts,tsx}

⚙️ CodeRabbit configuration file

src/blocks/**/*.{js,jsx,ts,tsx}: - Follow WordPress JavaScript coding standards and @wordpress/scripts configuration.

  • Use WordPress components from @wordpress/components and design system.
  • Implement proper React/JSX patterns for WordPress blocks.
  • Ensure proper WordPress script dependencies and localization.
  • Use WordPress data store patterns with @wordpress/data.
  • Implement proper error boundaries and loading states.
  • Follow modern JavaScript/TypeScript patterns with proper typing.
  • Ensure accessibility in interactive block components.
  • Use WordPress block editor APIs correctly (useBlockProps, InspectorControls, etc.).
  • Implement proper block validation and save/edit functionality.

Files:

  • src/blocks/sticky-menu/view.js
🧬 Code graph analysis (1)
src/blocks/sticky-menu/view.js (1)
src/js/custom.js (1)
  • lsx_to (8-8)
⏰ 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). (2)
  • GitHub Check: review
  • GitHub Check: Summary
🔇 Additional comments (4)
src/blocks/sticky-menu/view.js (4)

432-447: update_menu_items implementation is straightforward and robust.

The DOM scan and mapping into sticky_menu.menu_items handle the no‑sections case correctly and provide sensible fallbacks for titles. No issues from a correctness or performance perspective in this block.


507-566: Mobile section initialisation/cleanup looks consistent.

Initialising wrappers as collapsed with aria-expanded="false" and then dropping the collapsed class and attribute on desktop transition is coherent, and legacy support via using the section as wrapper is a pragmatic fallback. Given that headers are PHP‑rendered and likely styled for mobile only, leaving the header elements in place on desktop is acceptable.

No changes required here.


676-678: DOMContentLoaded initialisation is appropriate.

Hooking initialise_sticky_menu on DOMContentLoaded is appropriate here and avoids race conditions with late‑loading assets while keeping the script simple. No changes needed.


688-690: beforeunload cleanup wiring is acceptable.

Cleaning up the scroll spy and observer on beforeunload is harmless and provides a clear lifecycle end‑point for the feature on traditional page loads. No further changes required in this block.

Copy link
Copy Markdown
Collaborator

@krugazul krugazul left a comment

Choose a reason for hiding this comment

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

@tibiii Ive tested the new settings and styles and they are working great, the UI is working great thanks.

@github-project-automation github-project-automation bot moved this from 🔎 In Review to Needs Triage in Tour Operator Nov 21, 2025
@krugazul krugazul merged commit 26f8e35 into 2.1-trunk Nov 21, 2025
9 of 11 checks passed
@krugazul krugazul deleted the feature/771-sticky-menu-design-ux-improvements branch November 21, 2025 08:01
@github-project-automation github-project-automation bot moved this from Needs Triage to ✅ Done in Tour Operator Nov 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:block-editor lang:css Stylesheets lang:javascript lang:php PHP code meta:needs-changelog Requires a changelog entry before merge status:needs-review Awaiting code review

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

[Feature request] Style Sticky Menu Block According to Figma Design System

3 participants