Skip to main content

Theme Customizations

Suma Elementor v3.0.0 theme with 60+ custom widgets, Laravel Mix build system, and Preact integration.

Overview

The StealthCam site uses Suma Elementor v3.0.0, a custom WordPress theme developed by Rhino Group specifically for BigCommerce headless commerce integrations. Built on Elementor Pro, it provides 60+ specialized widgets and a modern build pipeline.

Theme Architecture

Directory Structure

suma-elementor/
├── style.css # Theme header (v3.0.0)
├── functions.php # Bootstrap and autoload
├── webpack.mix.js # Laravel Mix configuration
├── package.json # npm dependencies
├── composer.json # PHP dependencies
├── inc/
│ ├── class-setup.php # Theme setup hooks
│ ├── class-enqueue.php # Asset loading
│ ├── class-utils.php # Utility functions
│ ├── class-bigcommerce.php # BC integration helpers
│ ├── class-ajax-handlers.php # AJAX endpoints
│ ├── integrations/ # Third-party integrations
│ │ ├── class-facetwp.php
│ │ ├── class-algolia.php
│ │ └── class-klaviyo.php
│ └── widgets/ # Elementor custom widgets (60+)
│ ├── base/ # Base widget class
│ ├── bigcommerce/ # BC-specific widgets
│ ├── content/ # Content widgets
│ ├── navigation/ # Menu and navigation
│ └── utility/ # Utility widgets
├── templates/ # Template files
│ ├── header.php
│ ├── footer.php
│ ├── single-bigcommerce_product.php
│ ├── archive-bigcommerce_product.php
│ └── page-templates/
├── template-parts/ # Reusable template parts
├── assets/
│ ├── src/
│ │ ├── scss/ # Source SCSS files
│ │ │ ├── app.scss # Main stylesheet
│ │ │ ├── _variables.scss
│ │ │ ├── components/
│ │ │ └── layouts/
│ │ ├── js/ # Source JavaScript
│ │ │ ├── app.js # Main JS entry
│ │ │ ├── components/ # JS components
│ │ │ └── modules/ # Feature modules
│ │ └── preact/ # Preact components
│ │ ├── cart-widget.jsx
│ │ ├── product-card.jsx
│ │ └── variant-selector.jsx
│ └── dist/ # Compiled assets
│ ├── css/
│ │ ├── app.css
│ │ └── app.css.map
│ └── js/
│ ├── app.js
│ └── app.js.map
└── vendor/ # Composer dependencies

Technology Stack

  • WordPress: 6.7.2+
  • PHP: 7.4+ (PSR-4 autoloading)
  • Elementor Pro: v3.28.2
  • Laravel Mix: v6.0.39 - Build system
  • Preact: v10.11.0 - Lightweight React alternative
  • Tailwind CSS: v3.0.11 - Utility-first CSS
  • Sass: SCSS compilation
  • Babel: ES6+ transpilation
  • Autoprefixer: Browser compatibility

Custom Elementor Widgets

The theme provides 60+ custom Elementor widgets organized by category. All widgets support Elementor's responsive controls, custom CSS, and conditional display.

BigCommerce Product Widgets (20+)

Product Grid

Widget ID: suma-product-grid
Category: BigCommerce

Display products in a customizable grid layout.

Features:

  • Query builder (by category, brand, featured, etc.)
  • Column controls (1-6 columns, responsive)
  • Product card templates
  • Pagination or load more
  • Filter integration (FacetWP)

Style Controls:

  • Card spacing
  • Image aspect ratio
  • Hover effects
  • Button styling
  • Price display options

Widget ID: suma-product-carousel
Category: BigCommerce

Rotating product showcase with Swiper.js integration.

Features:

  • Auto-play with configurable speed
  • Navigation arrows
  • Pagination dots
  • Touch/swipe support
  • Lazy loading

Single Product Components

Product Title (suma-product-title)

  • Custom typography controls
  • SKU display toggle
  • Brand display option

Product Price (suma-product-price)

  • Sale price highlighting
  • Compare at price display
  • Custom prefix/suffix text
  • Currency formatting

Product Images (suma-product-images)

  • Gallery with zoom
  • Lightbox integration
  • Thumbnail navigation
  • Variant image switching

Product Description (suma-product-description)

  • Tabbed or accordion layout
  • Custom content sections
  • Specifications table
  • Video embed support

Add to Cart Button (suma-add-to-cart)

  • Custom button text
  • Quantity selector
  • Success message display
  • Cart drawer integration
  • Loading states

Product Variants (suma-product-variants)

  • Dropdown or swatch display
  • Color/image swatches
  • Stock status display
  • Price updates on selection
  • Preact-powered reactive UI

Related Products (suma-related-products)

  • BC relationship queries
  • Custom query fallback
  • Grid or carousel display
  • Limit products shown

Category & Brand Widgets

Category Grid (suma-category-grid)

  • Display BC categories
  • Custom images/icons
  • Product count badges
  • Category descriptions
  • Custom links

Brand Showcase (suma-brand-showcase)

  • Brand logo display
  • Grid or carousel layout
  • Link to brand archives
  • Custom ordering

Featured Products (suma-featured-products)

  • Query featured BC products
  • Custom badges/labels
  • Sale items highlighting
  • Custom sorting

Mega Menu

Widget ID: suma-mega-menu
Category: Navigation

Multi-column dropdown menu with categories, featured products, and custom content.

Features:

  • Category columns with product counts
  • Featured product showcases
  • Custom HTML content areas
  • Sticky menu support
  • Mobile hamburger transformation

Configuration:

// Theme filter for menu structure
add_filter('suma_mega_menu_structure', function($structure) {
$structure['main'] = [
'categories' => get_categories(['taxonomy' => 'bigcommerce_category']),
'featured' => get_featured_products(4),
'promo_html' => '<div>Custom promo content</div>'
];
return $structure;
});

Widget ID: suma-breadcrumbs

BC-aware breadcrumb navigation with schema markup.

Mobile Menu Toggle

Widget ID: suma-mobile-menu-toggle

Hamburger button with animation and off-canvas menu trigger.

Account Menu

Widget ID: suma-account-menu

User account dropdown with login/register links and BigCommerce account integration.

Cart Icon

Widget ID: suma-cart-icon

Animated cart icon with item count badge.

Features:

  • Real-time cart count updates
  • Cart drawer toggle
  • Customizable icon library
  • Badge styling controls

Search & Filter Widgets (10+)

FacetWP Facet List

Widget ID: suma-facetwp-facets

Display one or more FacetWP facets with custom styling.

Features:

  • Select multiple facets
  • Collapsible sections
  • Mobile filter drawer
  • Result count display

Widget ID: suma-algolia-search

Instant search box with autocomplete.

Features:

  • Custom placeholder text
  • Icon styling
  • Autocomplete dropdown
  • Recent searches
  • Popular searches

Sort Dropdown

Widget ID: suma-sort-dropdown

Product sorting control (price, name, newest, etc.)

Filter Button (Mobile)

Widget ID: suma-filter-button

Mobile-optimized button to reveal filters in drawer/modal.

Active Filters Display

Widget ID: suma-active-filters

Show currently applied filters with remove buttons.

Content Widgets (15+)

Hero Slider

Widget ID: suma-hero-slider

Full-width hero with multiple slides, parallax effects, and video backgrounds.

Features:

  • Drag-and-drop slide builder
  • Video backgrounds (YouTube, Vimeo, self-hosted)
  • Parallax scrolling
  • Ken Burns effect
  • Custom CTA buttons per slide
  • Autoplay controls

Content Tabs

Widget ID: suma-content-tabs

Tabbed content sections with customizable triggers.

Accordion

Widget ID: suma-accordion

Collapsible content panels with icon controls.

Icon Box

Widget ID: suma-icon-box

Icon/image with heading and description. Useful for features, benefits, USPs.

Testimonials

Widget ID: suma-testimonials

Customer testimonial slider with ratings, photos, and quotes.

Video Popup

Widget ID: suma-video-popup

Lightbox video player trigger with custom thumbnail.

Image Comparison

Widget ID: suma-image-compare

Before/after image slider with draggable divider.

Countdown Timer

Widget ID: suma-countdown

JavaScript countdown for sales, launches, events.

Instagram Feed

Widget ID: suma-instagram-feed

Display Instagram posts via API.

Blog Posts

Widget ID: suma-blog-posts

Custom WordPress post query with grid/list layouts.

Utility Widgets (7+)

Widget ID: suma-modal-trigger

Button/link that opens a modal popup with custom content.

Use Cases:

  • Size charts
  • Dealer locator
  • Quick product views
  • Newsletter signup
  • Store policies

Custom Code

Widget ID: suma-custom-code

Raw HTML/CSS/JS injection with syntax highlighting editor.

Alert Bar

Widget ID: suma-alert-bar

Dismissible alert banner for announcements, promotions, shipping info.

Features:

  • Sticky positioning
  • Cookie-based dismissal
  • Countdown integration
  • Link/button support

Back to Top

Widget ID: suma-back-to-top

Smooth scroll to top button with reveal animation.

Lazy Load Container

Widget ID: suma-lazy-container

Wrapper that lazy loads child content on viewport intersection.


Laravel Mix Build System

Configuration

File: webpack.mix.js

const mix = require('laravel-mix');

mix
// Compile SCSS
.sass('assets/src/scss/app.scss', 'assets/dist/css')
.options({
postCss: [
require('tailwindcss')('./tailwind.config.js'),
require('autoprefixer')
]
})

// Compile JavaScript
.js('assets/src/js/app.js', 'assets/dist/js')
.babel(['assets/src/js/app.js'], 'assets/dist/js/app.js')

// Preact components
.js('assets/src/preact/index.jsx', 'assets/dist/js/preact.js')
.preact()

// Enable sourcemaps in development
.sourceMaps()

// Enable versioning in production
.version()

// BrowserSync for hot reload
.browserSync({
proxy: 'stealthcam.test',
files: [
'assets/dist/**/*',
'**/*.php',
'**/*.html'
]
});

NPM Scripts

File: package.json

{
"scripts": {
"dev": "npm run development",
"development": "mix",
"watch": "mix watch",
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "mix --production"
},
"devDependencies": {
"laravel-mix": "^6.0.39",
"sass": "^1.49.9",
"sass-loader": "^12.4.0",
"tailwindcss": "^3.0.11",
"autoprefixer": "^10.4.2",
"browser-sync": "^2.27.7",
"browser-sync-webpack-plugin": "^2.3.0",
"@babel/preset-react": "^7.16.7"
},
"dependencies": {
"preact": "^10.11.0",
"swiper": "^8.0.0",
"gsap": "^3.9.1"
}
}

Development Workflow

# Install dependencies
npm install

# Development mode (watch files, recompile on change)
npm run watch

# Production build (minified, optimized)
npm run production

# Hot module reload with BrowserSync
npm run hot

Asset Loading

File: inc/class-enqueue.php

public function enqueue_assets() {
// Get versioned asset path
$css_path = $this->get_asset_path('css/app.css');
$js_path = $this->get_asset_path('js/app.js');
$preact_path = $this->get_asset_path('js/preact.js');

// Enqueue styles
wp_enqueue_style(
'suma-elementor',
get_template_directory_uri() . '/assets/dist/' . $css_path,
[],
$this->get_asset_version($css_path)
);

// Enqueue scripts
wp_enqueue_script(
'suma-elementor',
get_template_directory_uri() . '/assets/dist/' . $js_path,
['jquery'],
$this->get_asset_version($js_path),
true
);

// Preact components (product pages only)
if (is_singular('bigcommerce_product')) {
wp_enqueue_script(
'suma-preact',
get_template_directory_uri() . '/assets/dist/' . $preact_path,
[],
$this->get_asset_version($preact_path),
true
);
}
}

Preact Integration

Purpose

Preact provides reactive UI components for dynamic product features (variant selection, cart updates, etc.) with minimal bundle size (~3KB vs React's ~40KB).

Component Structure

Location: assets/src/preact/

Cart Widget Component

File: assets/src/preact/cart-widget.jsx

import { h, Component } from 'preact';
import { getCart, updateCartItem, removeCartItem } from '../api/cart';

export default class CartWidget extends Component {
state = {
cart: null,
loading: true,
isOpen: false
};

componentDidMount() {
this.loadCart();
}

async loadCart() {
const cart = await getCart();
this.setState({ cart, loading: false });
}

async updateQuantity(itemId, quantity) {
this.setState({ loading: true });
await updateCartItem(itemId, quantity);
await this.loadCart();
}

async removeItem(itemId) {
this.setState({ loading: true });
await removeCartItem(itemId);
await this.loadCart();
}

toggleDrawer = () => {
this.setState({ isOpen: !this.state.isOpen });
};

render() {
const { cart, loading, isOpen } = this.state;

return (
<div class={`cart-widget ${isOpen ? 'is-open' : ''}`}>
<button
class="cart-toggle"
onClick={this.toggleDrawer}
>
<span class="cart-icon">🛒</span>
{cart && (
<span class="cart-count">{cart.item_count}</span>
)}
</button>

{isOpen && (
<div class="cart-drawer">
{loading ? (
<div class="cart-loading">Loading...</div>
) : cart && cart.items.length > 0 ? (
<>
<div class="cart-items">
{cart.items.map(item => (
<CartItem
key={item.id}
item={item}
onUpdate={this.updateQuantity}
onRemove={this.removeItem}
/>
))}
</div>
<div class="cart-footer">
<div class="cart-total">
Total: {cart.total}
</div>
<a href="/checkout" class="btn btn-primary">
Checkout
</a>
</div>
</>
) : (
<div class="cart-empty">Your cart is empty</div>
)}
</div>
)}
</div>
);
}
}

Product Variant Selector

File: assets/src/preact/variant-selector.jsx

import { h, Component } from 'preact';

export default class VariantSelector extends Component {
state = {
selectedOptions: {},
currentVariant: null,
price: this.props.basePrice
};

handleOptionChange = (optionId, valueId) => {
const selectedOptions = {
...this.state.selectedOptions,
[optionId]: valueId
};

this.setState({ selectedOptions });
this.updateVariant(selectedOptions);
};

updateVariant(selectedOptions) {
const { variants } = this.props;

// Find matching variant
const variant = variants.find(v =>
this.variantMatches(v, selectedOptions)
);

if (variant) {
this.setState({
currentVariant: variant,
price: variant.price
});

// Update product images if variant has specific images
if (variant.image_url) {
this.props.onVariantChange(variant);
}
}
}

variantMatches(variant, selectedOptions) {
return variant.option_values.every(ov =>
selectedOptions[ov.option_id] === ov.id
);
}

render() {
const { options } = this.props;
const { selectedOptions, price } = this.state;

return (
<div class="variant-selector">
{options.map(option => (
<div key={option.id} class="option-group">
<label class="option-label">{option.display_name}</label>

{option.type === 'swatch' ? (
<div class="swatch-grid">
{option.values.map(value => (
<button
key={value.id}
class={`swatch ${
selectedOptions[option.id] === value.id
? 'is-selected'
: ''
}`}
onClick={() =>
this.handleOptionChange(option.id, value.id)
}
style={{
backgroundColor: value.data?.colors?.[0]
}}
>
{value.label}
</button>
))}
</div>
) : (
<select
class="option-select"
onChange={(e) =>
this.handleOptionChange(
option.id,
parseInt(e.target.value)
)
}
>
<option value="">Select {option.display_name}</option>
{option.values.map(value => (
<option key={value.id} value={value.id}>
{value.label}
</option>
))}
</select>
)}
</div>
))}

<div class="variant-price">
${price}
</div>
</div>
);
}
}

Mounting Preact Components

File: assets/src/preact/index.jsx

import { h, render } from 'preact';
import CartWidget from './cart-widget';
import VariantSelector from './variant-selector';

// Mount cart widget
const cartMount = document.getElementById('cart-widget-mount');
if (cartMount) {
render(<CartWidget />, cartMount);
}

// Mount variant selector on product pages
const variantMount = document.getElementById('variant-selector-mount');
if (variantMount) {
const props = JSON.parse(variantMount.dataset.props || '{}');
render(<VariantSelector {...props} />, variantMount);
}

Tailwind CSS Integration

Configuration

File: tailwind.config.js

module.exports = {
content: [
'./templates/**/*.php',
'./template-parts/**/*.php',
'./inc/**/*.php',
'./assets/src/**/*.{js,jsx}',
],
theme: {
extend: {
colors: {
brand: {
primary: '#1a5f3f',
secondary: '#8b4513',
accent: '#f4a460'
}
},
fontFamily: {
sans: ['Inter', 'sans-serif'],
display: ['Oswald', 'sans-serif']
},
spacing: {
'128': '32rem',
'144': '36rem'
}
}
},
plugins: [
require('@tailwindcss/forms'),
require('@tailwindcss/typography'),
require('@tailwindcss/aspect-ratio')
]
};

Usage in Widgets

Tailwind classes can be used directly in widget templates:

<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<?php foreach ($products as $product) : ?>
<div class="bg-white rounded-lg shadow-md hover:shadow-xl transition-shadow">
<img src="<?php echo esc_url($product->image); ?>"
class="w-full h-64 object-cover rounded-t-lg">
<div class="p-4">
<h3 class="text-xl font-bold mb-2"><?php echo esc_html($product->name); ?></h3>
<p class="text-gray-600 mb-4"><?php echo esc_html($product->description); ?></p>
<div class="flex justify-between items-center">
<span class="text-2xl font-bold text-brand-primary">
$<?php echo esc_html($product->price); ?>
</span>
<button class="bg-brand-primary text-white px-4 py-2 rounded hover:bg-brand-secondary transition-colors">
Add to Cart
</button>
</div>
</div>
</div>
<?php endforeach; ?>
</div>

Complete Widget List

BigCommerce Widgets (20)

  1. suma-product-grid - Product grid display
  2. suma-product-carousel - Product slider
  3. suma-product-title - Product title/SKU
  4. suma-product-price - Price display
  5. suma-product-images - Image gallery
  6. suma-product-description - Description tabs
  7. suma-add-to-cart - Add to cart button
  8. suma-product-variants - Variant selector
  9. suma-related-products - Related products
  10. suma-category-grid - Category display
  11. suma-brand-showcase - Brand logos
  12. suma-featured-products - Featured items
  13. suma-product-badge - Custom badges
  14. suma-product-comparison - Compare products
  15. suma-recently-viewed - Browsing history
  16. suma-product-reviews - BazaarVoice integration
  17. suma-stock-status - Availability display
  18. suma-product-specifications - Specs table
  19. suma-product-video - Video gallery
  20. suma-quick-view - Modal quick view
  1. suma-mega-menu - Dropdown menu
  2. suma-breadcrumbs - Breadcrumb trail
  3. suma-mobile-menu-toggle - Hamburger button
  4. suma-account-menu - User account dropdown
  5. suma-cart-icon - Cart with badge
  6. suma-search-toggle - Search modal trigger
  7. suma-category-menu - Category navigation
  8. suma-footer-menu - Footer links

Search & Filter Widgets (10)

  1. suma-facetwp-facets - Filter display
  2. suma-algolia-search - Search box
  3. suma-sort-dropdown - Sort control
  4. suma-filter-button - Mobile filter button
  5. suma-active-filters - Applied filters
  6. suma-result-count - Search results count
  7. suma-load-more - Load more button
  8. suma-pagination - Pagination controls
  9. suma-filter-drawer - Mobile filter drawer
  10. suma-search-suggestions - Search autocomplete

Content Widgets (15)

  1. suma-hero-slider - Homepage hero
  2. suma-content-tabs - Tabbed content
  3. suma-accordion - Collapsible panels
  4. suma-icon-box - Icon with text
  5. suma-testimonials - Customer reviews
  6. suma-video-popup - Video lightbox
  7. suma-image-compare - Before/after slider
  8. suma-countdown - Countdown timer
  9. suma-instagram-feed - Instagram posts
  10. suma-blog-posts - Blog grid
  11. suma-team-members - Team showcase
  12. suma-pricing-table - Pricing comparison
  13. suma-progress-bar - Animated progress
  14. suma-image-hotspots - Interactive image
  15. suma-flip-box - Card flip animation
  16. suma-call-to-action - CTA banner

Utility Widgets (7)

  1. suma-modal-trigger - Modal popup
  2. suma-custom-code - HTML/JS injection
  3. suma-alert-bar - Alert banner
  4. suma-back-to-top - Scroll to top
  5. suma-lazy-container - Lazy load wrapper
  6. suma-cookie-notice - GDPR cookie banner
  7. suma-age-gate - Age verification modal

Theme Hooks & Filters

Product Display Filters

// Modify product card template
add_filter('suma_product_card_template', function($template, $product) {
// Custom template logic
return $template;
}, 10, 2);

// Add custom product badge
add_filter('suma_product_badge', function($badge, $product) {
if ($product->on_sale) {
$badge = '<span class="badge-sale">SALE</span>';
}
return $badge;
}, 10, 2);

// Customize price display
add_filter('suma_product_price_html', function($html, $product) {
// Custom price formatting
return $html;
}, 10, 2);

Cart & Checkout Hooks

// Before add to cart button
add_action('suma_before_add_to_cart', function($product) {
// Custom content before button
});

// After add to cart success
add_action('suma_after_add_to_cart_success', function($product, $cart) {
// Track analytics, show message, etc.
}, 10, 2);

Asset Loading Filters

// Disable default styles on specific pages
add_filter('suma_load_default_styles', function($load) {
if (is_page('custom-landing')) {
return false;
}
return $load;
});

Performance Optimizations

Asset Loading Strategy

  1. Critical CSS - Inline critical styles in <head>
  2. Deferred JavaScript - Non-critical JS loaded with defer
  3. Lazy Loading - Images and components loaded on viewport intersection
  4. Code Splitting - Separate bundles for different page types
  5. SVG Icons - Inline SVG sprite instead of icon fonts

Caching Strategy

  • Object Cache - Redis/Memcached for database queries
  • Page Cache - Full page caching via WP Rocket
  • Asset Versioning - Cache busting with Mix versioning
  • CDN Integration - Static assets served from CDN

Mobile Optimization

  • Responsive Images - srcset and sizes attributes
  • Touch Gestures - Swipe support for carousels
  • Reduced Motion - Respect prefers-reduced-motion
  • Mobile-First CSS - Tailwind mobile-first breakpoints