npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@thewishlistco/preference-brand

v0.3.0

Published

Preference Widget

Readme

🛍️ Brand Preference Widget

A simple, developer-friendly JavaScript widget that allows retailers to add brand selection functionality to their websites. Shoppers can easily favorite brands using heart or star icons, with preferences automatically synced through The Wishlist API.

✨ Features

  • Easy Integration: Simple JavaScript class with minimal setup required
  • Customer-Specific: Automatically loads and saves individual customer preferences
  • Environment Support: Works with both staging and production APIs
  • Customizable Icons: Choose between heart, star, or custom icons
  • Automatic API Integration: Handles authentication and data fetching automatically
  • Event Callbacks: React to brand selection changes in real-time
  • Error Handling: Graceful fallbacks and error messages

📦 Installation

Option 1: CDN (Recommended)

Include the widget directly from unpkg CDN:

<script src="https://unpkg.com/@thewishlistco/preference-brand@latest/script.js"></script>

Option 2: NPM

npm install @thewishlistco/preference-brand
import BrandPreferenceWidget from '@thewishlistco/preference-brand';

Option 3: Download

Download script.js and include it in your project:

<script src="path/to/script.js"></script>

🚀 Quick Start

1. Add a Container Element

<div id="my-brand-widget"></div>

2. Initialize the Widget

const widget = new BrandPreferenceWidget({
    tenantId: 'your-tenant-id',
    customerEmail: '[email protected]',
    containerId: 'my-brand-widget',
    env: 'staging'
});

3. Complete Example

<!DOCTYPE html>
<html>
<head>
    <title>Brand Preferences</title>
</head>
<body>
    <div id="brand-widget"></div>
    
    <script src="https://unpkg.com/@thewishlistco/[email protected]/script.js"></script>
    <script>
        const widget = new BrandPreferenceWidget({
            tenantId: 'your-tenant-id',
            customerEmail: '[email protected]',
            containerId: 'brand-widget',
            env: 'staging',
            iconType: 'heart',
            onBrandToggle: (data) => {
                console.log(`${data.brand.label} ${data.isSelected ? 'selected' : 'deselected'}`);
            }
        });
    </script>
</body>
</html>

⚙️ Configuration Options

| Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | tenantId | string | ✅ Yes | - | Your unique tenant identifier from The Wishlist | | customerEmail | string | ✅ Yes | - | Customer's email address for personalized preferences | | containerId | string | ✅ Yes | - | DOM element ID where the widget will be rendered | | env | string | No | 'staging' | API environment: 'staging' or 'prod' | | iconType | string | No | 'heart' | Icon style: 'heart' (♥/♡) or 'star' (★/☆) | | customIcon | string | No | null | Custom HTML icon (overrides iconType) | | onBrandToggle | function | No | null | Callback function triggered on brand selection changes |

Required Parameters

The widget requires three essential parameters to function:

  • tenantId: Obtained from your Wishlist account settings
  • customerEmail: The current user's email address
  • containerId: Must match an existing DOM element ID

Example with minimum required parameters:

const widget = new BrandPreferenceWidget({
    tenantId: 'your-tenant-id',
    customerEmail: '[email protected]',
    containerId: 'widget-container'
});

Example with All Options

const widget = new BrandPreferenceWidget({
    tenantId: 'your-tenant-id',
    customerEmail: '[email protected]',
    containerId: 'my-brand-widget',
    env: 'prod',
    iconType: 'star',
    customIcon: '<i class="fas fa-bookmark"></i>',
    onBrandToggle: (data) => {
        console.log('Brand:', data.brand.label);
        console.log('Selected:', data.isSelected);
        console.log('All selected brands:', data.selectedBrands);
        
        // Analytics tracking
        if (typeof gtag !== 'undefined') {
            gtag('event', 'brand_preference_changed', {
                brand_code: data.brand.code,
                brand_name: data.brand.label,
                action: data.isSelected ? 'selected' : 'deselected',
                total_selected: data.selectedBrands.length
            });
        }
        
        // Custom business logic
        updateProductRecommendations(data.selectedBrands);
    }
});

🔧 API Methods

getSelectedBrands()

Returns an array of currently selected brand codes.

const selectedBrands = widget.getSelectedBrands();
console.log(selectedBrands); // ['SW', 'SR', 'BC']

setSelectedBrands(brandCodes)

Programmatically set the selected brands.

widget.setSelectedBrands(['SW', 'RHS']);

👤 Customer-Specific Preferences

The widget requires a customerEmail and automatically:

  1. Load Customer Data: Fetch the customer's existing preferences using their email
  2. Display Saved Preferences: Show previously saved brand selections instead of defaults
  3. Auto-Save Changes: Automatically save any preference changes to the customer's profile

Behavior

  • Existing Customer: Loads and displays their saved preferences
  • New Customer: Shows default preferences from configuration, saves changes to their profile
  • Customer Not Found: Falls back to defaults but won't save changes

🎨 Styling

The widget includes default CSS that's automatically injected. You can override styles by targeting these classes:

.brand-preference-widget { }
.brand-list { }
.brand-item { }
.brand-icon { }
.brand-label { }
.brand-preference-error { }

Custom Styling Example

.brand-item {
    background: linear-gradient(45deg, #ff6b6b, #feca57);
    border-radius: 20px;
    color: white;
}

.brand-item:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}

🔄 Event Handling

The onBrandToggle callback provides detailed information about brand selection changes:

{
    brand: {
        label: "Saltwater Wine",
        code: "SW",
        default: true,
        required: false
    },
    isSelected: true,
    selectedBrands: ["SW", "SR"]
}

Common Use Cases

Save to Local Storage:

onBrandToggle: (data) => {
    localStorage.setItem('selectedBrands', JSON.stringify(data.selectedBrands));
}

Update Shopping Recommendations:

onBrandToggle: (data) => {
    updateProductRecommendations(data.selectedBrands);
    showBrandSpecificOffers(data.brand.code, data.isSelected);
}

Analytics Tracking:

onBrandToggle: (data) => {
    gtag('event', 'brand_preference', {
        brand_code: data.brand.code,
        action: data.isSelected ? 'select' : 'deselect',
        total_selected: data.selectedBrands.length
    });
}

React Integration

Using the widget in a React component:

import { useEffect, useRef } from 'react';

function BrandPreferences({ tenantId, customerEmail, onPreferencesChange }) {
    const containerRef = useRef(null);
    const widgetRef = useRef(null);

    useEffect(() => {
        if (containerRef.current && !widgetRef.current) {
            // Load script dynamically
            const script = document.createElement('script');
            script.src = 'https://unpkg.com/@thewishlistco/[email protected]/script.js';
            script.onload = () => {
                widgetRef.current = new window.BrandPreferenceWidget({
                    tenantId,
                    customerEmail,
                    containerId: 'react-brand-widget',
                    env: 'prod',
                    onBrandToggle: (data) => {
                        onPreferencesChange?.(data);
                    }
                });
            };
            document.head.appendChild(script);
        }

        return () => {
            // Cleanup if needed
            if (widgetRef.current) {
                widgetRef.current = null;
            }
        };
    }, [tenantId, customerEmail]);

    return (
        <div className="brand-preferences">
            <h2>Choose Your Favorite Brands</h2>
            <div id="react-brand-widget" ref={containerRef}></div>
        </div>
    );
}

export default BrandPreferences;

Made with ❤️ by The Wishlist Co