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
- Requirements
- Installation
- Quick Start with React
- Detailed API
- Web Component Usage
- Changelog
Features
- Geolocated icon set: categories with normal/active icons, can fetch results based on user location.
- Customizable titles, colors, subtitles (supports HTML in the
titlefield). - 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.0or^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:
- Create a GitHub Personal Access Token with
read:packagesscope at: https://github.com/settings/tokens - 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 —
GlIconSetfetches its categories directly from the Admin Portal Icon Set API as soon as it mounts. Make sure the targetenvironmenthas 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:
| Prop | Type | Required | Description |
|---|---|---|---|
jwt | string | ✅ | JWT 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. |
buttonConfig | ButtonProps | ❌ | Customize Buy Now button and theme. If not provided, defaults will be used. |
maxCategories | number | ❌ | Maximum 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. |
maxResultsPerCategory | number | ❌ | Maximum number of results per category (capped at 10). Default is 10. |
receiveUpdates | boolean | ❌ | Whether 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
categoriesprop was removed in1.0.8). If the number of fetched categories is greater than the effectivemaxCategories(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[];
};
idis the Admin Portal category GUID (not partner-facing). Usename(e.g.'Restaurants') when callingdisableCategory/enableCategoryvia the ref API below.
Typical usage patterns:
- With
request: the library will automatically call the API to fetch results based ontermandprogram. - 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 byname(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 byname(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 byid.getResults(): Promise<CategoryConfig[]> | undefined– get current results (async). Returnsundefinedif handle is not ready.searchCategory(categoryId: string): Promise<CategoryConfig[]> | undefined– trigger search for a specific category, matched byid.
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-readygl:category-changed— Fired when a category is selected/changed.event.detailcontains{ categoryId }.gl:buy-clicked— Fired when the Buy Now button is clicked.event.detailcontains business information.gl:errorgl:location-acquiredgl:location-deniedgl:category-loadedgl: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
categoriesprop from the public type (GlIconSetPros). It has been ignored at runtime since1.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. - 🔒
maxCategoriesis 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 runtimeaddCategory. - 🐛 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/enableCategoryinvoked via the ref API or Web Component always act against the category that is currently selected.
Version 1.0.7
- 💥 Breaking (runtime):
categoriesprop 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@deprecatedfor backward compatibility, but no longer has any effect. If your Icon Set categories aren't configured in the Admin Portal for the targetenvironment, the component renders with an empty list. - 🆕 Added
maxResultsPerCategoryprop (andmax-results-per-categoryattribute) — caps results per category, up to 10. - 🆕 Added
receiveUpdatesprop (andreceive-updatesattribute) — 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 categoryname(notid) — the Admin Portal-drivenidis now a backend GUID, not partner-facing. - 🐛 Removed the unsupported
'local'value from theenvironmenttype.
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.