Satisfaction overview
(68 verified reviews)
Trusted by homeowners, strata communities, and businesses.
Impeccable safety record
/*prevent FOUC on mobile when using sidebar */
.dwc-mobile :is(.bricks-is-frontend.brx-header-left, .bricks-is-frontend.brx-header-right) #brx-header {
position: relative;
inline-size: 100%;
flex-direction: column;
}
.dwc-mobile .bricks-is-frontend:is(.brx-header-left, .brx-header-right) :is(#brx-content, #brx-footer) {
margin-inline-start: 0;
}
/*prevent FOUC on desktop when using sidebar */
.bricks-is-frontend:is(.brx-header-left, .brx-header-right):not(.show-nav) .dwc-nav-wrapper {
display: none;
}
/*=== sidebar css ===*/
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header {
flex-direction: column;
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.7);
}
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]).no-scroll {
overflow: visible;
}
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu.brxe-nav-nested .brx-nav-nested-items {
max-block-size: 100dvb;
padding-block-end: 12rem;
overscroll-behavior: contain;
}
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nav-wrapper {
position: relative;
overflow: hidden;
block-size: 100%;
transform: translateX(0%);
visibility: visible;
}
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) .dwc-nest-menu .brxe-toggle {
display: none !important;
}
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu {
display: flex;
flex-direction: column;
}
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-header > div {
display: flex;
grid-template-columns: 1fr;
block-size: 100%;
flex-direction: column;
justify-content: flex-start;
}
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-menu-wrap {
inline-size: 100%;
display: grid;
grid-template-columns: 1fr;
block-size: 100%;
}
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header :is(.brxe-code, .dwc-nest-menu-overlay) {
display: none;
}
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-header {
inline-size: 100%;
padding-inline: 0;
}
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu-top {
min-block-size: var(--top-offset);
}
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu:not( [data-hide-close-bar = 'true']) .brx-dropdown-content {
inset-block-start: calc(var(--top-offset) + 1px) !important;
}
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu:not( [data-submenu-reveal = 'slide']) .brx-dropdown-content:not([data-submenu-reveal = 'slide'] *) {
inset-inline-start: 0;
inset-block-start: unset !important;
overflow: hidden;
}
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu:not([data-submenu-reveal = 'slide']) .brxe-dropdown:not(.open.active) > .brx-dropdown-content > .brxe-dropdown:not([data-submenu-reveal = 'slide'] *){
visibility: hidden;
}
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu.brxe-nav-nested.brx-open .brxe-dropdown > .brx-dropdown-content {
overscroll-behavior: contain;
min-inline-size: var(--mobile-menu-width);
}
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu .brxe-dropdown.open > .brx-submenu-toggle button:not([data-submenu-reveal = 'expand'] button) {
min-block-size: calc(var(--top-offset) - 1px);
inset-block-start: 0;
}
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu .brxe-dropdown.open[data-submenu-reveal = 'slide'] > .brx-submenu-toggle button {
min-block-size: calc(var(--top-offset) - 1px);
inset-block-start: 0;
}
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu .brxe-dropdown .brx-submenu-toggle button {
min-block-size: 0;
}
/* sidebar css ends*/
/*sidebar in builder*/
/*=== sidebar css ===*/
:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header {
flex-direction: column;
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.7);
--top-offset: 40px;
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-menu.brxe-nav-nested .brx-nav-nested-items {
max-block-size: 100dvb;
padding-block-end: 12rem;
overscroll-behavior: contain;
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nav-wrapper {
position: relative;
overflow: hidden;
block-size: 100%;
transform: translateX(0%);
visibility: visible;
}
body:is(.brx-header-left, .brx-header-right)[data-builder-window] .dwc-nest-menu .brxe-toggle {
display: none !important;
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-menu {
display: flex;
flex-direction: column;
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-header > div {
display: flex;
grid-template-columns: 1fr;
block-size: 100%;
flex-direction: column;
justify-content: flex-start;
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-menu-wrap {
inline-size: 100%;
display: grid;
grid-template-columns: 1fr;
block-size: 100%;
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-header {
inline-size: 100%;
padding-inline: 0;
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-menu-top {
min-block-size: var(--top-offset);
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-menu .brx-dropdown-content {
inset-block-start: calc(var(--top-offset) - 1px) !important;
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-menu.brxe-nav-nested.brx-open .brxe-dropdown > .brx-dropdown-content {
overscroll-behavior: contain;
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-menu .brxe-dropdown.open > .brx-submenu-toggle button {
min-block-size: calc(var(--top-offset) - 1px);
inset-block-start: 0;
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-menu .brxe-dropdown .brx-submenu-toggle button {
min-block-size: 0;
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] .dwc-nest-menu {
margin: 0 !important;
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] .brx-nav-nested-items {
flex-direction: column !important;
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] .dwc-nest-toggle--open.brxe-toggle {
display: flex !important;
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] .dwc-nest-menu .brx-nav-nested-items {
position: relative !Important;
background: var(--mobile-menu-bg) !important;
align-items: stretch;
flex: 1;
}
:where(.brx-header-left, .brx-header-right)[data-builder-mode]:not(:has(.dwc-sidebar)) .dwc-nest-menu-top::before {
content: 'this space is the back text bar';
padding: 1rem;
background-color: gray;
color: white;
width: 100%;
text-transform: uppercase;
font-size: 12px;
font-weight: bold;
letter-spacing: 1px;
}
/* MENU CTA (LAST BUTTON) */
:is(.brx-header-left, .brx-header-right)[data-builder-window] [data-last-item-is-button="true"].dwc-nest-menu .brx-nav-nested-items > .menu-item:last-of-type {
padding-inline: var(--menu-item-inline-padding) !important;
padding-block: var(--menu-item-block-padding) !important;
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] .dwc-nest-menu-top {
min-block-size: 80px !important;
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] .dwc-nest-nav-items {
overflow-y: scroll;
}
:is(.brx-header-left, .brx-header-right)[data-builder-mode] .brx-dropdown-content {
min-inline-size: var(--mobile-menu-width);
position: static;
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-menu.brxe-nav-nested .brx-nav-nested-items {
flex-wrap: nowrap;
}
:is(.brx-header-left, .brx-header-right)[data-builder-window] #brx-header .dwc-nest-menu .brx-dropdown-content {
visibility: visible !important;
opacity: 1;
}
/*OVERLAY SIDEBAR*/
html:not(.dwc-mobile):has([data-overlay-sidebar=true]) {
--mobile-menu-bg: rgb(255 255 255 / 0%);
--menu-item-border: solid 1px rgb(255 255 255 / 50%);
}
html:not(.dwc-mobile):has([data-overlay-sidebar=true]) :is(.brx-header-left, .brx-header-right):not([data-builder-modee]) :is(main, footer){
margin: 0 !important
}
html:not(.dwc-mobile):has([data-overlay-sidebar=true]) :is(.brx-header-left, .brx-header-right):not([data-builder-modee]) :is(main, footer) :where(section):not(section>section) {
padding-inline-start: calc(var(--mobile-menu-width) + clamp(1.5rem, calc(0.625vw + 1.375rem), 1.875rem));
max-inline-size: 100%
}
html:not(.dwc-mobile):has([data-overlay-sidebar=true]) :is(.brx-header-left, .brx-header-right):not([data-builder-modee]) #brx-header {
border-radius: var(--overlay-sidebar-radius);
overflow: hidden;
background: var(--overlay-sidebar-bg);
box-shadow: var(--overlay-sidebar-shadow) !important;
inset: var(--overlay-sidebar-inset);
}
html:not(.dwc-mobile):has([data-overlay-sidebar=true]) :is(.brx-header-left, .brx-header-right):not([data-builder-modee]) .dwc-nest-header{
backdrop-filter: blur(13px);
background: transparent !important;
}
html:not(.dwc-mobile):has([data-overlay-sidebar=true]):not([data-builder-modee]) .brx-dropdown-content {
background-color: rgb(255 255 255 / 100%);
}
/*NO BRX-OPEN STYLES*/
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) #brx-header .dwc-nest-menu.brxe-nav-nested .brx-nav-nested-items {
display: flex;
flex-wrap: nowrap;
flex-direction: column !important;
}
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) .dwc-nest-menu.brxe-nav-nested .brxe-dropdown .brx-dropdown-content {
visibility: visible;
min-inline-size: var(--mobile-menu-width) !important;
}
html:not(.dwc-mobile) :is(.brx-header-left, .brx-header-right):not([data-builder-window]) .dwc-nest-menu[data-submenu-reveal="expand"] .brxe-dropdown.open>.brx-dropdown-content {
position: static;
}
class SidebarNavigation {
constructor(options = {}) {
// Basic configuration properties
this.config = {
minWidth: options.minWidth || MegaMenuCONFIG.minWidth, // Using external minWidth variable
menuSelector: options.menuSelector || '.dwc-nest-menu',
openClass: options.openClass || 'brx-open',
activeClasses: options.activeClasses || ['open', 'active'],
leftHeaderClass: options.leftHeaderClass || 'brx-header-left',
rightHeaderClass: options.rightHeaderClass || 'brx-header-right',
debounceDelay: options.debounceDelay || 100,
menuItemClickDelay: options.menuItemClickDelay || 300
};
// Set dependent selectors
const menuSelector = this.config.menuSelector;
this.config.submenuToggleSelector = options.submenuToggleSelector || `${menuSelector} .brx-submenu-toggle`;
this.config.dropdownSelector = options.dropdownSelector || `${menuSelector} .brxe-dropdown`;
this.config.dropdownContentSelector = options.dropdownContentSelector || `${menuSelector} .brx-dropdown-content`;
// State
this.previousHeaderClass = null;
this.dropdownClickHandlers = new Map();
this.menuHoverHandlers = null;
this.menuItemClickTimeout = null;
this.keyboardNavHandler = null;
this.cachedFocusableElements = null;
this.cachedElements = {
menuElement: null,
navElement: null,
dropdowns: null,
dropdownToggles: null,
menuItems: null
};
// Bind methods to this instance
this.handleResize = this.debounce(this.handleMenu.bind(this), this.config.debounceDelay);
this.handleOutsideClick = this.handleOutsideClick.bind(this);
}
// Initialize everything - called once
init() {
// Wait for DOM to be fully loaded before attaching events
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => {
this.initAfterDOMLoaded();
}, { once: true });
} else {
this.initAfterDOMLoaded();
}
return this;
}
// Separate initialization method to run after DOM is loaded
initAfterDOMLoaded() {
// Cache DOM elements once
this.cacheElements();
// Setup resize event with passive flag
window.addEventListener('resize', this.handleResize, { passive: true });
// Setup mutation observer for critical class changes only
this.setupMutationObserver();
// Initial setup based on current screen size
this.handleMenu();
// Cache focusable elements once if header class is present
if (this.hasHeaderClass()) {
this.cacheFocusableElements();
this.setupMenuFocusNavigation();
}
}
// Cache all required DOM elements upfront
cacheElements() {
this.cachedElements.menuElement = document.querySelector(this.config.menuSelector);
if (this.cachedElements.menuElement) {
this.cachedElements.navElement = this.cachedElements.menuElement.querySelector('.dwc-nest-nav-items');
this.cachedElements.dropdowns = Array.from(document.querySelectorAll(this.config.dropdownSelector));
this.cachedElements.dropdownToggles = Array.from(document.querySelectorAll(this.config.submenuToggleSelector));
this.cachedElements.menuItems = Array.from(document.querySelectorAll(`${this.config.menuSelector} .menu-item`));
}
}
// Set up a focused mutation observer only for dropdown state changes
setupMutationObserver() {
if (!this.cachedElements.dropdowns || this.cachedElements.dropdowns.length === 0) return;
const callback = (mutations) => {
for (let mutation of mutations) {
if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
const target = mutation.target;
const prevClassList = mutation.oldValue ? mutation.oldValue.split(' ') : [];
const hadBothBefore = prevClassList.includes('open') && prevClassList.includes('active');
const hasBothNow = target.classList.contains('open') && target.classList.contains('active');
if (hadBothBefore !== hasBothNow) {
this.updateDropdownAccessibility();
break; // Only need to update once per batch
}
}
}
};
// Create observer with optimized options
this.classObserver = new MutationObserver(callback);
// Observe only the dropdown elements
this.cachedElements.dropdowns.forEach(dropdown => {
this.classObserver.observe(dropdown, {
attributes: true,
attributeFilter: ['class'],
attributeOldValue: true
});
});
}
// Cache focusable elements for keyboard navigation
cacheFocusableElements() {
if (!this.cachedElements.navElement) return;
// Get direct children of nav
const directChildren = Array.from(this.cachedElements.navElement.children);
// Find the first focusable element within each direct child
this.cachedFocusableElements = directChildren.map(child => {
// Check if the child itself is focusable
if (child.matches('a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])')) {
return child;
}
// Otherwise, find the first focusable element within this child
return child.querySelector('a, button, input, select, textarea, [tabindex]:not([tabindex="-1"])');
}).filter(Boolean); // Remove null/undefined values
}
// Clean up all event listeners and observers
destroy() {
// Clean up the mutation observer
if (this.classObserver) {
this.classObserver.disconnect();
this.classObserver = null;
}
// Clean up resize listener
window.removeEventListener('resize', this.handleResize);
// Clean up click handlers
if (this.dropdownClickHandlers.size > 0) {
this.dropdownClickHandlers.forEach((handler, toggle) => {
toggle.removeEventListener('click', handler);
});
this.dropdownClickHandlers.clear();
}
// Clean up hover handlers
this.cleanupMenuHover();
// Clean up menu item click handlers
this.cleanupMenuItemClicks();
// Clean up outside click handler
document.removeEventListener('click', this.handleOutsideClick);
// Clean up keyboard navigation
if (this.keyboardNavHandler) {
document.removeEventListener('keydown', this.keyboardNavHandler);
this.keyboardNavHandler = null;
}
// Clear any pending timeouts
if (this.menuItemClickTimeout) {
clearTimeout(this.menuItemClickTimeout);
this.menuItemClickTimeout = null;
}
}
// Utility methods
hasHeaderClass() {
return document.body.classList.contains(this.config.leftHeaderClass) ||
document.body.classList.contains(this.config.rightHeaderClass);
}
debounce(func, delay) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => func(...args), delay);
};
}
// Check if an element has all the required active classes
hasAllActiveClasses(element) {
return this.config.activeClasses.every(className => element.classList.contains(className));
}
// Toggle all active classes on an element
toggleActiveClasses(element) {
this.config.activeClasses.forEach(className => {
element.classList.toggle(className);
});
}
// Core functionality methods
handleMenu() {
if (!this.cachedElements.menuElement) return;
if (!this.hasHeaderClass() && !this.previousHeaderClass) return;
const screenWidth = window.innerWidth;
const isLargeScreen = screenWidth >= this.config.minWidth;
const menuElement = this.cachedElements.menuElement;
if (!isLargeScreen) {
// Save which class was present before removal
if (this.hasHeaderClass()) {
this.previousHeaderClass = document.body.classList.contains(this.config.leftHeaderClass)
? this.config.leftHeaderClass
: this.config.rightHeaderClass;
// Remove header classes
document.body.classList.remove(this.config.leftHeaderClass, this.config.rightHeaderClass);
menuElement.classList.remove(this.config.openClass);
// Reset accessibility attributes
this.resetAccessibilityAttributes();
}
// Clean up event handlers for mobile view
this.cleanupMenuHover();
this.cleanupMenuItemClicks();
this.cleanupDropdownHandlers();
document.removeEventListener('click', this.handleOutsideClick);
return;
}
// Large screen behavior
if (!this.hasHeaderClass() && this.previousHeaderClass) {
document.body.classList.add(this.previousHeaderClass);
}
if (this.hasHeaderClass()) {
if (!menuElement.classList.contains(this.config.openClass)) {
menuElement.classList.add(this.config.openClass);
}
// Setup elements for large screen view
this.setupMenuHover();
this.setupMenuItemClicks();
this.setupDropdownHandlers();
this.setupMenuFocusNavigation();
this.updateDropdownAccessibility();
// Ensure outside click handler is set up
document.removeEventListener('click', this.handleOutsideClick);
document.addEventListener('click', this.handleOutsideClick, { passive: false });
}
}
// Reset accessibility attributes when switching to mobile
resetAccessibilityAttributes() {
if (!this.cachedElements.dropdowns) return;
// Remove all inert attributes from dropdown contents
this.cachedElements.dropdowns.forEach(dropdown => {
const content = dropdown.querySelector(this.config.dropdownContentSelector);
if (content) {
content.removeAttribute('inert');
}
const button = dropdown.querySelector('button');
if (button) {
button.setAttribute('aria-expanded', 'false');
}
});
}
setupMenuFocusNavigation() {
// Only run if hasHeaderClass() is true and we have focusable elements
if (!this.hasHeaderClass() || !this.cachedFocusableElements || this.cachedFocusableElements.length === 0) {
return;
}
// Clean up previous handler if it exists
if (this.keyboardNavHandler) {
document.removeEventListener('keydown', this.keyboardNavHandler, true);
this.keyboardNavHandler = null;
}
const navMenu = this.cachedElements.menuElement;
const focusableElements = this.cachedFocusableElements;
const firstFocusableElement = focusableElements[0];
const lastFocusableElement = focusableElements[focusableElements.length - 1];
// Find adjacent focusable elements outside the menu (only once during setup)
const headerElement = navMenu.closest('header') || document.querySelector('header');
// Prepare variables to hold adjacent elements
let prevFocusableElement = null;
let nextFocusableElement = null;
let firstElementAfterHeader = null;
if (headerElement) {
// Get all focusable elements within the header - do this once and cache the result
const headerFocusables = Array.from(
headerElement.querySelectorAll('a:not([tabindex="-1"]), button:not([tabindex="-1"]), input:not([tabindex="-1"]), select:not([tabindex="-1"]), textarea:not([tabindex="-1"]), [tabindex]:not([tabindex="-1"])')
).filter(el => window.getComputedStyle(el).display !== 'none');
// Find the index of our first and last menu elements in one pass
const menuStartIndex = headerFocusables.indexOf(firstFocusableElement);
const menuEndIndex = headerFocusables.indexOf(lastFocusableElement);
// Cache the adjacent elements
if (menuStartIndex > 0) {
prevFocusableElement = headerFocusables[menuStartIndex - 1];
}
if (menuEndIndex !== -1 && menuEndIndex < headerFocusables.length - 1) {
nextFocusableElement = headerFocusables[menuEndIndex + 1];
}
// Pre-calculate the first element after header - but only if needed
if (!nextFocusableElement) {
// Use a more efficient selector that targets immediate children of body that aren't the header
const selector = 'body > *:not(header)';
const nonHeaderElements = document.querySelectorAll(selector);
// Only process if we have elements
if (nonHeaderElements.length > 0) {
// Create a function to find the first focusable element (used later if needed)
this.findFirstFocusableAfterHeader = () => {
for (const element of nonHeaderElements) {
const focusable = element.querySelector('a:not([tabindex="-1"]), button:not([tabindex="-1"]), input:not([tabindex="-1"]), select:not([tabindex="-1"]), textarea:not([tabindex="-1"]), [tabindex]:not([tabindex="-1"])');
if (focusable && window.getComputedStyle(focusable).display !== 'none') {
return focusable;
}
}
return null;
};
}
}
}
// Create keyboard navigation handler with closure over the cached elements
this.keyboardNavHandler = (e) => {
// Quick check for Tab key first
if (e.key !== 'Tab') return;
// Then check if focus is inside the menu
if (!navMenu.contains(document.activeElement)) return;
let targetElement = null;
// Handle tab navigation at boundaries only
if (!e.shiftKey && document.activeElement === lastFocusableElement) {
// Forward tab from last element
e.preventDefault();
e.stopPropagation();
if (nextFocusableElement) {
targetElement = nextFocusableElement;
} else if (this.findFirstFocusableAfterHeader) {
// Only search for elements after header if needed and not already found
firstElementAfterHeader = this.findFirstFocusableAfterHeader();
targetElement = firstElementAfterHeader;
}
// Focus on the target or body as fallback
setTimeout(() => {
if (targetElement) {
targetElement.focus();
} else {
document.body.setAttribute('tabindex', '-1');
document.body.focus();
document.body.removeAttribute('tabindex');
}
}, 10);
}
else if (e.shiftKey && document.activeElement === firstFocusableElement) {
// Backward tab from first element
e.preventDefault();
e.stopPropagation();
setTimeout(() => {
if (prevFocusableElement) {
prevFocusableElement.focus();
} else {
document.body.setAttribute('tabindex', '-1');
document.body.focus();
document.body.removeAttribute('tabindex');
}
}, 10);
}
};
// Use capture phase for the event
document.addEventListener('keydown', this.keyboardNavHandler, true);
}
setupMenuHover() {
const menuElement = this.cachedElements.menuElement;
if (!menuElement) return;
// Clean up existing hover handlers first
this.cleanupMenuHover();
// Create event handlers
const mouseenterHandler = () => {
menuElement.classList.add(this.config.openClass);
};
const mouseleaveHandler = () => {
menuElement.classList.remove(this.config.openClass);
};
// Add event listeners with passive flag for better performance
menuElement.addEventListener('mouseenter', mouseenterHandler, { passive: true });
menuElement.addEventListener('mouseleave', mouseleaveHandler, { passive: true });
// Store the handlers for cleanup
this.menuHoverHandlers = {
element: menuElement,
mouseenter: mouseenterHandler,
mouseleave: mouseleaveHandler
};
}
cleanupMenuHover() {
if (this.menuHoverHandlers) {
const { element, mouseenter, mouseleave } = this.menuHoverHandlers;
element.removeEventListener('mouseenter', mouseenter);
element.removeEventListener('mouseleave', mouseleave);
this.menuHoverHandlers = null;
}
}
setupMenuItemClicks() {
if (!this.cachedElements.menuItems || this.cachedElements.menuItems.length === 0) return;
// Clean up existing handlers first
this.cleanupMenuItemClicks();
const menuElement = this.cachedElements.menuElement;
const menuItemHandlers = new Map();
this.cachedElements.menuItems.forEach(item => {
const clickHandler = () => {
if (this.hasHeaderClass()) {
// Clear any existing timeout
if (this.menuItemClickTimeout) {
clearTimeout(this.menuItemClickTimeout);
}
// Set timeout before adding the class
this.menuItemClickTimeout = setTimeout(() => {
if (!menuElement.classList.contains(this.config.openClass)) {
menuElement.classList.add(this.config.openClass);
}
}, this.config.menuItemClickDelay);
}
};
menuItemHandlers.set(item, clickHandler);
item.addEventListener('click', clickHandler);
});
this.menuItemClickHandlers = menuItemHandlers;
}
cleanupMenuItemClicks() {
if (this.menuItemClickHandlers && this.menuItemClickHandlers instanceof Map) {
this.menuItemClickHandlers.forEach((handler, item) => {
item.removeEventListener('click', handler);
});
this.menuItemClickHandlers.clear();
}
if (this.menuItemClickTimeout) {
clearTimeout(this.menuItemClickTimeout);
this.menuItemClickTimeout = null;
}
}
setupDropdownHandlers() {
if (!this.hasHeaderClass() || !this.cachedElements.dropdownToggles) return;
// Clean up existing handlers first
this.cleanupDropdownHandlers();
this.cachedElements.dropdownToggles.forEach(toggle => {
const clickHandler = (event) => {
event.stopPropagation();
event.preventDefault();
const dropdown = toggle.closest(this.config.dropdownSelector);
if (dropdown) {
this.toggleActiveClasses(dropdown);
this.updateDropdownAccessibility();
}
};
this.dropdownClickHandlers.set(toggle, clickHandler);
toggle.addEventListener('click', clickHandler);
});
}
cleanupDropdownHandlers() {
if (this.dropdownClickHandlers.size > 0) {
this.dropdownClickHandlers.forEach((handler, toggle) => {
toggle.removeEventListener('click', handler);
});
this.dropdownClickHandlers.clear();
}
}
handleOutsideClick(event) {
if (event.target.tagName === 'A') return;
if (!event.target.closest(this.config.dropdownSelector)) return;
if (!event.target.closest(this.config.submenuToggleSelector)) {
event.preventDefault();
event.stopPropagation();
}
}
updateDropdownAccessibility() {
// Only run if hasHeaderClass() is true
if (!this.hasHeaderClass() || !this.cachedElements.dropdowns) return;
this.cachedElements.dropdowns.forEach(dropdown => {
const content = dropdown.querySelector(this.config.dropdownContentSelector);
const button = dropdown.querySelector('button');
// Check if dropdown has all active classes
const isOpen = this.hasAllActiveClasses(dropdown);
if (content) {
if (isOpen) {
content.removeAttribute('inert');
} else {
content.setAttribute('inert', '');
}
}
if (button) {
button.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
}
});
}
}
const sidebarNav = new SidebarNavigation().init();Coquitlam construction services
VALROC Development Ltd. delivers hands-on construction services across Coquitlam, BC for homeowners, strata councils, and commercial sites. From hillside driveways and large RV pads to heritage restoration and infrastructure upgrades, we build durable results shaped by real Coquitlam site conditions.
Coquitlam projects often involve clay soils, older infrastructure, and steep elevation changes that demand precise grading, strong sub-base preparation, and proper drainage planning. The services below reflect the work we’ve completed across the city: concrete, asphalt, excavation, drainage, and structural upgrades, delivered with clear communication and reliable sequencing.
Customer confidence
Coquitlam construction planning often starts with grades, soil conditions, drainage, retaining, occupied access, and the equipment needed to work safely and efficiently.
(68 verified reviews)
Trusted by homeowners, strata communities, and businesses.
Impeccable safety record
Slopes, elevation changes, clay soils, drainage routes, and retaining requirements can strongly influence Coquitlam projects. We review these conditions before confirming equipment, access, and sequence.
Customers benefit from one coordinated plan across excavation, drainage, retaining, concrete, asphalt, structures, and the logistics required by the property.
Local construction planning
Construction planning in Coquitlam starts with the property, the municipal jurisdiction, and the practical conditions that affect approvals, access, sequencing, equipment, and material movement.
CONSTRUCTION SERVICE DIRECTORY
Open the complete construction service hub, choose a service category, or go directly to a core service.
Decisions before construction
A site conversation can identify alternatives before costs are committed, particularly where grades, retaining conditions, drainage, shared access, occupied areas, and equipment staging affect the plan.
Review grades, retaining conditions, drainage, shared access, occupied areas, and equipment staging in relation to the result you want and the equipment or material movement the work may require.
Identify likely City building and demolition requirements, utility-locate responses, disposal requirements, and property-specific questions before finalizing the sequence.
Coordinate crews, deliveries, occupied areas, hauling, and site protection so the construction sequence reflects how this Coquitlam property is actually used.
A practical route forward
The exact sequence depends on the work and property. Early review of City of Coquitlam requirements, access, disposal, equipment, and customer priorities helps turn an idea into a coordinated plan.
Identify likely municipal permits, utility locates, disposal needs, technical details, and property-specific approvals.
Coordinate machinery, crews, hauling, materials, protection, and access around elevation changes and active property use.
Complete the agreed sequence, review drainage, grades, retaining or finished surfaces, and provide a clear customer handoff.
Review the intended result, slopes, soil, drainage, retaining, access, occupied areas, and room for equipment and materials.
What customers gain from the way we work
These advantages help customers evaluate more than a price, including project clarity, relevant experience, site coordination, in-house capability, and the way disruption will be managed.
With a strong portfolio of completed work, our experience ensures high-quality craftsmanship and efficient project execution.
Our extensive fleet of heavy-duty machinery, mobile service trucks, and specialized tools ensures unmatched efficiency and precision on every job site.
Our contracts eliminate guesswork with clearly defined terms, pricing, timelines, and warranties, ensuring total transparency and peace of mind.
We respect your time and space, ensuring efficient construction with minimal disruptions to your home or business.
In-house capability
Our Langley yard provides a base for selecting and staging equipment for Coquitlam projects around access, excavation depth, hauling, material movement, compaction, and the actual scope of work.

Excavation fleet
Our in-house range includes compact machines for tight access, mid-size excavators for precise residential work, larger Deere excavators for deeper excavation and material handling, plus hydraulic breaker capability for concrete and rock removal.

Heavy Machinery & Earthmoving Equipment
Delivers smooth, even asphalt and soil compaction, improving surface durability and road longevity.

Mobile Construction Equipped Service Vehicles
Facilitates equipment and material transport, allowing us to move multiple machines and long materials efficiently.

Heavy Machinery & Earthmoving Equipment
A compact, maneuverable track dumper that allows us to transport materials through tight spaces, improving site logistics and reducing manual labour.

Heavy Machinery & Earthmoving Equipment
A high-capacity hauler for transporting materials, debris, and equipment, streamlining job site cleanup and logistics.

Mobile Construction Equipped Service Vehicles
Our fully equipped mobile service truck, essential for transporting contracting tools, materials, and heavy-duty equipment, ensuring on-site readiness and maximum efficiency.

Heavy Machinery & Earthmoving Equipment
A compact excavator with strong digging power, perfect for tight job sites requiring precision excavation.
High-value planning information
Verified municipal, utility, recycling, and disposal contacts for construction decisions in Coquitlam. Use each section for a focused task, then confirm current requirements with the authority before acting.

Check Coquitlam permit requirements, Review official permit and inspection information.
Contact: permits@coquitlam.ca · 604-927-3441
Before you proceed: Confirm the application type and supporting documents. Define the scope before requesting direction.
Review Coquitlam demolition requirements, Check approvals before demolishing a structure.
Contact: permits@coquitlam.ca · 604-927-3441
Before you proceed: Utility, hazardous-material, and site steps may be prerequisites. Confirm prerequisites before setting a demolition date.
Request a free utility locate, Request utility-owner information before digging or excavation.
Contact: info@bc1c.ca · 1-800-474-6886
Before you proceed: A locate request does not identify every privately owned line; review the response package before work starts. Allow time for members to respond and keep the ticket information available on site.
Find a facility for a specific material, Search for facilities that accept a specific construction, renovation, or landscaping material.
Contact: 604-732-9253
Before you proceed: Confirm the facility accepts the material type and load source before travelling. Use this directory when the material is not accepted at the nearest municipal or regional facility.
Check accepted materials at United Boulevard, Confirm accepted materials, fees, and load requirements.
Contact: 604-432-6200
Before you proceed: Check hours and restrictions before hauling. Sorting recyclable materials may reduce disposal cost.
Review asbestos requirements before disturbing materials, Understand asbestos identification, qualified-person, and safe-work requirements before renovation or demolition.
Before you proceed: Suspect materials must be assessed before they are disturbed; disposal facilities may require documentation. Older buildings can contain asbestos in products that are not obvious from appearance alone.
Check provincial hazardous-waste requirements, Find provincial guidance for hazardous waste that cannot enter ordinary construction-waste streams.
Before you proceed: Use an authorized pathway; facility rules and documentation vary by material. Confirm classification and receiving requirements before material is transported.
Common local questions
Open only the answer you need. These questions remain connected through the existing Location relationship.
At VALROC Development Ltd., we provide full-service construction solutions for homeowners, strata properties, and commercial businesses in Coquitlam, BC. With a proven track record across residential, strata, and commercial projects, our experienced team delivers high-quality craftsmanship, efficient project execution, and customized solutions tailored to each client’s needs.
Homeowners in Coquitlam
For homeowners in Coquitlam, we specialize in new builds, renovations, and structural upgrades that enhance both property value and functionality. Our services include:
• Concrete & Asphalt Driveways – Professionally installed and built to last, ensuring a durable and attractive entrance to your home.
• Custom Home Construction – Full-service design-build solutions tailored to your lifestyle and vision.
• Excavation & Site Preparation – Proper groundwork for residential construction, landscaping, and additions.
• Home Additions & Structural Modifications – Expanding and upgrading existing homes with seamless integration.
Our team takes care of permitting, site logistics, and project management, ensuring that every homeowner in Coquitlam receives a stress-free, high-quality construction experience.
Strata Property Owners & Managers in Coquitlam
Strata properties require expert management and proactive maintenance to protect property value and ensure safety. We collaborate with strata councils, property managers, and building owners to deliver long-lasting construction solutions, such as:
• Asphalt & Concrete Paving for Strata Complexes – Enhancing curb appeal and safety in parking lots, walkways, and communal spaces.
• Drainage & Water Management Solutions – Preventing issues like foundation damage, pooling water, and erosion.
• Structural Repairs & Preventative Maintenance – Keeping strata properties functional, compliant, and up to code.
• Emergency & Routine Construction Services – Quick response to urgent repair needs and scheduled property upgrades.
With years of experience serving Coquitlam’s strata communities, we ensure that projects are efficiently planned, cost-effective, and completed with minimal disruption to residents.
Business & Commercial Clients in Coquitlam
Coquitlam is a rapidly growing commercial hub, and we provide businesses with customized construction solutions to meet their evolving needs. From renovations to full-scale builds, we help businesses enhance their operational efficiency and visual appeal. Our commercial services include:
• Parking Lot Construction & Paving – Ensuring safe, well-maintained surfaces for businesses, warehouses, and retail centres.
• Retail & Office Space Renovations – Customizing commercial interiors for better workflow and customer experience.
• Excavation & Land Development – Preparing commercial sites for new construction and expansion projects.
• Industrial & Warehouse Construction – Delivering efficient and structurally sound spaces for commercial operations.
We understand the importance of staying on schedule and within budget, which is why businesses in Coquitlam trust VALROC Development Ltd. for seamless project execution and high-quality results.
At VALROC Development Ltd., we provide full-service construction solutions for homeowners, strata properties, and commercial businesses in Coquitlam, BC. With a proven track record across residential, strata, and commercial projects, our experienced team delivers high-quality craftsmanship, efficient project execution, and customized solutions tailored to each client’s needs.
Homeowners in Coquitlam
For homeowners in Coquitlam, we specialize in new builds, renovations, and structural upgrades that enhance both property value and functionality. Our services include:
• Concrete & Asphalt Driveways – Professionally installed and built to last, ensuring a durable and attractive entrance to your home.
• Custom Home Construction – Full-service design-build solutions tailored to your lifestyle and vision.
• Excavation & Site Preparation – Proper groundwork for residential construction, landscaping, and additions.
• Home Additions & Structural Modifications – Expanding and upgrading existing homes with seamless integration.
Our team takes care of permitting, site logistics, and project management, ensuring that every homeowner in Coquitlam receives a stress-free, high-quality construction experience.
Strata Property Owners & Managers in Coquitlam
Strata properties require expert management and proactive maintenance to protect property value and ensure safety. We collaborate with strata councils, property managers, and building owners to deliver long-lasting construction solutions, such as:
• Asphalt & Concrete Paving for Strata Complexes – Enhancing curb appeal and safety in parking lots, walkways, and communal spaces.
• Drainage & Water Management Solutions – Preventing issues like foundation damage, pooling water, and erosion.
• Structural Repairs & Preventative Maintenance – Keeping strata properties functional, compliant, and up to code.
• Emergency & Routine Construction Services – Quick response to urgent repair needs and scheduled property upgrades.
With years of experience serving Coquitlam’s strata communities, we ensure that projects are efficiently planned, cost-effective, and completed with minimal disruption to residents.
Business & Commercial Clients in Coquitlam
Coquitlam is a rapidly growing commercial hub, and we provide businesses with customized construction solutions to meet their evolving needs. From renovations to full-scale builds, we help businesses enhance their operational efficiency and visual appeal. Our commercial services include:
• Parking Lot Construction & Paving – Ensuring safe, well-maintained surfaces for businesses, warehouses, and retail centres.
• Retail & Office Space Renovations – Customizing commercial interiors for better workflow and customer experience.
• Excavation & Land Development – Preparing commercial sites for new construction and expansion projects.
• Industrial & Warehouse Construction – Delivering efficient and structurally sound spaces for commercial operations.
We understand the importance of staying on schedule and within budget, which is why businesses in Coquitlam trust VALROC Development Ltd. for seamless project execution and high-quality results.
Yes, Coquitlam requires permits for various types of construction projects, including residential, commercial, and industrial builds. The permit process depends on the project type:
• Major Projects – Commercial, industrial, institutional, or multi-family builds.
• Minor Projects – Residential renovations, additions, or small-scale construction.
• Development Permits – Required if your project is located in a designated Development Permit Area.
At VALROC Development Ltd., we help clients navigate the City of Coquitlam’s permitting process, ensuring all necessary applications, approvals, and zoning requirements are met. Contact us today for expert guidance and a seamless construction experience.
📍 More information: Coquitlam Building & Construction
Yes, Coquitlam requires permits for various types of construction projects, including residential, commercial, and industrial builds. The permit process depends on the project type:
• Major Projects – Commercial, industrial, institutional, or multi-family builds.
• Minor Projects – Residential renovations, additions, or small-scale construction.
• Development Permits – Required if your project is located in a designated Development Permit Area.
At VALROC Development Ltd., we help clients navigate the City of Coquitlam’s permitting process, ensuring all necessary applications, approvals, and zoning requirements are met. Contact us today for expert guidance and a seamless construction experience.
📍 More information: Coquitlam Building & Construction
We offer comprehensive construction solutions tailored to homeowners, strata managers, and commercial clients. Our services include:
• Custom home builds and luxury property development.
• Concrete driveways, sidewalks, and patios for residential and commercial properties.
• Excavation and site preparation for new builds and expansions.
• Asphalt paving for parking lots, roadways, and private properties.
• Structural modifications and engineered retaining walls.
• Perimeter drainage, water management, and drain tile repairs.
We have completed hundreds of construction projects in Coquitlam, working closely with local zoning, engineering, and building departments to ensure compliance and top-quality results.
We offer comprehensive construction solutions tailored to homeowners, strata managers, and commercial clients. Our services include:
• Custom home builds and luxury property development.
• Concrete driveways, sidewalks, and patios for residential and commercial properties.
• Excavation and site preparation for new builds and expansions.
• Asphalt paving for parking lots, roadways, and private properties.
• Structural modifications and engineered retaining walls.
• Perimeter drainage, water management, and drain tile repairs.
We have completed hundreds of construction projects in Coquitlam, working closely with local zoning, engineering, and building departments to ensure compliance and top-quality results.
The Board of Variance is an independent body that reviews requests for minor variances from the Coquitlam Zoning Bylaw. If a zoning regulation creates an undue hardship for a property owner, they may apply for a variance related to:
• Building setbacks
• Lot coverage
• Building height adjustments
If you are planning a construction project and require a minor zoning adjustment, VALROC Development Ltd. can assist in evaluating your options and preparing your application.
📍 More information: Coquitlam Board of Variance
The Board of Variance is an independent body that reviews requests for minor variances from the Coquitlam Zoning Bylaw. If a zoning regulation creates an undue hardship for a property owner, they may apply for a variance related to:
• Building setbacks
• Lot coverage
• Building height adjustments
If you are planning a construction project and require a minor zoning adjustment, VALROC Development Ltd. can assist in evaluating your options and preparing your application.
📍 More information: Coquitlam Board of Variance
The City of Coquitlam provides various waste management services for construction debris, including:
• Cart Repairs & Exchanges – For damaged garbage and green carts.
• Large Item Pick-Up – Up to four large household items per year.
• Multi-Family Recycling & Waste Setup – Services for apartment buildings and condos.
• Secure Waste Storage – Recommendations to prevent urban wildlife from accessing waste.
For larger construction waste disposal, our team at VALROC Development Ltd. ensures that all materials are disposed of responsibly at approved facilities in compliance with city regulations.
📍 More information: Coquitlam Garbage & Recycling
The City of Coquitlam provides various waste management services for construction debris, including:
• Cart Repairs & Exchanges – For damaged garbage and green carts.
• Large Item Pick-Up – Up to four large household items per year.
• Multi-Family Recycling & Waste Setup – Services for apartment buildings and condos.
• Secure Waste Storage – Recommendations to prevent urban wildlife from accessing waste.
For larger construction waste disposal, our team at VALROC Development Ltd. ensures that all materials are disposed of responsibly at approved facilities in compliance with city regulations.
📍 More information: Coquitlam Garbage & Recycling
The Engineering & Public Works department is responsible for designing, maintaining, and upgrading the city’s transportation, drainage, and infrastructure systems. Their key divisions include:
• Roads & Transportation – Managing traffic flow, street maintenance, and road construction.
• Utilities & Flood Control – Overseeing water distribution, stormwater management, and sewage collection.
• Public Works & Environmental Services – Maintaining sidewalks, street lighting, and city parks.
At VALROC Development Ltd., we coordinate with Coquitlam’s Engineering & Public Works team to ensure all construction projects align with municipal infrastructure requirements.
📍 More information: Coquitlam Engineering & Public Works
The Engineering & Public Works department is responsible for designing, maintaining, and upgrading the city’s transportation, drainage, and infrastructure systems. Their key divisions include:
• Roads & Transportation – Managing traffic flow, street maintenance, and road construction.
• Utilities & Flood Control – Overseeing water distribution, stormwater management, and sewage collection.
• Public Works & Environmental Services – Maintaining sidewalks, street lighting, and city parks.
At VALROC Development Ltd., we coordinate with Coquitlam’s Engineering & Public Works team to ensure all construction projects align with municipal infrastructure requirements.
📍 More information: Coquitlam Engineering & Public Works
Coquitlam provides numerous resources for businesses and construction professionals, including:
• Tri-Cities Chamber of Commerce – Supporting local businesses in Coquitlam, Port Coquitlam, and Port Moody.
• BCIT Trades & Apprenticeships – Offering specialized training for skilled trades.
• City of Coquitlam Business Licensing – Required for all construction-related businesses operating in the city.
As an established construction company in Coquitlam, VALROC Development Ltd. maintains active business licensing and works closely with local agencies to uphold high industry standards.
📍 More information: Tri-Cities Chamber of Commerce
Coquitlam provides numerous resources for businesses and construction professionals, including:
• Tri-Cities Chamber of Commerce – Supporting local businesses in Coquitlam, Port Coquitlam, and Port Moody.
• BCIT Trades & Apprenticeships – Offering specialized training for skilled trades.
• City of Coquitlam Business Licensing – Required for all construction-related businesses operating in the city.
As an established construction company in Coquitlam, VALROC Development Ltd. maintains active business licensing and works closely with local agencies to uphold high industry standards.
📍 More information: Tri-Cities Chamber of Commerce
At VALROC Development Ltd., we offer full-service construction solutions backed by years of experience in Coquitlam, BC. Whether you’re a homeowner, strata manager, or business owner, we provide:
✅ Free on-site estimates
✅ Expert guidance on permits and zoning
✅ Top-tier craftsmanship and reliable service
📍 Contact us today to discuss your project!
At VALROC Development Ltd., we offer full-service construction solutions backed by years of experience in Coquitlam, BC. Whether you’re a homeowner, strata manager, or business owner, we provide:
✅ Free on-site estimates
✅ Expert guidance on permits and zoning
✅ Top-tier craftsmanship and reliable service
📍 Contact us today to discuss your project!