Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/gwenholford/iw-megamenu/archive/refs/heads/main.zipA powerful, accessible, and Elementor-optimized Mega Menu plugin with multi-level navigation and widget support. Developed for Austin Community College - Instructional Web Projects.
Version
2.0.0
Features
- Fully Responsive Navigation: Optimized for Desktop, Tablet, and Mobile devices with dynamic viewport height support (
100dvh). - WCAG 2.2 Level AA Accessibility:
- Semantic DOM tree colocating dropdown menus within parent list items for natural keyboard Tab order.
- Complete keyboard navigation support (
Tab,Shift+Tab,Escapeto close & return focus). - Accessible modal dialog drawer with focus trap on mobile.
- Screen reader announcements (
aria-expanded,aria-controls,aria-haspopup,aria-hiddenon icons). - High-contrast
:focus-visiblefocus indicators without suppressing default browser accessibility.
- Multi-Level Navigation: Supports up to 3 hierarchical levels (Top-Level, Second-Level categories/accordions, Third-Level sub-links).
- Elementor Integration:
- Built natively for modern Elementor 3.x using
elementor/widgets/register. - Conditional asset enqueuing via
get_script_depends()andget_style_depends()for Core Web Vitals optimization. - Cached Elementor template queries for fast editor and admin load times.
- Built natively for modern Elementor 3.x using
- Customizable Brand Styling:
- Full control over typography, colors, borders, paddings, and item gaps.
- Built-in ACC brand color presets for icons and badges (
Purple,Teal,Blue,Lime,Yellow,Orange,Red, etc.). - Sidebar template embedding for rich content callouts, forms, and contact cards.
- Dedicated WordPress Builder with nested menu editing and a side-by-side live preview.
- Reusable saved menus stored as
iw_mega_menurecords and selectable from Elementor. - REST API and JSON import/export for menu persistence, backups, and WordPress menu imports.
Menu Structure
Menus nest three levels:
| Level | Role | Supports |
|---|---|---|
| Top | Sits on the nav bar. Links directly if given a URL, or opens a dropdown if it has Sections. | Label, URL, description, icon, badge, sidebar template |
| Section | Fills a Top item's dropdown. Either a single link, or an expandable accordion of Links. | Label, URL, description, icon, badge, accordion toggle |
| Link | Nests inside a Section. | Label, URL, badge |
Important: nested Links require an Accordion
A Section renders its nested Links on desktop only when "Show nested links" is set to Yes (the is_accordion flag). A Section left as a single link displays its own label/icon/description, and any Links nested under it are not shown on desktop — though they do still appear in the mobile drawer.
The Builder handles this for you: adding a Link to a Section turns "Show nested links" on automatically, and any pre-existing Section with hidden Links is flagged with an "N hidden" warning in the tree and an explanation in its editor.
Layout limits
- Sections (non-accordion): up to 4 per column, 2 columns
- Links inside an accordion: up to 2 per column, 3 columns
Items beyond these counts are not rendered.
Installation
- Download or clone this repository to your local machine.
- Upload the
iw-megamenufolder to your WordPress site'swp-content/plugins/directory. - Activate the plugin through the WordPress admin dashboard (
Plugins > Installed Plugins). - Ensure Elementor (v3.5.0 or later recommended) is installed and activated.
Updating an existing install
The folder name is the plugin's identity. WordPress keys every plugin on
folder-name/main-file.php. This plugin must live in a folder named exactlyiw-megamenu, so its basename isiw-megamenu/iw-megamenu.php.
A GitHub "Download ZIP" produces a folder named iw-megamenu-main (or -<branch> / -<commit>). Uploading that as-is installs a second, separate plugin rather than updating the existing one — it appears as a duplicate row in the Plugins list with a different version, and the original stays active.
To package a release correctly:
# From the parent directory of the repo, not inside it
zip -r iw-megamenu.zip iw-megamenu \
-x "iw-megamenu/.git/*" "iw-megamenu/.github/*" "iw-megamenu/.claude/*" \
"iw-megamenu/.gitignore" "*/.DS_Store"
Verify the zip's top-level folder before uploading — it must be iw-megamenu/:
unzip -l iw-megamenu.zip | head -5
Then either upload that zip (WordPress 5.5+ detects the matching folder and offers Replace current with uploaded), or replace the folder's contents in place over SFTP. Both preserve the plugin's activation state and all saved Elementor widget settings.
Never activate two copies at once. They declare the same classes; the bootstrap now bails out early if a second copy loads, but the duplicate should be deleted rather than relied on.
Usage — Builder (recommended)
- Go to IW Mega Menu in the WordPress admin sidebar.
- Click + New, name the menu, and click Create.
- Click + Add Top-Level Item to add a nav bar item. Click any row to open its editor.
- Expand a row with the chevron, then use + Add Section / + Add Link to nest items beneath it.
- In an item's editor, set the Label, Link URL, Description, Badge, and Icon. Click Browse beside the Icon field to pick from the built-in icon set, or type any Font Awesome class directly.
- Watch the right-hand live preview — it opens to whatever you're editing and matches how the item will render on the site.
- Click Save Menu, then drop the IW Mega Menu widget onto an Elementor page/header and select your saved menu.
Migrating a legacy widget to the Builder
Menus built before v2.0.0 live inside the Elementor widget itself (the Legacy Repeater), not as a reusable saved menu. To convert one:
- Open IW Mega Menu in the admin and create a new menu (+ New).
- Click Import Legacy Widget. The dropdown lists every Elementor page/template that still has an IW Mega Menu widget with repeater items, showing the item count and the first few labels so you can tell them apart.
- Pick one and click Import. The flat
parent_idstructure is rebuilt as a proper three-level tree. - Review it in the live preview, then Save Menu.
- Edit the original page/template in Elementor, set Menu Source to Saved Menu (Builder), and select your new menu.
The import only reads — the original widget is left untouched, so you can import, compare, and roll back by simply not changing the widget's Menu Source.
Two things the importer normalises rather than copying verbatim:
- Sections that have links are switched to accordion. Nested links only render on desktop inside an accordion (see Menu Structure above), so importing them any other way would silently hide them.
- Items are never duplicated. The legacy renderer also pushed any item with
parent_idof0into the top level even when it was already nested under a parent, so such an item appeared twice. The importer nests it once, under its parent.
Because of these, compare the preview against the live menu before switching a production page over.
Exporting
Export downloads the current builder menu as JSON — useful for backups or moving a menu between sites (pair it with Import JSON on the destination). It exports saved builder menus only; to get a legacy widget's items out, import it first using the steps above, then export.
Usage — Elementor widget
- In the WordPress admin, edit a page or Header Template with Elementor.
- Search for IW Mega Menu in the Elementor widget panel and drag it into your layout.
- In the Menu Structure section, add your menu items:
- Top-Level: Primary navigation triggers.
- Second-Level: Categories or Accordion headers. Can include an optional description and icon.
- Third-Level: Sub-links within categories or accordions.
- (Optional) Assign an Elementor template to display as a sidebar card for desktop mega menu dropdowns and mobile drawers.
- Customize colors, typography, borders, and spacing in the Style tab.
- Publish or save your template.
Changelog
v2.0.0 (Current Release)
- Added the dedicated IW Mega Menu Builder admin dashboard.
- Added reusable saved menus with Elementor widget selection and legacy repeater fallback.
- Added REST CRUD endpoints, Elementor template lookup, WordPress menu import, and JSON import/export.
Accordion header layout
- Removed the dead vertical space in accordion headers. The toggle was
flex-direction: column, which stacked the caret as a third row below the label (align-self: flex-endonly pushed it right). It is now a wrapping row: label and caret share the first line with the caret vertically centered at the right, and the optional description wraps onto a full-width second line — so the header is compact whether or not a description is set. - Caret and description now inherit the toggle's own text color instead of being hardcoded, so both stay legible in the collapsed (dark-on-grey) and expanded (white-on-purple) states. This also fixed a latent contrast bug where an accordion description rendered
#333on the purple expanded background. - The caret keeps a consistent
fa-regularweight in both states and flips direction only; it previously switched tofa-solidwhen open, which rendered as a heavy filled block rather than a caret.
Color fidelity fixes
- Per-item icon colors now survive the widget's global "Icon Color" control. That control emits a rule targeting
.iw-mega-menu__icon idirectly, while theicon-acc-*classes set color on the parent<span>— and a direct rule on a child always beats a color inherited from its parent,!importantor not. The palette classes now also target the nestedi/svg, so each item's chosen accent color wins. - The Builder preview no longer invents its own colors. It was hand-rolling a second copy of the menu styles that had drifted from the real ones (badges rendered gold instead of brand purple, section labels near-black instead of
#5a3fa0, third-level links WordPress blue, accordion toggles with no background). The admin stylesheet now scales sizing/spacing only and defers every color toassets/css/iw-megamenu.css, which is already enqueued on that page. - Tree-row badge indicators recolored to match the real purple badge.
Builder usability & rendering fixes
- Top-level items now render their icon and description. Previously both fields were editable but silently discarded for Top-level items on the frontend, in the Elementor editor preview, and in the Builder preview. Top-level icons and descriptions now render in all three, forced to white/translucent-white so they stay legible on the nav bar.
- Nested Links no longer disappear silently. Links added to a Section only render on desktop when the Section is set to show nested links. Adding a Link now enables that automatically, and Sections with hidden Links are flagged with an "N hidden" warning plus an explanation in the editor.
- Added a searchable icon picker with ~60 curated Font Awesome icons, a live color-accurate preview, and a Remove button — typing raw
fas fa-starclasses is now optional rather than required. - Icon and Description fields are hidden for third-level Links, which the frontend renders as label + badge only.
- Rows show at-a-glance indicators for icon, description, and URL, plus a warning on items missing a label.
- Click any row to open its editor; expand/collapse moved to a leading chevron and is hidden on items that cannot have children (this also removed a stray empty grey box under expanded third-level Links).
- The live preview now opens to whatever is being edited and keeps its open dropdown/accordion while you type.
- Replaced cryptic glyph buttons with labelled/
aria-labeled Dashicons, added drag-to-reorder, duplicate, expand/collapse all, per-level empty-state guidance, and an unsaved-changes warning. - Replaced browser
prompt()dialogs for creating menus and importing WordPress menus with inline forms.
v1.1.0
Major Accessibility & Architecture Modernization
- Full WAI-ARIA APG & WCAG 2.2 AA Compliance:
- Colocated mega menu dropdowns inside parent
<li>items, correcting DOM tab order so keyboard users can seamlessly navigate into submenus. - Added
Escapekey handler to dismiss open dropdowns and return focus to the trigger button. - Added accessible focus trapping inside the mobile navigation drawer.
- Removed all
outline: none !important;overrides and introduced high-contrast:focus-visiblestyling. - Non-linked category headers now render as semantic headings (
role="heading" aria-level="3") instead of empty<a href="">tags. - Carets and decorative icons are marked with
aria-hidden="true".
- Colocated mega menu dropdowns inside parent
- Modernized Elementor Asset Pipeline:
- Migrated widget registration to the modern
elementor/widgets/registerhook andregister_controls()API. - Extracted all frontend JavaScript from inline `
- Migrated widget registration to the modern