hazo_ihelp
v2.3.0
Published
Contextual popup help system for React/Next.js applications. Provides hierarchical help topics, rich HTML content, context-aware search, and a full CRUD editor.
Readme
hazo_ihelp
Contextual popup help system for React/Next.js applications. Provides hierarchical help topics, rich HTML content, context-aware search, and a full CRUD editor.
Installation
npm install hazo_ihelpPeer Dependencies
| Package | Required | Notes |
|---------|----------|-------|
| react | ^18 or ^19 | Required |
| react-dom | ^18 or ^19 | Required |
| tailwindcss | ^4.2.4 | Required for styling |
| @tailwindcss/typography | >=0.5.0 | Required — prose classes for rich content rendering |
| hazo_core | ^1.2.0 | Required — error classes, correlation IDs, config/logger |
| hazo_ui | ^4.4.0 | Required — shared UI primitives + cn() |
| next | ^14 or ^16 | Optional — needed for API handlers |
| hazo_connect | ^3.8.0 | Optional — needed for API handlers |
| hazo_config | ^2.3.0 | Optional — INI config loading |
| hazo_logs | ^2.1.1 | Optional — structured logging |
| hazo_auth | ^10.4.1 | Optional — multi-tenant scoping |
| hazo_chat | ^6.0.0 | Optional |
| hazo_files | ^3.1.0 | Optional — image upload handling |
| hazo_llm_api | ^2.1.0 | Optional |
| hazo_notes | ^2.0.0 | Optional |
Tailwind v4 Setup (Required)
hazo_ihelp uses Tailwind utility classes internally. Tailwind v4's JIT compiler only scans your project files by default — it does not scan node_modules/. You must add a @source directive so Tailwind generates CSS for the package's classes.
In your globals.css, add this after the tailwind import:
@import "tailwindcss";
/* Required: tell Tailwind to scan hazo_ihelp for utility classes */
@source "../node_modules/hazo_ihelp/dist";Adjust the relative path if your CSS file is not at the standard app/globals.css location.
Without this directive, the Help dialog will render with correct structure and dark theme colors (these use inline styles), but will have:
- Missing hover effects on topic cards
- Inconsistent spacing and padding in inner content
- Unstyled badges and tags
- Missing scrollbar customization
- Rich content appears as plain text — headings, bullet points, bold, and other formatting will be invisible because Tailwind's
proseclasses are not compiled
Tailwind Typography Plugin (Required)
The rich content editor and Help dialog use Tailwind's prose classes to render HTML content (headings, lists, bold, etc.). Install the typography plugin:
npm install @tailwindcss/typographyTailwind v4 auto-detects installed plugins. For Tailwind v3, add it to your tailwind.config.js plugins array.
Without this plugin, imported or authored rich content will appear as unstyled plain text — all formatting (headings, bullet points, bold) will be invisible even though the HTML is preserved correctly in the database.
Quick Start
1. Run the database migration
Execute the SQL migration to create the required tables:
# The schema setup files are included in the package
cat node_modules/hazo_ihelp/db_setup_postgres.sql # PostgreSQL
cat node_modules/hazo_ihelp/db_setup_sqlite.sql # SQLiteThis creates the hazo_ihelp_topics table — help topics with tags and context mappings stored as JSON columns. (The shared hazo_config table is owned by hazo_config and is not created here.)
The setup files document both SQLite and PostgreSQL variants:
| Column | SQLite | PostgreSQL |
|--------|--------|------------|
| id | TEXT (UUID string) | UUID (gen_random_uuid) |
| scope_id | TEXT | UUID |
| is_published | INTEGER (0/1) | BOOLEAN |
| tags | TEXT (JSON string) | JSONB |
| contexts | TEXT (JSON string) | JSONB |
| created_at | TEXT (datetime) | TIMESTAMPTZ |
2. Set up API routes (Next.js)
// app/api/ihelp/topics/route.ts
import { createIhelpHandler } from 'hazo_ihelp/api';
import { getHazoConnectSingleton } from 'hazo_connect/nextjs/setup';
export const dynamic = 'force-dynamic';
const { GET, POST } = createIhelpHandler({
getHazoConnect: () => getHazoConnectSingleton(),
});
export { GET, POST };// app/api/ihelp/topics/[id]/route.ts
import { createIhelpHandler } from 'hazo_ihelp/api';
import { getHazoConnectSingleton } from 'hazo_connect/nextjs/setup';
export const dynamic = 'force-dynamic';
const { PATCH, DELETE } = createIhelpHandler({
getHazoConnect: () => getHazoConnectSingleton(),
});
export { PATCH, DELETE };3. Add the Provider
Wrap your app (or a subtree) with IhelpProvider:
import { IhelpProvider } from 'hazo_ihelp';
export default function Layout({ children }) {
return (
<IhelpProvider api_base_url="/api/ihelp/topics">
{children}
</IhelpProvider>
);
}4. Add help icons to your forms
import { IhelpIcon } from 'hazo_ihelp';
function MyFormField() {
return (
<label>
Salary & Wages
<IhelpIcon context_key="tax.salary_wages" />
</label>
);
}Clicking the icon opens the Help search dialog, pre-filtered to topics mapped to that context key.
Components
IhelpProvider
Context provider that supplies topics, search, and keyboard shortcuts to all child components.
<IhelpProvider
api_base_url="/api/ihelp/topics" // Base URL for the topics API
scope_id="org-uuid" // Optional: multi-tenant scoping
search_shortcut="mod+k" // Optional: keyboard shortcut (default: mod+k)
asset_base_url="/api/ihelp/assets" // Optional: base URL for topic images
theme={{ // Optional: override default dark theme
background: '#1a2332',
foreground: '#e2e8f0',
muted_foreground: '#94a3b8',
border: '#2d3f56',
accent: '#253347',
primary: '#38bdf8',
}}
labels={{ // Optional: UI label overrides
search_placeholder: 'Search help topics...',
dialog_title: 'Help',
}}
>
{children}
</IhelpProvider>IhelpFieldHelp
Inline help icon designed for use inside form field labels. Thin wrapper over HoverHelpIcon with defaults tuned for the field-label context: smaller icon (13 px), aria_label auto-derived from title.
import { IhelpFieldHelp } from 'hazo_ihelp';
<label className="flex items-center gap-1">
Tax File Number
<IhelpFieldHelp
title="Tax File Number"
body="Your 9-digit TFN issued by the ATO."
/>
</label>Props: title (string), body (string or ReactNode), size (default 13), side ("top" | "right" | "bottom" | "left", default "top"), className.
IhelpIcon
Small trigger button that opens the Help dialog for a specific context key.
<IhelpIcon context_key="deductions.work_from_home" size={16} />IhelpSearchDialog
The Help search dialog. Usually opened via IhelpIcon or keyboard shortcut, but can be controlled directly:
<IhelpSearchDialog
open={isOpen}
onOpenChange={setIsOpen}
initial_context_key="tax.dividends"
/>IhelpEditor
Full CRUD editor for managing help topics (tags and context mappings are embedded JSON on each topic).
<IhelpEditor
api_url="/api/ihelp/topics" // Topics API URL (default: /api/ihelp)
upload_url="/api/ihelp/upload" // Optional: image upload endpoint
config_api_url="/api/ihelp/config" // Optional: context key config endpoint
scope_id="org-uuid" // Optional: multi-tenant scoping
/>Exports
| Import path | Contents |
|-------------|----------|
| hazo_ihelp | Client components: IhelpProvider, IhelpIcon, IhelpFieldHelp, IhelpSearchDialog, IhelpDetailPanel |
| hazo_ihelp/runtime | Lean runtime entry — help consumption surface (provider, icons, search dialog, detail panel, field help, hooks) without the Tiptap/dnd-kit editor. Use this in consumers that only need to display help, not author it. |
| hazo_ihelp/api | Server handlers: createIhelpHandler, createImageUploadHandler, createConfigHandler |
| hazo_ihelp/hooks | Hooks: use_ihelp, use_ihelp_search, use_ihelp_editor, use_ihelp_config |
| hazo_ihelp/components | All components including IhelpEditor and UI primitives |
| hazo_ihelp/types | TypeScript type definitions |
Theme
The Help dialog ships with a built-in dark theme that works out of the box. Pass a theme prop to IhelpProvider to override:
const customTheme = {
background: '#1a2332', // Dialog background
foreground: '#e2e8f0', // Primary text
muted_foreground: '#94a3b8', // Secondary text
border: '#2d3f56', // Border color
accent: '#253347', // Hover background
primary: '#38bdf8', // Accent color (links, highlights)
};
<IhelpProvider theme={customTheme}>License
MIT
