3.1 CRM monoline icons
The CRM nav-rail set. Twenty-five monoline glyphs covering the canonical Spark CRM entities — contacts, companies, leads, deals, tickets, sequences, and the rest of the platform’s primary objects. Every glyph fits the same 18×18 viewBox, uses a 1.5 stroke, and inherits currentColor. Drop one in front of any nav label, button label, or section header to mark the object type.
IconFamily · CRM set
.ic-cellEvery CRM icon in the kit, rendered at 32px above its import name. Hover or focus a cell to surface a subtle highlight. Each cell’s SVG is the same payload the React component renders; only the wrapping <svg> width + height change with the size prop.
<!-- Each icon is a tiny inline SVG sharing the same viewBox + stroke. -->
<!-- size=18 default; pass width/height to render larger (32 here). -->
<!-- Colour comes from `color: currentColor` on the parent. The cell -->
<!-- wrapper labels the glyph with its import name in mono type. -->
<div class="ic-cell">
<span class="ic-cell-glyph" aria-hidden="true">
<svg width="32" height="32" viewBox="0 0 18 18"
fill="none" stroke="currentColor" stroke-width="1.5"
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M2.75 8.5L9 3l6.25 5.5V14a1 1 0 0 1-1 1h-3v-4.25h-4.5V15h-3a1 1 0 0 1-1-1V8.5Z"/>
</svg>
</span>
<span class="ic-cell-name">HomeIcon</span>
</div>
/* Chapter-local catalogue grid. Auto-fills cells at ~120px; each cell
centres a glyph above its mono import name. Hover lifts the cell
background subtly so the operator can scan + zero in on a name. */
.ic-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
gap: var(--s-3);
}
.ic-cell {
display: flex; flex-direction: column;
align-items: center; justify-content: center;
gap: var(--s-3);
padding: var(--s-4) var(--s-3);
background: var(--bg-paper);
border: 1px solid var(--hair);
border-radius: var(--r-md);
transition: background 120ms ease, border-color 120ms ease;
}
.ic-cell:hover,
.ic-cell:focus-within {
background: var(--bg-warm);
border-color: color-mix(in oklab, var(--ink) 16%, var(--hair));
}
.ic-cell-glyph { color: var(--ink); width: 32px; height: 32px; }
.ic-cell-name { font: 500 11px/1.2 var(--f-mono); color: var(--fg-soft); }
// Icons are plain inline SVGs — no inline JS required for the catalogue.
// In live product UI you typically render them via the React component
// (see the React tab). When you only need raw HTML, you can also drop
// the <svg> payload into any markup directly; the family is designed to
// inherit `color: currentColor` from any parent.
//
// Programmatic tinting (optional):
document.querySelectorAll('.ic-cell-glyph').forEach((el) => {
el.style.color = 'var(--accent)';
});
// Every icon is a tiny `forwardRef` component sharing the IconProps
// shape — `size` (px, defaults to 18), `className`, and every native
// SVG attribute. Import any subset by name from the package barrel.
import {
HomeIcon,
CheckIcon,
PersonIcon,
BuildingIcon,
SproutIcon,
BriefcaseIcon,
FolderIcon,
WandIcon,
MegaphoneIcon,
HeadphonesIcon,
BookIcon,
StarIcon,
RefreshIcon,
RocketIcon,
HandshakeIcon,
CoinIcon,
ChartLineIcon,
ChartBarIcon,
SettingsIcon,
PenIcon,
CalendarIcon,
UsersIcon,
ScrollIcon,
SearchIcon,
PlusIcon,
} from '@magicblocksai/ui';
// Default render — 18px, currentColor.
<HomeIcon />
// Custom size — kept square. Pair with a label (or aria-label).
<HomeIcon size={32} />
<HomeIcon size={32} aria-label="Overview" />
// Coloured via CSS — inherits `color` from any parent.
<span style={{ color: 'var(--accent)' }}>
<SettingsIcon />
</span>
3.2 File-type icons
Seven file-type glyphs sharing a “page with corner fold” base — the inner mark distinguishes the type. Pair with the <FileTypeIcon contentType="…" /> dispatcher when you have a MIME string and want the kit to pick the right glyph. <FilePdfIcon> carries a typographic “PDF” label as a scoped exception — at 18×18 the format isn’t otherwise distinguishable from a generic document.
File-type set & FileTypeIcon dispatcher
.ic-stripThe seven base glyphs in a horizontal strip, then three dispatcher examples beneath — application/pdf, image/png, and application/zip — resolving to FilePdfIcon, FileImageIcon, and FileArchiveIcon. The dispatcher normalises content-type to lowercase, trims whitespace, and falls back to FileIcon for any string that doesn’t match a specific branch.
<!-- The seven file-type glyphs share the same page-with-fold base. -->
<!-- Drop the inner mark in place to distinguish the format. The PDF -->
<!-- glyph carries a typographic "PDF" label as a scoped exception. -->
<div class="ic-strip">
<div class="ic-cell">
<span class="ic-cell-glyph" aria-hidden="true">
<svg width="32" height="32" viewBox="0 0 18 18" fill="none"
stroke="currentColor" stroke-width="1.5"
stroke-linecap="round" stroke-linejoin="round">
<path d="M4 2.75A1 1 0 0 1 5 1.75H10.5L14 5.25V15.25A1 1 0 0 1 13 16.25H5A1 1 0 0 1 4 15.25Z"/>
<path d="M10.5 1.75V5.25H14"/>
</svg>
</span>
<span class="ic-cell-name">FileIcon</span>
</div>
<!-- …six more cells (Text / Image / Pdf / Video / Audio / Archive) -->
</div>
<!-- Dispatcher row — visualises the contentType→icon mapping. -->
<div class="ic-dispatch-row">
<span class="ic-dispatch-ct">application/pdf</span>
<span class="ic-dispatch-arrow">→</span>
<span class="ic-dispatch-resolved">FilePdfIcon</span>
<span class="ic-dispatch-glyph"><svg…/></span>
</div>
/* Horizontal strip for the file-type set + a dispatch row pairing a
contentType pill with the resolved icon name and a rendered glyph. */
.ic-strip {
display: flex; flex-wrap: wrap; align-items: stretch;
gap: var(--s-3);
}
.ic-strip .ic-cell { flex: 1 1 120px; min-width: 120px; }
.ic-dispatch {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: var(--s-3);
}
.ic-dispatch-row {
display: flex; align-items: center; gap: var(--s-3);
padding: var(--s-3) var(--s-4);
background: var(--bg-paper);
border: 1px solid var(--hair);
border-radius: var(--r-md);
}
.ic-dispatch-ct {
font: 500 11px/1 var(--f-mono); color: var(--fg-soft);
padding: 4px 8px; background: var(--bg-sunk);
border-radius: var(--r-sm);
}
.ic-dispatch-arrow { color: var(--fg-faint); }
.ic-dispatch-resolved { font: 500 11px/1 var(--f-mono); color: var(--ink); }
.ic-dispatch-glyph { margin-left: auto; color: var(--ink); }
// The dispatcher's mapping logic in vanilla JS — mirrors the
// `getFileTypeKind` exported from `@magicblocksai/ui` for consumers
// rendering icons outside React.
function getFileTypeKind(contentType) {
const ct = (contentType ?? '').toLowerCase().trim();
if (!ct) return 'doc';
if (ct.startsWith('image/')) return 'image';
if (ct === 'application/pdf') return 'pdf';
if (ct.startsWith('video/')) return 'video';
if (ct.startsWith('audio/')) return 'audio';
if (/(zip|tar|gzip|7z|rar|bzip|xz)/i.test(ct)) return 'archive';
if (/(text\/|application\/(json|xml|yaml|x-csv|jsonl))/i.test(ct)) return 'text';
return 'doc';
}
getFileTypeKind('application/pdf'); // → 'pdf'
getFileTypeKind('image/png'); // → 'image'
getFileTypeKind('application/zip'); // → 'archive'
getFileTypeKind('application/x-yaml');// → 'text'
getFileTypeKind(''); // → 'doc'
// Import any individual glyph by name, or use the dispatcher to pick
// the right one from a content-type string. Both surfaces share the
// standard IconProps shape (size, className, aria-label, etc.).
import {
FileTypeIcon,
FileIcon,
FileTextIcon,
FileImageIcon,
FilePdfIcon,
FileVideoIcon,
FileAudioIcon,
FileArchiveIcon,
getFileTypeIcon,
} from '@magicblocksai/ui';
// Direct — when the type is known at compile time.
<FilePdfIcon size={18} aria-label="PDF" />
// Dispatcher — when you have a MIME string at render time.
<FileTypeIcon contentType="application/pdf" size={18} />
<FileTypeIcon contentType="image/png" size={18} />
<FileTypeIcon contentType="application/zip" size={18} />
// As a prop / in a render list — resolve the component once.
const Icon = getFileTypeIcon(file.content_type);
<Icon size={18} aria-label={`${file.name} (${file.content_type})`} />
3.3 Misc
Sixteen glyphs that don’t belong to the CRM nav set or the file-type family — task-type icons (clock, eye, phone, trash), source-control marks (GitHub, branch), and a grab-bag of utility shapes (bolt, inbox, link, mail, menu, platform, route, shield, sync, target). Same monoline style as the CRM set; same currentColor theming.
IconFamily · misc set
.ic-cellEvery miscellaneous icon in the kit, rendered at 32px above its import name. The mix covers task-type indicators (phone call, SLA clock, review eye, destructive trash), source-control glyphs (the Octocat and a branch fork), and a set of utility shapes that span feedback (bolt, target, shield), navigation (menu, route, link), and CRM-adjacent surfaces (inbox, mail, platform, sync).
<!-- Same inline-SVG pattern as the CRM set. The misc icons follow the -->
<!-- same 18×18 / 1.5 stroke / currentColor / round caps spec. -->
<div class="ic-cell">
<span class="ic-cell-glyph" aria-hidden="true">
<svg width="32" height="32" viewBox="0 0 18 18" fill="none"
stroke="currentColor" stroke-width="1.5"
stroke-linecap="round" stroke-linejoin="round">
<circle cx="9" cy="9" r="6.25"/>
<path d="M9 5.5V9l2.5 1.75"/>
</svg>
</span>
<span class="ic-cell-name">ClockIcon</span>
</div>
/* The misc grid reuses the same .ic-grid / .ic-cell wrapper as 22.1. */
.ic-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
gap: var(--s-3);
}
.ic-cell {
display: flex; flex-direction: column;
align-items: center; justify-content: center;
gap: var(--s-3);
padding: var(--s-4) var(--s-3);
background: var(--bg-paper);
border: 1px solid var(--hair);
border-radius: var(--r-md);
}
// No inline JS needed — these are plain inline SVGs. Tint via CSS:
//
// :where(.toolbar, .nav, .sidebar) .ic-cell-glyph { color: var(--accent); }
//
// Or, swap colour on a state change:
function setIconTone(el, tone) {
el.style.color = tone === 'danger'
? 'var(--error)'
: tone === 'success'
? 'var(--success)'
: 'var(--ink)';
}
// The misc set is barrel-exported alongside the CRM and file-type sets.
import {
ClockIcon,
EyeIcon,
TrashIcon,
PhoneIcon,
BoltIcon,
InboxIcon,
LinkIcon,
MailIcon,
MenuIcon,
PlatformIcon,
RouteIcon,
ShieldIcon,
SyncIcon,
TargetIcon,
GithubIcon,
BranchIcon,
ExpandIcon,
BellIcon,
SunIcon,
MoonIcon,
SystemThemeIcon,
MessageCircleQuestionIcon,
ExternalLinkIcon,
HeartIcon,
MoreVerticalIcon,
DownloadIcon,
UploadIcon,
GlobeIcon,
MessageSquarePlusIcon,
FlaskIcon,
TrendingDownIcon,
UserCogIcon,
ArrowRightIcon,
SmartphoneIcon,
MessageSquareIcon,
CodeIcon,
ChevronDownIcon,
ChevronUpIcon,
ChevronLeftIcon,
ChevronRightIcon,
} from '@magicblocksai/ui';
// Default render.
<ClockIcon />
// Larger render with an accessible label.
<TrashIcon size={24} aria-label="Delete row" />
// Tinted via CSS — inherits `color` from any parent.
<span style={{ color: 'var(--error)' }}>
<TrashIcon />
</span>
// Inside an IconButton (chapter 3).
<IconButton aria-label="Open menu">
<MenuIcon />
</IconButton>