Skip to main content

GL Icon Set

Version: 1.0.2
Package: @gift-card-market/gl-icon-set
Last Updated: January 16, 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

import '@gift-card-market/gl-dynamic-image/dist/style.css';
import { type CategoryConfig, 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';

const data: CategoryConfig[] = [
{
id: 'celebrate-summer',
name: 'Celebrate Summer',
iconUrl: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/sun.svg',
activeIconUrl: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/sun-active.svg',
title: 'Lets Go <strong style="color: rgb(252, 191, 0);">Summer</strong>',
subtitle: 'Get ready for summer with our top gift card picks!',
active: true,
request: {
term: 'brunch',
program: 'restaurant',
},
},
{
id: 'local-choice-cards',
name: 'Local Choice Cards',
iconUrl: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/choice.svg',
activeIconUrl: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/choice-active.svg',
title: 'An Option for <strong style="color: rgb(238, 61, 132);">Any Preference</strong>',
subtitle: "Not sure what to gift, or want something more universal? We've got cards for any local preference.",
active: true,
results: [
{
name: 'Local Restaurants Card',
image: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/gcm-choice-restaurants-v2.webp',
},
{
name: 'Local Spas Card',
image: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/gcm-choice-spas-v2.webp',
},
{
name: 'Local Salons Card',
image: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/gcm-choice-salons-v2.webp',
},
{
name: 'Local Home Services Card',
image: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/gcm-choice-home-v2.webp',
},
{
name: 'Local Auto Services Card',
image: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/gcm-choice-auto-v2.webp',
},
{
name: 'Local Personal Services Card',
image: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/gcm-choice-personal-v2.webp',
},
],
},
{
id: 'restaurants',
name: 'Restaurants',
iconUrl: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/restaurant.svg',
activeIconUrl: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/restaurant-active.svg',
title: 'Mouthwatering <strong style="color: rgb(238, 61, 132);">Eats</strong>',
subtitle: 'The absolute local favorites, one text away.',
active: true,
request: {
term: 'restaurants',
program: 'restaurant',
},
},
{
id: 'spas-salons',
name: 'Spas & Salons',
iconUrl: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/spa.svg',
activeIconUrl: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/spa-active.svg',
title: 'Pamper & <strong style="color: rgb(108, 198, 177);">Relax</strong>',
subtitle: 'The absolute local favorites, one text away.',
active: true,
request: {
term: 'spas+salons',
program: 'spa',
},
},
{
id: 'best-sellers',
name: 'Best-Sellers',
iconUrl: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/best-sellers.svg',
activeIconUrl: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/best-sellers-active.svg',
title: 'The Cream of <strong style="color: rgb(238, 61, 132);">the Crop</strong>',
subtitle: 'The absolute local favorites, one text away.',
active: true,
request: {
term: 'best+sellers',
program: 'restaurant;spa;serviceprovider',
},
},
{
id: 'home-services',
name: 'Home Services',
iconUrl: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/home.svg',
activeIconUrl: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/home-active.svg',
title: 'Gift <strong style="color: rgb(108, 198, 177);">Peace of Mind</strong>',
subtitle: 'The absolute local favorites, one text away.',
active: true,
request: {
term: 'home+services',
program: 'serviceprovider',
},
},
{
id: 'auto-services',
name: 'Auto Services',
iconUrl: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/car.svg',
activeIconUrl: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/car-active.svg',
title: 'Gift <strong style="color: rgb(238, 61, 132);">Peace of Mind</strong>',
subtitle: 'The absolute local favorites, one text away.',
active: true,
request: {
term: 'auto+services',
program: 'serviceprovider',
},
},
{
id: 'personal-services',
name: 'Personal Services',
iconUrl: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/personal.svg',
activeIconUrl: 'https://dev.giftcardmarket.com/wp-content/uploads/2025/07/personal-active.svg',
title: 'Gift <strong style="color: rgb(108, 198, 177);">Convenience</strong>',
subtitle: 'The absolute local favorites, one text away.',
active: true,
request: {
term: 'personal+services',
program: 'serviceprovider',
},
},
];

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',
}}
categories={data}
maxCategories={8}
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"
categories={categories}
/>
</>
);
}

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).
environmentstring (e.g., 'development', 'production', etc.)Backend environment; used to map to the corresponding domain.
categoriesCategoryConfig[]List of categories to display.
buttonConfigButtonPropsCustomize Buy Now button and theme. If not provided, defaults will be used.
maxCategoriesnumberMaximum number of categories to display. Default is 8.

Note: in the component, if categories.length is greater than maxCategories (or 8 if not provided), the array will be 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;
active?: boolean;
request?: {
term: string;
program: string;
};
results?: BusinessInfo[];
};

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(categoryId: string): void – disable a category.
  • enableCategory(categoryId: string): void – re-enable a category.
  • addCategory(config: CategoryConfig): void – add a new category to the list.
  • removeCategory(categoryId: string): void – remove a category 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.

IconSetEvents (Event bus)

The file iconSetEvents.ts defines event names such as:

  • gl:iconset-ready
  • gl:category-clicked
  • gl:buynow-clicked
  • gl:error
  • gl:location-acquired
  • gl:location-denied
  • gl:category-loaded
  • gl:search-complete

You can listen to these in both React and vanilla JS:

useEffect(() => {
const handler = (event: any) => {
console.log('Icon set event:', event.type, event.detail);
};

window.addEventListener('gl:buynow-clicked', handler);
return () => window.removeEventListener('gl:buynow-clicked', handler);
}, []);

The specific payload in event.detail depends on GeolocatedSetComponent – see the file src/components/GeolocatedSetComponent.tsx for the exact structure (merchant, categoryId, etc.).