Skip to content

feat: Add Sticky Menu Block with Desktop/Mobile Navigation#684

Merged
krugazul merged 9 commits into2.1-trunkfrom
feature/496-sticky-secondary-nav-menu
Oct 30, 2025
Merged

feat: Add Sticky Menu Block with Desktop/Mobile Navigation#684
krugazul merged 9 commits into2.1-trunkfrom
feature/496-sticky-secondary-nav-menu

Conversation

@tibiii
Copy link
Copy Markdown
Contributor

@tibiii tibiii commented Oct 28, 2025


name: "Feature: Sticky Menu Block"
about: "Add sticky navigation block with responsive design for single post templates"
title: "feat: Add Sticky Menu Block with Desktop/Mobile Navigation"

Summary

Implements a new Sticky Menu Block that provides anchor navigation functionality for single Tour, Destination, and Accommodation pages. This feature improves user experience by making it easy to navigate long content pages with jump-to-section navigation that remains visible while scrolling.

Linked issues: Closes #496 and relates to #374

Changes

New Block Implementation

  • Created sticky-menu block with comprehensive block.json configuration including attributes for mobile behavior, section anchors, and styling controls
  • Implemented Edit and Save components in index.js with proper editor integration and frontend rendering
  • Added server-side rendering in render.php to handle mobile headers and dynamic content generation
  • Developed sticky-menu-editor-extension.js to extend core/group blocks with sticky menu attributes and inspector controls

Frontend Functionality

  • Implemented view.js with complete sticky menu functionality including:
    • Scroll-to-section navigation with smooth scrolling
    • Active menu item highlighting based on viewport position
    • Mobile section toggling with accordion-style interaction
    • Keyboard accessibility support (Enter/Space keys)
    • Proper cleanup of event listeners and observers

Styling & Responsive Design

  • Created comprehensive SCSS styles ensuring responsive design for desktop and mobile
  • Desktop behavior: Fixed sticky navigation with horizontal menu items
  • Mobile behavior: Collapsible sections with toggle functionality
  • Accessibility features: Proper focus management, ARIA attributes, and keyboard navigation
  • Generated RTL-compatible styles for international language support

Build Integration

  • Updated build pipeline to include new sticky menu block assets
  • Generated proper asset dependencies with webpack asset management
  • Compiled CSS and JavaScript with proper source maps for debugging

Test Notes

  • Desktop Testing: Verify sticky menu remains fixed while scrolling and active items update correctly
  • Mobile Testing: Confirm accordion functionality works with proper expand/collapse behavior
  • Keyboard Navigation: Test Enter/Space key functionality and focus management
  • Cross-browser: Verify functionality across Chrome, Firefox, Safari, and Edge
  • Single Post Types: Test on Tour, Accommodation, and Destination single pages
  • Accessibility: Screen reader compatibility and ARIA attributes function properly

Risk & Rollback

  • Risk level: Medium - New block with JavaScript functionality
  • Rollback plan: Remove block registration from tour-operator.php and clear compiled assets; no database changes required

Implementation Details

Technical Architecture

  • Block Structure: Utilizes WordPress block development best practices with proper useBlockProps() integration
  • Performance: Uses Intersection Observer API for efficient scroll position detection
  • Accessibility: Implements WCAG 2.2 AA compliance with proper ARIA roles and keyboard navigation
  • Mobile-First: Responsive design approach with progressive enhancement for desktop

Integration Points

  • Block Editor: Seamlessly integrates with WordPress 6.x block editor
  • Theme Compatibility: Uses standard WordPress block wrapper attributes for theme consistency
  • Extension Support: Editor extension allows adding sticky menu functionality to existing group blocks

Checklist (Global DoD / PR)

  • All AC met and demonstrated (sticky navigation, mobile toggles, keyboard accessibility)
  • Tests added/updated (frontend JavaScript functionality with proper event handling)
  • A11y considerations addressed where relevant (ARIA attributes, keyboard navigation, focus management)
  • Docs/readme/changelog updated (if user-facing) - Ready for documentation team review
  • Security/perf impact reviewed where relevant (Intersection Observer API, proper event cleanup)
  • Code/design reviews approved - Pending review
  • CI green; linked issues closed; release notes prepared (if shipping) - Pending CI validation

Summary by CodeRabbit

  • New Features

    • Added a Sticky Menu block for single-post templates with desktop and collapsible mobile navigation, smooth scroll-to-section, active-state highlighting, scroll‑spy, keyboard/ARIA accessibility and screen‑reader announcements.
    • Editor controls to mark sections as Sticky Menu sources, visual editor badges, and save-time attributes for in-page anchors.
    • Mobile section headers enable toggling individual content sections with accessible focus handling.
    • Enhanced styling, responsive behaviour and reduced‑motion support.
  • Documentation

    • Changelog updated with the new Sticky Menu entry.

- Created block.json for the Sticky Menu block with necessary attributes and settings.
- Implemented the Edit and Save components in index.js to manage the block's behavior in the editor and on the frontend.
- Added server-side rendering in render.php to handle mobile headers for sticky menu sections.
- Developed sticky-menu-editor-extension.js to extend core/group block with sticky menu attributes and controls.
- Styled the Sticky Menu block with SCSS, ensuring responsive design and accessibility features.
- Implemented view.js for sticky menu functionality, including scroll-to-section, mobile section toggling, and active menu item updates.
- Added event listeners for keyboard accessibility and mobile interactions.
- Ensured proper cleanup of event listeners and observers on page unload.
@github-actions github-actions bot added lang:php PHP code lang:css Stylesheets lang:javascript area:block-editor status:needs-review Awaiting code review meta:needs-changelog Requires a changelog entry before merge labels Oct 28, 2025
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Oct 28, 2025

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

📥 Commits

Reviewing files that changed from the base of the PR and between e186434 and 5fc2272.

⛔ Files ignored due to path filters (167)
  • build/admin-rtl.css is excluded by !build/**
  • build/admin-script.asset.php is excluded by !build/**
  • build/admin-script.js is excluded by !build/**
  • build/admin.asset.php is excluded by !build/**
  • build/admin.css is excluded by !build/**
  • build/blocks/accommodation-related-accommodation/index.asset.php is excluded by !build/**
  • build/blocks/accommodation-related-accommodation/index.js is excluded by !build/**
  • build/blocks/accommodation-related-destination/index.asset.php is excluded by !build/**
  • build/blocks/accommodation-related-destination/index.js is excluded by !build/**
  • build/blocks/accommodation-related-tour/index.asset.php is excluded by !build/**
  • build/blocks/accommodation-related-tour/index.js is excluded by !build/**
  • build/blocks/accommodation-type/index.asset.php is excluded by !build/**
  • build/blocks/accommodation-type/index.js is excluded by !build/**
  • build/blocks/additional-info/index.asset.php is excluded by !build/**
  • build/blocks/additional-info/index.js is excluded by !build/**
  • build/blocks/banking/index.asset.php is excluded by !build/**
  • build/blocks/banking/index.js is excluded by !build/**
  • build/blocks/banner-cover/index.asset.php is excluded by !build/**
  • build/blocks/banner-cover/index.js is excluded by !build/**
  • build/blocks/best-time-to-visit/index.asset.php is excluded by !build/**
  • build/blocks/best-time-to-visit/index.js is excluded by !build/**
  • build/blocks/booking-validity/index.asset.php is excluded by !build/**
  • build/blocks/booking-validity/index.js is excluded by !build/**
  • build/blocks/checkin-time/index.asset.php is excluded by !build/**
  • build/blocks/checkin-time/index.js is excluded by !build/**
  • build/blocks/checkout-time/index.asset.php is excluded by !build/**
  • build/blocks/checkout-time/index.js is excluded by !build/**
  • build/blocks/climate/index.asset.php is excluded by !build/**
  • build/blocks/climate/index.js is excluded by !build/**
  • build/blocks/cuisine/index.asset.php is excluded by !build/**
  • build/blocks/cuisine/index.js is excluded by !build/**
  • build/blocks/day-by-day/index.asset.php is excluded by !build/**
  • build/blocks/day-by-day/index.js is excluded by !build/**
  • build/blocks/departs-from/index.asset.php is excluded by !build/**
  • build/blocks/departs-from/index.js is excluded by !build/**
  • build/blocks/destination-to-accommodation/index.asset.php is excluded by !build/**
  • build/blocks/destination-to-accommodation/index.js is excluded by !build/**
  • build/blocks/dress/index.asset.php is excluded by !build/**
  • build/blocks/dress/index.js is excluded by !build/**
  • build/blocks/duration/index.asset.php is excluded by !build/**
  • build/blocks/duration/index.js is excluded by !build/**
  • build/blocks/electricity/index.asset.php is excluded by !build/**
  • build/blocks/electricity/index.js is excluded by !build/**
  • build/blocks/ends-in/index.asset.php is excluded by !build/**
  • build/blocks/ends-in/index.js is excluded by !build/**
  • build/blocks/facilities/index.asset.php is excluded by !build/**
  • build/blocks/facilities/index.js is excluded by !build/**
  • build/blocks/facts-country-wrapper/index.asset.php is excluded by !build/**
  • build/blocks/facts-country-wrapper/index.js is excluded by !build/**
  • build/blocks/facts-regions-wrapper/index.asset.php is excluded by !build/**
  • build/blocks/facts-regions-wrapper/index.js is excluded by !build/**
  • build/blocks/featured-accommodation/index.asset.php is excluded by !build/**
  • build/blocks/featured-accommodation/index.js is excluded by !build/**
  • build/blocks/featured-destinations/index.asset.php is excluded by !build/**
  • build/blocks/featured-destinations/index.js is excluded by !build/**
  • build/blocks/featured-tours/index.asset.php is excluded by !build/**
  • build/blocks/featured-tours/index.js is excluded by !build/**
  • build/blocks/gallery/index.asset.php is excluded by !build/**
  • build/blocks/gallery/index.js is excluded by !build/**
  • build/blocks/google-map/index.asset.php is excluded by !build/**
  • build/blocks/google-map/index.js is excluded by !build/**
  • build/blocks/group-size/index.asset.php is excluded by !build/**
  • build/blocks/group-size/index.js is excluded by !build/**
  • build/blocks/health/index.asset.php is excluded by !build/**
  • build/blocks/health/index.js is excluded by !build/**
  • build/blocks/icons/index.asset.php is excluded by !build/**
  • build/blocks/icons/index.js is excluded by !build/**
  • build/blocks/icons/style-index-rtl.css is excluded by !build/**
  • build/blocks/icons/style-index.css is excluded by !build/**
  • build/blocks/included/index.asset.php is excluded by !build/**
  • build/blocks/included/index.js is excluded by !build/**
  • build/blocks/itinerary/index.asset.php is excluded by !build/**
  • build/blocks/itinerary/index.js is excluded by !build/**
  • build/blocks/lsx-destination-to-tour/index.asset.php is excluded by !build/**
  • build/blocks/lsx-destination-to-tour/index.js is excluded by !build/**
  • build/blocks/minimum-child-age/index.asset.php is excluded by !build/**
  • build/blocks/minimum-child-age/index.js is excluded by !build/**
  • build/blocks/modal-button/index.asset.php is excluded by !build/**
  • build/blocks/modal-button/index.js is excluded by !build/**
  • build/blocks/more-link/index.asset.php is excluded by !build/**
  • build/blocks/more-link/index.js is excluded by !build/**
  • build/blocks/not-included/index.asset.php is excluded by !build/**
  • build/blocks/not-included/index.js is excluded by !build/**
  • build/blocks/number-of-rooms/index.asset.php is excluded by !build/**
  • build/blocks/number-of-rooms/index.js is excluded by !build/**
  • build/blocks/permalink-button/index.asset.php is excluded by !build/**
  • build/blocks/permalink-button/index.js is excluded by !build/**
  • build/blocks/price-include-exclude/index.asset.php is excluded by !build/**
  • build/blocks/price-include-exclude/index.js is excluded by !build/**
  • build/blocks/price/index.asset.php is excluded by !build/**
  • build/blocks/price/index.js is excluded by !build/**
  • build/blocks/rating/index.asset.php is excluded by !build/**
  • build/blocks/rating/index.js is excluded by !build/**
  • build/blocks/regions/index.asset.php is excluded by !build/**
  • build/blocks/regions/index.js is excluded by !build/**
  • build/blocks/related-regions/index.asset.php is excluded by !build/**
  • build/blocks/related-regions/index.js is excluded by !build/**
  • build/blocks/review-related-accommodation/index.asset.php is excluded by !build/**
  • build/blocks/review-related-accommodation/index.js is excluded by !build/**
  • build/blocks/review-related-destination/index.asset.php is excluded by !build/**
  • build/blocks/review-related-destination/index.js is excluded by !build/**
  • build/blocks/review-related-tour/index.asset.php is excluded by !build/**
  • build/blocks/review-related-tour/index.js is excluded by !build/**
  • build/blocks/safety/index.asset.php is excluded by !build/**
  • build/blocks/safety/index.js is excluded by !build/**
  • build/blocks/single-supplement-wrapper/index.asset.php is excluded by !build/**
  • build/blocks/single-supplement-wrapper/index.js is excluded by !build/**
  • build/blocks/special-interests/index.asset.php is excluded by !build/**
  • build/blocks/special-interests/index.js is excluded by !build/**
  • build/blocks/spoken-languages/index.asset.php is excluded by !build/**
  • build/blocks/spoken-languages/index.js 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/sticky-menu-editor-extension.asset.php is excluded by !build/**
  • build/blocks/sticky-menu/sticky-menu-editor-extension.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/**
  • build/blocks/suggested-visitor-types/index.asset.php is excluded by !build/**
  • build/blocks/suggested-visitor-types/index.js is excluded by !build/**
  • build/blocks/tagline/index.asset.php is excluded by !build/**
  • build/blocks/tagline/index.js is excluded by !build/**
  • build/blocks/tour-related-accommodation/index.asset.php is excluded by !build/**
  • build/blocks/tour-related-accommodation/index.js is excluded by !build/**
  • build/blocks/tour-related-destination/index.asset.php is excluded by !build/**
  • build/blocks/tour-related-destination/index.js is excluded by !build/**
  • build/blocks/tour-related-tour/index.asset.php is excluded by !build/**
  • build/blocks/tour-related-tour/index.js is excluded by !build/**
  • build/blocks/transport/index.asset.php is excluded by !build/**
  • build/blocks/transport/index.js is excluded by !build/**
  • build/blocks/travel-styles/index.asset.php is excluded by !build/**
  • build/blocks/travel-styles/index.js is excluded by !build/**
  • build/blocks/unit-rooms/index.asset.php is excluded by !build/**
  • build/blocks/unit-rooms/index.js is excluded by !build/**
  • build/blocks/units/index.asset.php is excluded by !build/**
  • build/blocks/units/index.js is excluded by !build/**
  • build/blocks/videos/index.asset.php is excluded by !build/**
  • build/blocks/videos/index.js is excluded by !build/**
  • build/blocks/visa/index.asset.php is excluded by !build/**
  • build/blocks/visa/index.js is excluded by !build/**
  • build/blocks/wetu-map/index.asset.php is excluded by !build/**
  • build/blocks/wetu-map/index.js is excluded by !build/**
  • build/custom.asset.php is excluded by !build/**
  • build/custom.js is excluded by !build/**
  • build/general.asset.php is excluded by !build/**
  • build/general.js is excluded by !build/**
  • build/linked-cover.asset.php is excluded by !build/**
  • build/linked-cover.js is excluded by !build/**
  • build/maps.asset.php is excluded by !build/**
  • build/maps.js is excluded by !build/**
  • build/metabox-structure.asset.php is excluded by !build/**
  • build/metabox-structure.js is excluded by !build/**
  • build/metaboxes-rtl.css is excluded by !build/**
  • build/metaboxes.asset.php is excluded by !build/**
  • build/metaboxes.css is excluded by !build/**
  • build/modals.asset.php is excluded by !build/**
  • build/modals.js is excluded by !build/**
  • build/scporder.asset.php is excluded by !build/**
  • build/scporder.js is excluded by !build/**
  • build/slider-query.asset.php is excluded by !build/**
  • build/slider-query.js is excluded by !build/**
  • build/slotfills.asset.php is excluded by !build/**
  • build/slotfills.js is excluded by !build/**
  • build/style-rtl.css is excluded by !build/**
  • build/style.asset.php is excluded by !build/**
  • build/style.css is excluded by !build/**
📒 Files selected for processing (1)
  • src/blocks/sticky-menu/sticky-menu-editor-extension.js (1 hunks)
 ________________________________________________________________________________________________________________________________________________________________________________________________
< Abstractions live longer than details. Invest in the abstraction, not the implementation. Abstractions can survive the barrage of changes from different implementations and new technologies. >
 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).

Tip

You can make CodeRabbit's review stricter and more nitpicky using the `assertive` profile, if that's what you prefer.

Change the reviews.profile setting in your project's settings in CodeRabbit to assertive to make CodeRabbit's nitpick more issues in your PRs.

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.

Walkthrough

Adds a new Sticky Menu block and integrates it across editor and frontend: block manifest and assets, editor HOCs for core/group (attributes, inspector controls, visual badge, save props), server render filter injecting mobile headers, frontend view.js with scroll‑spy and mobile toggle APIs, styles, and plugin bootstrap inclusion.

Changes

Cohort / File(s) Summary
Changelog
changelog.md
Added entry documenting the new Sticky Menu Block with desktop/mobile navigation (PR #684).
Block Manifest
src/blocks/sticky-menu/block.json
New block manifest lsx-tour-operator/sticky-menu declaring attributes (position, menuItems), supports, assets (editor scripts, style, view script) and textdomain.
Block Registration & UI
src/blocks/sticky-menu/index.js
New Edit and Save components; Edit scans blocks (debounced) for core/group candidates (addToStickyMenu) to build menuItems, renders nav or placeholder; Save outputs static nav HTML and registers block.
Editor Extension / HOCs
src/blocks/sticky-menu/sticky-menu-editor-extension.js
Adds attributes to core/group (addToStickyMenu, stickyMenuId, stickyMenuTitle), inspector controls HOC (ID/title toggle), save-time prop enhancer (IDs, ARIA, classes), and editor visual indicator HOC; registers filters/hooks.
Server-side Rendering
src/blocks/sticky-menu/render.php
Adds add_mobile_section_headers( $block_content, $block ) and registers render_block filter to wrap eligible core/group blocks with mobile header/button, collapsible wrapper markup and ARIA attributes.
Styles
src/blocks/sticky-menu/style.scss
New SCSS for .lsx-to-sticky-menu and related classes: sticky positioning, responsive nav layout, mobile collapsible section styling, transitions, reduced-motion support and editor helpers/placeholders.
Frontend View Script
src/blocks/sticky-menu/view.js
Adds client-side sticky menu system exposed on lsx_to: scroll-to, scroll-spy (IntersectionObserver + offsets), mobile section toggles, menu item updates, accessibility announcements, init/cleanup flows and public API/state.
Plugin Bootstrap
tour-operator.php
Added require_once to include the sticky menu block rendering file during plugin initialization.

Sequence Diagram(s)

sequenceDiagram
    participant Editor as Block Editor
    participant useSelect as useSelect Hook
    participant Scanner as Block Scanner (debounced)
    participant EditUI as Sticky Menu Edit UI

    Editor->>useSelect: subscribe to blocks
    useSelect->>Scanner: trigger scan (debounced 500ms)
    Scanner->>Scanner: recursively collect core/group with addToStickyMenu
    alt candidates found
        Scanner->>EditUI: update attributes.menuItems
        EditUI->>Editor: render navigation list
    else none
        EditUI->>Editor: render placeholder & troubleshooting
    end
Loading
sequenceDiagram
    participant User as Page Visitor
    participant Scroll as Scroll Event
    participant Observer as IntersectionObserver
    participant Sticky as sticky_menu.handle_scroll_spy
    participant Active as update_active_menu_item
    participant SR as aria-live region

    User->>Scroll: scrolls page
    Scroll->>Observer: intersection updates
    Observer->>Sticky: determine active section
    Sticky->>Active: set active menu item / aria-current
    Active->>SR: announce_section_change
Loading
sequenceDiagram
    participant MobileUser as Mobile User
    participant HeaderBtn as Mobile Header Button
    participant ToggleFn as toggle_mobile_section
    participant Wrapper as Collapsible Section

    MobileUser->>HeaderBtn: click / keypress
    HeaderBtn->>ToggleFn: invoke
    ToggleFn->>Wrapper: toggle expanded/collapsed, set aria-expanded
    Wrapper->>MobileUser: animate reveal/hide
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Pay extra attention to:
    • src/blocks/sticky-menu/view.js — scroll offset calculations, IntersectionObserver lifecycle, event listeners and cleanup, reduced‑motion handling.
    • src/blocks/sticky-menu/sticky-menu-editor-extension.js — attribute injection, HOC logic, inspector controls, debounced syncing with native attributes.
    • src/blocks/sticky-menu/index.js — debounced recursive scanner and equality/comparison logic for menuItems updates.
    • src/blocks/sticky-menu/render.php — correctness of injected markup, ARIA attributes and collapsible wrapper semantics.

Possibly related issues

Suggested labels

[Type] Feature, comp:block-json, comp:block-editor, comp:block-variations

Suggested reviewers

  • krugazul
  • ZaredRogers

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title Check ✅ Passed The title "feat: Add Sticky Menu Block with Desktop/Mobile Navigation" directly reflects the primary change in the pull request—implementing a new sticky menu block with responsive design capabilities. It uses the conventional commit format with "feat:" prefix, is concise and readable (58 characters), and clearly communicates the main functionality added. The title is specific enough for developers scanning the history to understand this introduces a new navigation block with both desktop and mobile support, which accurately summarizes the extensive changeset.
Linked Issues Check ✅ Passed The implementation successfully addresses all primary requirements from linked issue #496. The changeset includes sticky positioning with visibility management (view.js, style.scss), dynamic section navigation through jump-to-section anchors (index.js, view.js), active section highlighting using Intersection Observer scroll-spy (view.js), smooth scrolling with offset calculations for admin bars and fixed headers (view.js), comprehensive keyboard accessibility via Enter/Space keys (view.js), screen reader support through ARIA attributes and announcements (view.js), mobile responsiveness with accordion-style toggling (view.js, render.php), and prevention of layout shifts through proper event handling. All acceptance criteria—sticky nav visibility, active highlighting, smooth scrolling, keyboard/screen reader accessibility, and no overlapping content—are satisfied by the implementation.
Out of Scope Changes Check ✅ Passed All changes in the pull request remain within the scope defined by issue #496 and the broader sticky menu navigation feature. The eight modified or added files—changelog.md (documentation update), block.json (block manifest), index.js (block components), render.php (server-side rendering), sticky-menu-editor-extension.js (editor integration), style.scss (styling), view.js (frontend functionality), and tour-operator.php (plugin initialization)—directly implement or support the sticky anchor navigation requirement. No auxiliary refactoring, unrelated improvements, or out-of-scope modifications are present in the changeset.
Description Check ✅ Passed The pull request description comprehensively follows the repository template, including all required sections: a clear Summary with linked issues (Closes #496, Relates to #374), a detailed Changes section organized into logical subsections (New Block Implementation, Frontend Functionality, Styling & Responsive Design, Build Integration), Test Notes with checkbox items, Risk & Rollback assessment, and the completed DoD checklist. The description provides substantial detail about the technical implementation, architecture decisions, and acceptance criteria validation, making it well-structured and informative for reviewers.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

github-actions bot commented Oct 28, 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.

@tibiii tibiii self-assigned this Oct 28, 2025
@github-project-automation github-project-automation bot moved this to Needs Triage in Tour Operator Oct 28, 2025
@tibiii tibiii added this to the v2.1.0 milestone Oct 28, 2025
@tibiii tibiii moved this from Needs Triage to 🔎 In Review in Tour Operator Oct 28, 2025
@github-actions github-actions bot added lang:md Markdown content/docs status:needs-review Awaiting code review and removed status:needs-review Awaiting code review labels Oct 28, 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 436e3f8 and 0afcb23 commits.
Files selected (12)
  • build/blocks/sticky-menu/index.js (1)
  • build/blocks/sticky-menu/sticky-menu-editor-extension.js (1)
  • build/blocks/sticky-menu/style-index-rtl.css (1)
  • build/blocks/sticky-menu/style-index.css (1)
  • build/blocks/sticky-menu/view.js (1)
  • changelog.md (1)
  • src/blocks/sticky-menu/index.js (1)
  • src/blocks/sticky-menu/render.php (1)
  • src/blocks/sticky-menu/sticky-menu-editor-extension.js (1)
  • src/blocks/sticky-menu/style.scss (1)
  • src/blocks/sticky-menu/view.js (1)
  • tour-operator.php (1)
Files ignored due to filter (2)
  • build/blocks/sticky-menu/block.json
  • src/blocks/sticky-menu/block.json
Files not summarized due to errors (12)
  • build/blocks/sticky-menu/index.js (diff tokens exceeds limit)
  • build/blocks/sticky-menu/sticky-menu-editor-extension.js (diff tokens exceeds limit)
  • build/blocks/sticky-menu/view.js (diff tokens exceeds limit)
  • src/blocks/sticky-menu/render.php (nothing obtained from openai)
  • changelog.md (nothing obtained from openai)
  • src/blocks/sticky-menu/view.js (diff tokens exceeds limit)
  • src/blocks/sticky-menu/sticky-menu-editor-extension.js (nothing obtained from openai)
  • src/blocks/sticky-menu/index.js (nothing obtained from openai)
  • build/blocks/sticky-menu/style-index-rtl.css (nothing obtained from openai)
  • build/blocks/sticky-menu/style-index.css (nothing obtained from openai)
  • src/blocks/sticky-menu/style.scss (nothing obtained from openai)
  • tour-operator.php (nothing obtained from openai)
Files not reviewed due to errors (9)
  • build/blocks/sticky-menu/style-index.css (no response)
  • changelog.md (no response)
  • src/blocks/sticky-menu/render.php (no response)
  • build/blocks/sticky-menu/style-index-rtl.css (no response)
  • build/blocks/sticky-menu/sticky-menu-editor-extension.js (no response)
  • src/blocks/sticky-menu/index.js (no response)
  • tour-operator.php (no response)
  • src/blocks/sticky-menu/style.scss (no response)
  • src/blocks/sticky-menu/sticky-menu-editor-extension.js (no response)
Files skipped from review due to trivial changes (3)
  • build/blocks/sticky-menu/index.js (diff too large)
  • build/blocks/sticky-menu/view.js (diff too large)
  • src/blocks/sticky-menu/view.js (diff too large)
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: 30

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

51-54: Respect reduced motion and avoid transition: all.

Specify properties and disable transitions for users preferring reduced motion. Also add coverage on .sticky-menu-button.

-.sticky-menu-button {
-  transition: opacity 0.2s ease;
-}
+.sticky-menu-button { transition: opacity 0.2s ease; }
+@media (prefers-reduced-motion: reduce) {
+  .sticky-menu-button { transition: none; }
+}
 
-  /* Ensure smooth transitions (respect motion preferences) */
-  transition: all 0.3s ease;
+  /* Target properties explicitly. */
+  transition: transform 0.3s ease;
   @media (prefers-reduced-motion: reduce) {
     transition: none;
   }
 
-button.section-header {
-  transition: all 0.2s ease;
+button.section-header {
+  transition: background-color 0.2s ease, color 0.2s ease;
+}
+@media (prefers-reduced-motion: reduce) {
+  button.section-header { transition: none; }
 }

Also applies to: 124-129, 168-169


53-54: Convert px ≥ 3 to rem via to_rem().

Radius and caret use fixed px; follow the rem rule.

-  border-radius: 4px;
+  border-radius: to_rem(4px);
 ...
-  border-top: 6px solid currentColor;
-  border-right: 6px solid transparent;
-  border-left: 6px solid transparent;
+  border-top: to_rem(6px) solid currentColor;
+  border-right: to_rem(6px) solid transparent;
+  border-left: to_rem(6px) solid transparent;

Also applies to: 183-191


95-104: Avoid inline sizing in px; use to_rem() and existing helper classes.

Replace 11px/16px with rems and prefer the existing .sticky-menu-help styles instead of duplicating.

 .sticky-menu-help {
-  font-size: 11px;
-  margin-top: 8px;
+  font-size: to_rem(11px);
+  margin-top: to_rem(8px);
 }
 .sticky-menu-help ol {
-  margin-left: 16px;
+  margin-left: to_rem(16px);
   line-height: 1.4;
   text-align: left;
 }

1-202: Align class naming and tokens with guidelines.

  • Prefer tour-operator- prefixed, BEM‑style class names, or add prefixed aliases alongside current classes.
  • Where possible, use theme tokens (e.g., var(--wp--preset--color--… )) instead of rgba(0,0,0,0.1) and magic z-index: 100.
tour-operator.php (1)

45-48: Minor doc comment punctuation.

Add a trailing full stop per guidelines.

 /**
- * Include sticky menu block functionality. This doesn't work via the block.json registration method
+ * Include sticky menu block functionality. This doesn't work via the block.json registration method.
  */
 require_once LSX_TO_PATH . 'src/blocks/sticky-menu/render.php';
src/blocks/sticky-menu/block.json (1)

9-10: Add keywords for discoverability and ensure strings are localisation‑friendly.

Include a short keywords list.

   "description": "A sticky navigation menu that links to sections on the page",
+  "keywords": [ "menu", "navigation", "anchor", "sticky", "scroll" ],

Also applies to: 41-49

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

23-29: Avoid inline styles; rely on block supports/theme.json.

Let supports.color/spacing/typography handle styling via block wrapper. Remove ad‑hoc style props.

-  const blockProps = useBlockProps({
-    className: `lsx-sticky-menu position-${position}`,
-    style: {
-      backgroundColor: backgroundColor || undefined,
-      color: textColor || undefined,
-    },
-  });
+  const blockProps = useBlockProps({ className: `lsx-sticky-menu position-${position}` });

105-114: Avoid inline styles in editor help; use the SCSS helper class.

Use .sticky-menu-help styles instead of inline CSS.

-              <details style={{ fontSize: '11px', color: '#666', marginTop: '8px' }}>
+              <details className="sticky-menu-help">
                 <summary>{__('Troubleshooting', 'tour-operator')}</summary>
-                <ol style={{ marginLeft: '16px', lineHeight: '1.4' }}>
+                <ol>

1-10: Add JSDoc with @since and ensure eslint rules are satisfied.

Document Edit/Save per guidelines and include @since 2.1.0.

src/blocks/sticky-menu/sticky-menu-editor-extension.js (1)

101-106: Validate cleaned ID is not empty.

After sanitizing the CSS ID, there's no validation to ensure the cleaned ID isn't empty. If a user enters only invalid characters, cleanId will be an empty string, which could cause issues.

Apply this diff to add validation:

 onBlur={() => {
     // Clean and save to attributes when user finishes typing
     const cleanId = localStickyMenuId.replace(/[^a-zA-Z0-9-_]/g, '').toLowerCase();
+    
+    // Ensure ID is not empty and doesn't start with a digit
+    if (cleanId && !/^\d/.test(cleanId)) {
         setLocalStickyMenuId(cleanId);
         setAttributes({ stickyMenuId: cleanId });
+    } else {
+        // Reset to empty if invalid
+        setLocalStickyMenuId('');
+        setAttributes({ stickyMenuId: '' });
+    }
-    setLocalStickyMenuId(cleanId);
-    setAttributes({ stickyMenuId: cleanId });
 }}
src/blocks/sticky-menu/view.js (3)

211-224: Remove aria-current attribute instead of setting to 'false'.

According to ARIA best practices, aria-current should be removed entirely when not applicable, rather than being set to 'false'. This provides clearer semantics for assistive technologies.

Apply this diff:

     // Remove active class and aria-current from all menu buttons
     const menu_buttons = document.querySelectorAll('.wp-block-lsx-tour-operator-sticky-menu .sticky-menu-button');
     menu_buttons.forEach(button => {
         button.classList.remove('active');
-        button.setAttribute('aria-current', 'false');
+        button.removeAttribute('aria-current');
     });
 
     // Add active class and aria-current to current menu button

613-618: Add JSDoc comments for event listeners.

The DOMContentLoaded event listener should have a JSDoc comment explaining when initialization occurs.

Apply this diff:

 /**
  * Initialize when DOM is ready.
+ *
+ * @since 2.1.0
  */
 document.addEventListener('DOMContentLoaded', function() {

620-625: Add JSDoc comments for cleanup event listener.

The beforeunload event listener should have a JSDoc comment.

Apply this diff:

 /**
  * Cleanup when page is unloaded.
+ *
+ * @since 2.1.0
  */
 window.addEventListener('beforeunload', function() {
📜 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 436e3f8 and 0afcb23.

⛔ Files ignored due to path filters (9)
  • 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/sticky-menu-editor-extension.asset.php is excluded by !build/**
  • build/blocks/sticky-menu/sticky-menu-editor-extension.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 (8)
  • changelog.md (1 hunks)
  • src/blocks/sticky-menu/block.json (1 hunks)
  • src/blocks/sticky-menu/index.js (1 hunks)
  • src/blocks/sticky-menu/render.php (1 hunks)
  • src/blocks/sticky-menu/sticky-menu-editor-extension.js (1 hunks)
  • src/blocks/sticky-menu/style.scss (1 hunks)
  • src/blocks/sticky-menu/view.js (1 hunks)
  • tour-operator.php (1 hunks)
🧰 Additional context used
📓 Path-based instructions (20)
**/*.php

📄 CodeRabbit inference engine (.github/instructions/coding-standards.instructions.md)

**/*.php: PHP classes must use the Tour_Operator_ prefix with Pascal_Case
PHP functions must use the tour_operator_ prefix with snake_case
Variables should use snake_case (e.g., $tour_data, $destination_info)
Constants must use UPPER_SNAKE_CASE (e.g., TOUR_OPERATOR_VERSION)
Always sanitize input data (e.g., sanitize_text_field)
Validate all data before processing (e.g., type checks, ranges)
Escape all output (e.g., esc_html, wp_kses_post)
Use nonces for form submissions (e.g., wp_nonce_field)
Use $wpdb->prepare() for all SQL queries
Prefix all custom tables with $wpdb->prefix
Prefer WordPress database helper functions when possible
Prefix all hooks (actions/filters) with tour_operator_
Document all hooks with proper DocBlocks
Provide examples in hook documentation DocBlocks
One class per PHP file
All functions must have DocBlocks
Use @SInCE tags for version tracking in DocBlocks
Include @param and @return tags in DocBlocks
Use transients for temporary cached data
Minimize database queries

Use wp_enqueue_block_style and wp_register_style with proper dependencies when adding styles in WordPress

**/*.php: Use proper WordPress file headers with plugin/theme information
Use kebab-case for file names
Use snake_case for PHP function names
Prefix all functions, classes, and constants to avoid conflicts
Escape all output using appropriate WordPress functions (esc_html, esc_attr, esc_url, wp_kses_post)
Sanitize input immediately on receipt (e.g., sanitize_text_field, sanitize_email, esc_url_raw)
Use nonces for all forms and AJAX requests and verify with wp_verify_nonce
Check user capabilities (current_user_can) before privileged actions
Always use $wpdb->prepare for custom SQL queries
Prefer WordPress API functions (e.g., get_posts) over direct SQL queries
Internationalize strings using __, _e, _x, _n with a consistent text domain
For JavaScript strings, pass data via wp_localize_script and include nonces where needed
Use WordPress error handling: check is_wp_error, log...

Files:

  • tour-operator.php
  • src/blocks/sticky-menu/render.php
**/*.{php,js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/instructions/review.instructions.md)

Internationalize user‑facing strings using WordPress i18n APIs

Files:

  • tour-operator.php
  • src/blocks/sticky-menu/render.php
  • src/blocks/sticky-menu/index.js
  • src/blocks/sticky-menu/sticky-menu-editor-extension.js
  • src/blocks/sticky-menu/view.js
**/*.{php,html,jsx,tsx}

📄 CodeRabbit inference engine (.github/instructions/review.instructions.md)

Do not use inline CSS (no style attributes or inline style props)

Files:

  • tour-operator.php
  • src/blocks/sticky-menu/render.php
**/*.{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:

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

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Avoid ad‑hoc CSS; prefer theme.json + block selectors

Files:

  • src/blocks/sticky-menu/style.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
**/*.{css,scss}

📄 CodeRabbit inference engine (.github/instructions/accessibility.instructions.md)

Respect prefers-reduced-motion for animations

Provide mobile‑first responsive behavior

Prefer CSS utilities/presets over custom CSS to reduce CSS size and specificity

Use theme.json design tokens (var(--wp--...)) instead of hard‑coded styles in stylesheets

Files:

  • src/blocks/sticky-menu/style.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
{assets,src}/**/*

📄 CodeRabbit inference engine (.github/instructions/block-theme-structure.instructions.md)

Keep SCSS/JS/images source assets in assets/ or src/

Files:

  • src/blocks/sticky-menu/style.scss
  • src/blocks/sticky-menu/block.json
  • src/blocks/sticky-menu/render.php
  • src/blocks/sticky-menu/index.js
  • src/blocks/sticky-menu/sticky-menu-editor-extension.js
  • src/blocks/sticky-menu/view.js
src/**/block.json

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/block.json: Prefer block.json with server-side registration for blocks (avoid ad‑hoc registration)
Use the block namespace lsx-to in block names

Files:

  • src/blocks/sticky-menu/block.json
**/block.json

📄 CodeRabbit inference engine (.github/instructions/accessibility.instructions.md)

**/block.json: Provide meaningful block titles, descriptions, and keywords in block.json
Include editor-specific accessibility guidance in block descriptions (block.json)
Include accessibility considerations in block registration (e.g., supports, attributes)

**/block.json: In block.json, include required fields: name, title, description, category, keywords, and supports
Ensure accessible metadata in block.json: use clear, descriptive title and description
Provide reasonable default values for attributes in block.json
Use usesInnerBlocks in block.json only when the block actually contains InnerBlocks
Define block variations in block.json to provide common starting points
Ensure i18n and RTL safety for user-facing strings in block.json (including variations)

Files:

  • src/blocks/sticky-menu/block.json
**/*.md

⚙️ CodeRabbit configuration file

**/*.md: - Keep documentation updated with code changes and new features.

  • Use clear examples for tour operator integration and API usage.
  • Document complex booking and tour management features with screenshots.
  • Include proper installation and configuration steps with troubleshooting.
  • Follow markdown linting rules and maintain consistent formatting.
  • On Pull Requests check for updates to the changelog file.
  • Ensure documentation covers accessibility features and requirements.
  • Include developer documentation for extending the plugin.
  • Document REST API endpoints and integration patterns.

Files:

  • changelog.md
src/**/*.{js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use @wordpress/eslint-plugin for JavaScript linting

Files:

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

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{js,jsx,ts,tsx}: Use useBlockProps() in block edit/save components when applicable
Use the text domain tour-operator for JS i18n calls

Files:

  • src/blocks/sticky-menu/index.js
  • src/blocks/sticky-menu/sticky-menu-editor-extension.js
  • src/blocks/sticky-menu/view.js
**/*.{js,ts}

📄 CodeRabbit inference engine (.github/instructions/javascript-react.instructions.md)

**/*.{js,ts}: Use const or let instead of var for variable declarations
Use default parameters for function arguments where appropriate
Use @wordpress/api-fetch (optionally with addQueryArgs) for REST API requests
Register blocks via registerBlockType using block metadata (imported from block.json), and localize title/description/keywords
Use wp.media for media selection in custom components/utilities when needed
Create and register custom data stores with @wordpress/data (createReduxStore + register), and structure actions/selectors clearly
Initialize frontend interactivity after DOMContentLoaded and implement ARIA attributes for toggles (aria-controls, aria-expanded)
Handle AJAX form submissions with fetch, proper loading states, and user notices; restore UI state in finally
Implement accessibility utilities like focus trapping and polite screen reader announcements for dynamic content

Files:

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

📄 CodeRabbit inference engine (.github/instructions/javascript-react.instructions.md)

**/*.{js,ts,jsx,tsx}: Prefer arrow functions for callbacks and inline handlers
Use object/array destructuring for cleaner code
Use template literals for string interpolation
Use async/await for promise handling with try/catch for errors
Use WordPress i18n APIs (__/_n/sprintf) with a consistent textdomain for all user-facing strings; include translator comments where needed
Use @wordpress/data dispatch/select for interacting with WP data stores (e.g., core/notices, core/editor)

Files:

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

📄 CodeRabbit inference engine (.github/instructions/js-ts.instructions.md)

**/*.{ts,tsx,js,jsx}: Debounce user inputs to prevent excessive processing
Avoid blocking the UI thread (prefer async/non-blocking operations)

Files:

  • src/blocks/sticky-menu/index.js
  • src/blocks/sticky-menu/sticky-menu-editor-extension.js
  • src/blocks/sticky-menu/view.js
**/*.{js,mjs,ts,tsx}

📄 CodeRabbit inference engine (.github/instructions/performance.instructions.md)

Defer non-critical JavaScript and avoid synchronous blocking operations

Files:

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

📄 CodeRabbit inference engine (.github/instructions/reviews.instructions.md)

Minimize CSS/JS payload size

Files:

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

📄 CodeRabbit inference engine (.github/instructions/reviews.instructions.md)

Lazy-load code and resources where possible

Files:

  • src/blocks/sticky-menu/index.js
  • src/blocks/sticky-menu/sticky-menu-editor-extension.js
  • src/blocks/sticky-menu/view.js
**/*.{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/index.js
  • src/blocks/sticky-menu/sticky-menu-editor-extension.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/index.js
  • src/blocks/sticky-menu/sticky-menu-editor-extension.js
  • src/blocks/sticky-menu/view.js
🧬 Code graph analysis (3)
src/blocks/sticky-menu/render.php (4)
src/blocks/sticky-menu/sticky-menu-editor-extension.js (1)
  • attributes (140-140)
build/blocks/sticky-menu/sticky-menu-editor-extension.js (1)
  • attributes (297-301)
src/blocks/sticky-menu/view.js (6)
  • section_id (424-424)
  • section_id (437-437)
  • section_id (445-445)
  • section_title (425-425)
  • section_title (469-469)
  • section_title (561-563)
build/blocks/sticky-menu/view.js (6)
  • section_id (397-397)
  • section_id (409-409)
  • section_id (417-417)
  • section_title (398-398)
  • section_title (440-440)
  • section_title (531-531)
src/blocks/sticky-menu/index.js (2)
src/blocks/sticky-menu/sticky-menu-editor-extension.js (1)
  • attributes (140-140)
build/blocks/sticky-menu/sticky-menu-editor-extension.js (1)
  • attributes (297-301)
src/blocks/sticky-menu/sticky-menu-editor-extension.js (1)
build/blocks/sticky-menu/sticky-menu-editor-extension.js (4)
  • withStickyMenuControls (206-287)
  • attributes (297-301)
  • existingClass (312-312)
  • withStickyMenuEditor (322-380)
🪛 Biome (2.1.2)
src/blocks/sticky-menu/view.js

[error] 195-195: 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 (1)
changelog.md (1)

18-18: Changelog entry looks good.

Entry is clear and references the PR. No changes needed.

@github-project-automation github-project-automation bot moved this from 🔎 In Review to Needs Triage in Tour Operator Oct 28, 2025
…lean up all related fields upon removing the sticky menu from the page

- Updated CSS class names in style files to use a consistent prefix (`lsx-to-`) for sticky menu elements.
@github-actions github-actions bot added status:needs-review Awaiting code review and removed status:needs-review Awaiting code review labels Oct 28, 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 0afcb23 and 77a4f44 commits.
Files selected (10)
  • build/blocks/sticky-menu/index.js (1)
  • build/blocks/sticky-menu/sticky-menu-editor-extension.js (1)
  • build/blocks/sticky-menu/style-index-rtl.css (1)
  • build/blocks/sticky-menu/style-index.css (1)
  • build/blocks/sticky-menu/view.js (1)
  • src/blocks/sticky-menu/index.js (1)
  • src/blocks/sticky-menu/render.php (1)
  • src/blocks/sticky-menu/sticky-menu-editor-extension.js (1)
  • src/blocks/sticky-menu/style.scss (1)
  • src/blocks/sticky-menu/view.js (1)
Files not summarized due to errors (10)
  • build/blocks/sticky-menu/index.js (diff tokens exceeds limit)
  • build/blocks/sticky-menu/sticky-menu-editor-extension.js (diff tokens exceeds limit)
  • build/blocks/sticky-menu/view.js (diff tokens exceeds limit)
  • src/blocks/sticky-menu/sticky-menu-editor-extension.js (diff tokens exceeds limit)
  • src/blocks/sticky-menu/view.js (diff tokens exceeds limit)
  • src/blocks/sticky-menu/style.scss (nothing obtained from openai)
  • src/blocks/sticky-menu/index.js (nothing obtained from openai)
  • src/blocks/sticky-menu/render.php (nothing obtained from openai)
  • build/blocks/sticky-menu/style-index.css (nothing obtained from openai)
  • build/blocks/sticky-menu/style-index-rtl.css (nothing obtained from openai)
Files not reviewed due to errors (6)
  • src/blocks/sticky-menu/index.js (no response)
  • src/blocks/sticky-menu/style.scss (no response)
  • build/blocks/sticky-menu/style-index-rtl.css (no response)
  • src/blocks/sticky-menu/render.php (no response)
  • build/blocks/sticky-menu/style-index.css (no response)
  • src/blocks/sticky-menu/sticky-menu-editor-extension.js (no response)
Files skipped from review due to trivial changes (4)
  • build/blocks/sticky-menu/index.js (diff too large)
  • build/blocks/sticky-menu/sticky-menu-editor-extension.js (diff too large)
  • build/blocks/sticky-menu/view.js (diff too large)
  • src/blocks/sticky-menu/view.js (diff too large)
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: 0

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

111-113: Use semantic anchors and sprintf for i18n in Edit component.

The Edit component still uses javascript:void(0); and .replace() for string interpolation. Use #${item.id} for the href and sprintf from @wordpress/i18n for translator-friendly strings.

Apply this diff:

+import { __, sprintf } from '@wordpress/i18n';
+
 // ... in the Edit component render:
                     <a
                       className="lsx-to-sticky-menu-button"
-                      href="javascript:void(0);"
+                      href={`#${item.id}`}
                       aria-current="false"
-                      aria-label={__('Navigate to %s section', 'tour-operator').replace('%s', item.title)}
+                      aria-label={sprintf(__('Navigate to %s section', 'tour-operator'), item.title)}
                     >
src/blocks/sticky-menu/view.js (2)

216-223: Wrap switch case variable in block scope.

The const is_expanded declaration at line 219 within the case 'Escape': can be accessed by other switch cases. Static analysis correctly flags this as an error.

Apply this diff:

             case 'Enter':
             case ' ':
                 event.preventDefault();
                 lsx_to.toggle_mobile_section(wrapper);
                 break;
-            case 'Escape':
+            case 'Escape': {
                 event.preventDefault();
                 // Always collapse on Escape if expanded
                 const is_expanded = wrapper.getAttribute('aria-expanded') === 'true';
                 if (is_expanded) {
                     lsx_to.toggle_mobile_section(wrapper);
                 }
                 break;
+            }
         }

467-468: Remove incorrect role='tab' that conflicts with accordion pattern.

Lines 467-468 add role='tab' to buttons, but the component implements an accordion pattern (with aria-expanded, aria-controls, and role='region' in render.php). This creates a conflicting ARIA pattern that confuses assistive technologies. Remove the role='tab' attribute.

Apply this diff:

             // 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');
+            // Add aria-current for active state
             button.setAttribute('aria-current', 'false');
🧹 Nitpick comments (1)
src/blocks/sticky-menu/style.scss (1)

22-24: Convert pixel value to rem for admin bar offset.

Line 23 uses 32px for the admin bar top offset. Per coding guidelines, convert values ≥3px to rem.

Apply this diff:

 .admin-bar .lsx-to-sticky-menu {
-	top: 32px;
+	top: 2rem;
 }
📜 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 a8d220d and e186434.

⛔ Files ignored due to path filters (8)
  • 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/sticky-menu-editor-extension.asset.php is excluded by !build/**
  • build/blocks/sticky-menu/sticky-menu-editor-extension.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 (4)
  • src/blocks/sticky-menu/index.js (1 hunks)
  • src/blocks/sticky-menu/sticky-menu-editor-extension.js (1 hunks)
  • src/blocks/sticky-menu/style.scss (1 hunks)
  • src/blocks/sticky-menu/view.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/blocks/sticky-menu/sticky-menu-editor-extension.js
🧰 Additional context used
📓 Path-based instructions (14)
src/**/*.{css,scss}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Avoid ad‑hoc CSS; prefer theme.json + block selectors

Files:

  • src/blocks/sticky-menu/style.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
**/*.{css,scss}

📄 CodeRabbit inference engine (.github/instructions/accessibility.instructions.md)

Respect prefers-reduced-motion for animations

Provide mobile‑first responsive behavior

Prefer CSS utilities/presets over custom CSS to reduce CSS size and specificity

Use theme.json design tokens (var(--wp--...)) instead of hard‑coded styles in stylesheets

Files:

  • src/blocks/sticky-menu/style.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
{assets,src}/**/*

📄 CodeRabbit inference engine (.github/instructions/block-theme-structure.instructions.md)

Keep SCSS/JS/images source assets in assets/ or src/

Files:

  • src/blocks/sticky-menu/style.scss
  • src/blocks/sticky-menu/view.js
  • src/blocks/sticky-menu/index.js
src/**/*.{js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use @wordpress/eslint-plugin for JavaScript linting

Files:

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

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{js,jsx,ts,tsx}: Use useBlockProps() in block edit/save components when applicable
Use the text domain tour-operator for JS i18n calls

Files:

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

📄 CodeRabbit inference engine (.github/instructions/javascript-react.instructions.md)

**/*.{js,ts}: Use const or let instead of var for variable declarations
Use default parameters for function arguments where appropriate
Use @wordpress/api-fetch (optionally with addQueryArgs) for REST API requests
Register blocks via registerBlockType using block metadata (imported from block.json), and localize title/description/keywords
Use wp.media for media selection in custom components/utilities when needed
Create and register custom data stores with @wordpress/data (createReduxStore + register), and structure actions/selectors clearly
Initialize frontend interactivity after DOMContentLoaded and implement ARIA attributes for toggles (aria-controls, aria-expanded)
Handle AJAX form submissions with fetch, proper loading states, and user notices; restore UI state in finally
Implement accessibility utilities like focus trapping and polite screen reader announcements for dynamic content

Files:

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

📄 CodeRabbit inference engine (.github/instructions/javascript-react.instructions.md)

**/*.{js,ts,jsx,tsx}: Prefer arrow functions for callbacks and inline handlers
Use object/array destructuring for cleaner code
Use template literals for string interpolation
Use async/await for promise handling with try/catch for errors
Use WordPress i18n APIs (__/_n/sprintf) with a consistent textdomain for all user-facing strings; include translator comments where needed
Use @wordpress/data dispatch/select for interacting with WP data stores (e.g., core/notices, core/editor)

Files:

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

📄 CodeRabbit inference engine (.github/instructions/js-ts.instructions.md)

**/*.{ts,tsx,js,jsx}: Debounce user inputs to prevent excessive processing
Avoid blocking the UI thread (prefer async/non-blocking operations)

Files:

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

📄 CodeRabbit inference engine (.github/instructions/performance.instructions.md)

Defer non-critical JavaScript and avoid synchronous blocking operations

Files:

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

📄 CodeRabbit inference engine (.github/instructions/review.instructions.md)

Internationalize user‑facing strings using WordPress i18n APIs

Files:

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

📄 CodeRabbit inference engine (.github/instructions/reviews.instructions.md)

Minimize CSS/JS payload size

Files:

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

📄 CodeRabbit inference engine (.github/instructions/reviews.instructions.md)

Lazy-load code and resources where possible

Files:

  • src/blocks/sticky-menu/view.js
  • src/blocks/sticky-menu/index.js
**/*.{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/sticky-menu/index.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
  • src/blocks/sticky-menu/index.js
🧬 Code graph analysis (2)
src/blocks/sticky-menu/view.js (1)
build/blocks/sticky-menu/view.js (37)
  • section_id (433-433)
  • section_id (445-445)
  • section_id (453-453)
  • section (55-55)
  • section (267-267)
  • section (574-574)
  • top (58-58)
  • prefersReducedMotion (64-64)
  • originalTabIndex (82-82)
  • sticky_menu (168-168)
  • button (431-431)
  • sections (251-251)
  • sections (332-332)
  • sections (399-399)
  • sections (471-471)
  • sections (509-509)
  • sections (602-602)
  • offset (255-255)
  • offset (337-337)
  • adminBar (256-256)
  • adminBar (338-338)
  • masthead (257-257)
  • masthead (339-339)
  • stickyMenu (258-258)
  • stickyMenu (340-340)
  • i (266-266)
  • offsetPercentage (346-346)
  • observer_options (347-351)
  • sectionId (358-358)
  • sectionId (607-607)
  • firstVisibleSection (373-376)
  • menu_items (423-423)
  • section_title (434-434)
  • section_title (478-478)
  • section_title (575-575)
  • sticky_menu_block (596-596)
  • correspondingSection (608-608)
src/blocks/sticky-menu/index.js (4)
src/blocks/sticky-menu/sticky-menu-editor-extension.js (3)
  • attributes (258-258)
  • sectionId (261-261)
  • sectionTitle (262-262)
build/blocks/sticky-menu/sticky-menu-editor-extension.js (3)
  • attributes (456-460)
  • sectionId (463-463)
  • sectionTitle (464-464)
src/blocks/sticky-menu/view.js (2)
  • sectionId (381-381)
  • sectionId (639-639)
build/blocks/sticky-menu/view.js (2)
  • sectionId (358-358)
  • sectionId (607-607)
🪛 Biome (2.1.2)
src/blocks/sticky-menu/view.js

[error] 219-219: 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

@github-actions github-actions bot added status:needs-review Awaiting code review and removed status:needs-review Awaiting code review labels Oct 30, 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 e186434 and 5fc2272 commits.
Files selected (1)
  • src/blocks/sticky-menu/sticky-menu-editor-extension.js (1)
Files not summarized due to errors (1)
  • src/blocks/sticky-menu/sticky-menu-editor-extension.js (diff tokens exceeds limit)
Files not reviewed due to errors (1)
  • src/blocks/sticky-menu/sticky-menu-editor-extension.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.

@krugazul krugazul self-requested a review October 30, 2025 10:40
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 reviewed it again, thanks for the changes. I did add in some code to autoset the "anchor" when you enabled the sticky menu section.

@krugazul krugazul merged commit ec7c129 into 2.1-trunk Oct 30, 2025
6 of 9 checks passed
@krugazul krugazul deleted the feature/496-sticky-secondary-nav-menu branch October 30, 2025 10:43
@github-project-automation github-project-automation bot moved this from Needs Triage to ✅ Done in Tour Operator Oct 30, 2025
@github-actions github-actions bot added status:needs-review Awaiting code review and removed status:needs-review Awaiting code review labels Oct 30, 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:md Markdown content/docs 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.

Sticky Secondary Navigation on Single Pages

2 participants