API

Configure icon packs once, then render resolved SVGs through the standalone <tng-icon> component.

Custom Packs

Using Bootstrap Icons

Register a custom pack to use Bootstrap Icons, or any other @ng-icons set, alongside the built-in Lucide pack.

Install the Bootstrap icon set

pnpm

bash
pnpm add @ng-icons/bootstrap-icons

Register the pack with createTngIconPack

icons.provider.ts

typescript
// icons.provider.ts
import { createTngIconPack, provideTngIcons, type TngIconLoader } from '@tailng-ui/icons';

function createBootstrapLoader(exportName: string): TngIconLoader {
  return async () => {
    const mod = await import('@ng-icons/bootstrap-icons') as Record<string, unknown>;
    const svg = mod[exportName];
    if (typeof svg !== 'string') {
      throw new Error(`Bootstrap icon "${exportName}" not found.`);
    }
    return svg;
  };
}

const bootstrapPack = createTngIconPack('bootstrap', {
  'star-fill': createBootstrapLoader('bootstrapStarFill'),
  'bell':      createBootstrapLoader('bootstrapBell'),
  'x-circle':  createBootstrapLoader('bootstrapXCircle'),
});

export const tngIconProviders = provideTngIcons({
  packs: [bootstrapPack],
});

Use in templates

my.component.html

html
<!-- explicit pack prefix -->
<tng-icon icon="bootstrap:star-fill" size="1.25rem" />
<tng-icon icon="bootstrap:bell" size="1.25rem" />

<!-- when bootstrap is set as defaultPack, prefix is optional -->
<tng-icon icon="star-fill" size="1.25rem" />

createTngIconPack

Create named icon packs from local SVG strings, remote SVG URLs, or generated icon modules.

static SVG pack

typescript
import { createTngIconPack, provideTngIcons, type TngIconLoader } from '@tailng-ui/icons';

function staticSvg(svg: string): TngIconLoader {
  return () => Promise.resolve(svg);
}

const brandPack = createTngIconPack('brand', {
  logo: staticSvg(
    '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2L2 22h20L12 2Z"/></svg>',
  ),
});

export const tngIconProviders = provideTngIcons({ packs: [brandPack] });

remote SVG pack

typescript
import { createTngIconPack, provideTngIcons, type TngIconLoader } from '@tailng-ui/icons';

const CDN = 'https://cdn.example.com/icons';

function remoteSvg(path: string): TngIconLoader {
  return async () => {
    const res = await fetch(`${CDN}/${path}.svg`);
    if (!res.ok) throw new Error(`Failed to load icon: ${path}`);
    return res.text();
  };
}

const remoteIconPack = createTngIconPack('remote', {
  avatar: remoteSvg('avatar'),
  dashboard: remoteSvg('dashboard'),
});

export const tngIconProviders = provideTngIcons({ packs: [remoteIconPack] });

provideTngIcons

Provide additional packs, set the default pack, or explicitly override a built-in pack.

multiple packs

typescript
export const tngIconProviders = provideTngIcons({
  defaultPack: 'lucide',          // default pack when no prefix is given
  packs: [bootstrapPack, brandPack],
});

override built-in Lucide icons

typescript
provideTngIcons({
  allowBuiltinOverride: true,
  packs: [
    createTngIconPack('lucide', {
      home: () => Promise.resolve('<svg viewBox="0 0 24 24"><!-- custom --></svg>'),
    }),
  ],
})
Reference

TngIcon Inputs

Public types and component inputs exported from @tailng-ui/icons.

TngProvideIconsOptions

typescript
interface TngProvideIconsOptions {
  /** Additional icon packs to register alongside the built-in Lucide pack. */
  packs?: TngIconPack[];

  /**
   * Pack used when no prefix is given in an icon ref.
   * Defaults to 'lucide'.
   */
  defaultPack?: string;

  /**
   * Allow a custom pack to shadow a built-in pack name (e.g. 'lucide').
   * Defaults to false.
   */
  allowBuiltinOverride?: boolean;
}

createTngIconPack

typescript
function createTngIconPack(
  name: string,
  icons: Record<string, TngIconLoader>,
): TngIconPack;

// TngIconLoader: a function that returns the SVG markup as a string
type TngIconLoader = () => Promise<string>;

TngIcon inputs

typescript
// <tng-icon> component inputs
icon: string;          // required - icon name or "pack:name" ref
label?: string | null; // accessible label; omit for decorative icons
size?: string | number | null; // CSS size; numeric values become px