Skip to main content

GL Icon Set

Version: 1.0.8
Package: @gift-card-market/gl-icon-set
Last Updated: July 21, 2026

A React library (with Web Component support) for displaying a geolocated category icon set with customizable titles/descriptions and a "Buy Now" button connected to Gift Card Market.

Table of Contents


Features

  • Geolocated icon set: categories with normal/active icons, can fetch results based on user location.
  • Customizable titles, colors, subtitles (supports HTML in the title field).
  • Buy Now button with customizable text, color, and visibility.
  • Can pass pre-defined results (results) or request configuration for the library to call the API automatically.
  • Control API via ref (GlIconSetHandle) and via controller helpers (disableCategory, enableCategory, etc.).
  • Supports Web Component for embedding in non-React pages.
  • Written in TypeScript, built with tsup + Tailwind CSS.

Requirements

  • React: ^18.0.0 or ^19.0.0.
  • Peer dependencies (install in your app):
npm install react react-dom react-slick slick-carousel @heroicons/react
  • Node / npm: follow the version used to build in the repo (not strictly required, but Node 18+ is recommended).

Installation

1. Configure GitHub Packages (if package is still hosted on GitHub)

From package.json, the package is published to GitHub Packages with:

"publishConfig": {
"registry": "https://npm.pkg.github.com/@Gift-Card-Market",
"access": "public"
}

You need to configure npm to read from this registry:

  1. Create a GitHub Personal Access Token with read:packages scope at: https://github.com/settings/tokens
  2. Login:
npm login --registry=https://npm.pkg.github.com --scope=@gift-card-market

Or add to your project's .npmrc file:

@gift-card-market:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN

2. Install the package

npm install @gift-card-market/gl-icon-set

3. Import CSS

// GL Icon Set styles
import '@gift-card-market/gl-icon-set/style.css';

// slick-carousel styles
import 'slick-carousel/slick/slick.css';
import 'slick-carousel/slick/slick-theme.css';

Quick Start with React

Basic Example

Category content is no longer provided by the partner — GlIconSet fetches its categories directly from the Admin Portal Icon Set API as soon as it mounts. Make sure the target environment has Icon Set categories configured in the Admin Portal, otherwise the component renders with an empty category list.

import '@gift-card-market/gl-dynamic-image/dist/style.css';
import { GlIconSet, type GlIconSetHandle } from '@gift-card-market/gl-icon-set';
import '@gift-card-market/gl-icon-set/style.css';
import 'slick-carousel/slick/slick.css';
import 'slick-carousel/slick/slick-theme.css';
import { useRef } from 'react';

export default function IconSetPage() {
const ref = useRef<GlIconSetHandle | null>(null);

return (
<GlIconSet
ref={ref}
buttonConfig={{
buyNowText: 'Buy Now',
buyNowColor: '#ee3d84',
buyNowVisible: true,
themeColor: '#ee3d84',
buyNowTextColor: '#ffffff',
}}
maxCategories={8}
maxResultsPerCategory={8}
receiveUpdates={true}
environment={'production'}
jwt={YOUR_JWT_TOKEN}
/>
);
}

Using ref (GlIconSetHandle) for control

function Toolbar() {
const ref = useRef<GlIconSetHandle | null>(null);

return (
<>
<button onClick={() => ref.current?.refresh()}>Refresh</button>
<button onClick={() => ref.current?.reset()}>Reset</button>
<button onClick={() => ref.current?.disableCategory('Restaurants')}>
Disable Restaurants
</button>
<button onClick={() => ref.current?.enableCategory('Restaurants')}>
Enable Restaurants
</button>
<button
onClick={async () => {
const results = await ref.current?.getResults();
console.log('Current results:', results);
}}
>
Log results
</button>

<GlIconSet ref={ref} jwt="YOUR_JWT_TOKEN" environment="production" />
</>
);
}

Detailed API

Props GlIconSet

The actual type is defined in glIconSetPros.ts. Summary:

PropTypeRequiredDescription
jwtstringJWT for calling Gift Card Market API. Access the following link to see instructions for obtaining JWT (access_token).
environment'production' | 'staging' | 'qa' | 'development'Backend environment; used to map to the corresponding domain.
buttonConfigButtonPropsCustomize Buy Now button and theme. If not provided, defaults will be used.
maxCategoriesnumberMaximum number of categories to display. Clamped to the range 1–8; default is 8. Values below 1 are raised to 1 and values above 8 are capped at 8.
maxResultsPerCategorynumberMaximum number of results per category (capped at 10). Default is 10.
receiveUpdatesbooleanWhether to apply Admin Portal content overrides that are currently active. Default is true.

Note: category content is fetched automatically from the Admin Portal Icon Set API (the partner-supplied categories prop was removed in 1.0.8). If the number of fetched categories is greater than the effective maxCategories (1–8), the list is sliced.

CategoryConfig

Defined in categoryConfig.ts (abbreviated):

export type BusinessInfo = {
name: string;
image: string;
};

export type CategoryConfig = {
id: string;
name: string;
iconUrl: string;
activeIconUrl: string;
title: string; // can contain HTML (see demo/main.tsx)
subtitle: string;
titleColor?: string;
subtitleColor?: string;
titleFont?: string;
subtitleFont?: string;
active?: boolean;
request?: {
term: string;
program: string;
};
results?: BusinessInfo[];
};

id is the Admin Portal category GUID (not partner-facing). Use name (e.g. 'Restaurants') when calling disableCategory/enableCategory via the ref API below.

Typical usage patterns:

  • With request: the library will automatically call the API to fetch results based on term and program.
  • With results: you provide a pre-defined list of businesses (gift cards, merchants, etc.).

ButtonProps (buttonConfig)

In GlIconSet.tsx, there is a default configuration:

const configurationDefault = {
themeColor: '#0052cc',
buyNowText: 'Buy Now',
buyNowColor: '#0052cc',
buyNowTextColor: '#ffffff',
buyNowVisible: true,
};

The ButtonProps type is defined correspondingly in glIconSetPros.ts (summary):

  • buyNowVisible: boolean – show/hide the Buy Now button.
  • buyNowText: string – button text.
  • buyNowColor: string – button background color.
  • buyNowTextColor?: string – text color.
  • themeColor: string – main theme color of the component.

When you pass buttonConfig, any field not provided will use the default value.

GlIconSetHandle (ref API)

Full definition in glIconSetHandle.ts. Main methods:

  • refresh(): void – refresh the current results/state.
  • reset(): void – reset to initial state (categories as initial).
  • disableCategory(categoryName: string): void – disable a category, matched by name (case-insensitive). If the disabled category is the one currently displayed, the component automatically selects and reloads the category that shifts into that position; if it was the last one, it falls back to the first category. Disabling a non-selected category keeps the current selection in sync.
  • enableCategory(categoryName: string): void – re-enable a category, matched by name (case-insensitive). The currently-selected category stays selected; if everything was disabled, the re-enabled category is selected and loaded.
  • addCategory(config: CategoryConfig): void – add a new category to the list.
  • removeCategory(categoryId: string): void – remove a category, matched by id.
  • getResults(): Promise<CategoryConfig[]> | undefined – get current results (async). Returns undefined if handle is not ready.
  • searchCategory(categoryId: string): Promise<CategoryConfig[]> | undefined – trigger search for a specific category, matched by id.

IconSetEvents (Event bus)

The Custom Element (gl-icon-set) uses Shadow DOM (mode: 'open') to completely encapsulate styling, preventing CSS bleeding. Component styles are compiled and injected directly into the shadow root during build execution.

Custom DOM Events are dispatched directly on the custom element host instance and bubble up with composed: true:

  • gl:iconset-ready
  • gl:category-changed — Fired when a category is selected/changed. event.detail contains { categoryId }.
  • gl:buy-clicked — Fired when the Buy Now button is clicked. event.detail contains business information.
  • gl:error
  • gl:location-acquired
  • gl:location-denied
  • gl:category-loaded
  • gl:search-complete

You can listen to these events directly on the Web Component instance (recommended):

const iconSet = document.querySelector('gl-icon-set');
iconSet.addEventListener('gl:category-changed', (e) => {
console.log('Category changed on host element:', e.detail.categoryId);
});

Or globally on the document or window object:

document.addEventListener('gl:category-changed', (e) => {
console.log('Global category changed event:', e.detail.categoryId);
});

Web Component Usage

The package includes browser build support in this repository (src/web.ts, build).

Shadow DOM Isolation

The Custom Element <gl-icon-set> uses Shadow DOM (mode: 'open') to completely encapsulate styling, preventing CSS bleeding. Component styles are compiled and injected directly into the shadow root during build execution.

Embedding Pattern

Include the global stylesheet and script in your HTML page:

<link rel="stylesheet" href="/path/to/@gift-card-market/gl-icon-set/dist/browser/gl-icon-set.css">
<script src="/path/to/@gift-card-market/gl-icon-set/dist/browser/gl-icon-set.global.js"></script>

Category content is no longer set via a categories attribute/property — the component fetches its categories directly from the Admin Portal Icon Set API as soon as it mounts. Just mount the tag with jwt/environment (and optionally max-categories/max-results-per-category/receive-updates):

<gl-icon-set
environment="development"
buttonConfig="{{ buyNowText: 'Buy Now', buyNowColor: '#ee3d84', buyNowVisible: true, themeColor: '#ee3d84', buyNowTextColor: '#ffffff' }}"
max-categories="8"
max-results-per-category="8"
receive-updates="true"
jwt="YOUR_JWT_TOKEN"
></gl-icon-set>

Scripting API

Alternatively, you can assign other properties programmatically:

const iconSetEl = document.querySelector('gl-icon-set');

customElements.whenDefined('gl-icon-set').then(() => {
iconSetEl.maxCategories = 8;
iconSetEl.maxResultsPerCategory = 8;
iconSetEl.receiveUpdates = true;
iconSetEl.buttonConfig = {
buyNowText: 'Buy Now',
buyNowColor: '#ee3d84',
buyNowVisible: true,
themeColor: '#ee3d84',
buyNowTextColor: '#ffffff'
};
});

Changelog

Version 1.0.8 (Current)

  • 🧹 Removed the deprecated categories prop from the public type (GlIconSetPros). It has been ignored at runtime since 1.0.7 (content is fetched from the Admin Portal Icon Set API); it is now removed from the type entirely. No runtime impact — delete it from any remaining TypeScript usages.
  • 🔒 maxCategories is now clamped to the range 1–8 (minimum 1, maximum 8). Values below 1 are raised to 1 and values above 8 are capped at 8. The limit is applied to both the initial category list and runtime addCategory.
  • 🐛 Fixed category disable/enable selection behavior:
    • Disabling the currently-displayed category now auto-selects and reloads the category that shifts into that position; if the disabled one was the last, it falls back to the first category (index 0) instead of showing an empty content area.
    • Disabling a different (non-selected) category keeps the current selection, with the highlighted tab and the content below staying in sync after the list re-indexes.
    • Fixed a stale-reference bug so disableCategory/enableCategory invoked via the ref API or Web Component always act against the category that is currently selected.

Version 1.0.7

  • 💥 Breaking (runtime): categories prop is now ignored — content is fetched automatically from the Admin Portal Icon Set API (GET /api/v1/web-component/icon-set) as soon as the component mounts. The prop is kept in the type as @deprecated for backward compatibility, but no longer has any effect. If your Icon Set categories aren't configured in the Admin Portal for the target environment, the component renders with an empty list.
  • 🆕 Added maxResultsPerCategory prop (and max-results-per-category attribute) — caps results per category, up to 10.
  • 🆕 Added receiveUpdates prop (and receive-updates attribute) — controls whether active Admin Portal content overrides are applied.
  • 🐛 Fixed disableCategory/enableCategory (ref API and Web Component) to be documented and typed as matching by category name (not id) — the Admin Portal-driven id is now a backend GUID, not partner-facing.
  • 🐛 Removed the unsupported 'local' value from the environment type.

Version 1.0.6

  • 🔒 Encapsulated CSS bleeding fixes (scoped variables and nested selectors).
  • ⚙️ Added Tailwind utility prefix and configured important option.
  • 📐 Inline slick-carousel stylesheets in the styles bundle to fix absolute positioning of slider arrows in Shadow DOM.

Version 1.0.4

  • 🚀 Enhanced custom element wrapper (GLIconSetComponent) to support passing properties directly via HTML attributes using JS expressions and string evaluation (e.g. buttonConfig="{{ buyNowText: 'Buy Now' }}", categories="data").

Version 1.0.3

  • 🐛 Bug fixes and stability improvements.

Version 1.0.2

  • 🐛 Bug fixes and stability improvements.