Last updated

/iblai-vibe-component

Mirrored from iblai/vibe Β· skills/start/iblai-vibe-component/SKILL.md. This page is generated β€” edit it in the repository, not here.

Overview of all ibl.ai components and how to create a new app.

Before adding a component or creating a new app, check for a iblai.env in the project root. Look for PLATFORM, DOMAIN, and TOKEN variables. If the file does not exist or is missing these variables, tell the user: "You need an iblai.env with your platform configuration. Copy the bundled template and fill in your values: cp iblai.env.example iblai.env (vibe-starter ships the example) β€” or, when the project has no iblai.env.example: curl -o iblai.env https://raw.githubusercontent.com/iblai/vibe/refs/heads/main/iblai.env"

iblai.env is NOT a .env.local replacement β€” it only holds the 3 shorthand variables. Next.js still reads runtime env vars from .env.local.

Use pnpm as the default package manager. Fall back to npm if pnpm is not installed. The generated app should live in the current directory, not in a subdirectory.

When building a navbar or header, do NOT display the organization/platform name. Use the ibl.ai logo instead.

BRAND.md is the default for colors, typography, spacing, and component styles β€” but if the project already has its own design system (downloaded from v0, a custom theme, a partner-branded shell, etc.), follow that instead. See "Detect Existing Design Style" below.

Detect Existing Design Style

Before applying any of the layout / navbar / spacing patterns later in this skill, check whether the project already has a design system in place. If it does, the project's tokens win β€” don't override them with ibl.ai brand defaults.

Signals that a design system is already present

SignalWhere to lookWhat it means
components.json exists with shadcn-style entriesrepo rootProject uses shadcn/ui (often via v0). Match its style (e.g. new-york), baseColor, and cssVariables settings.
components/ui/ is populatedcomponents/ui/*.tsxshadcn primitives already installed. Reuse them; don't add raw HTML or a different UI lib for the same primitives.
Custom CSS variables beyond shadcn defaultsapp/globals.css, styles/globals.css, app/(*)/layout.tsxE.g. --primary, --accent, --brand-*, --surface-*, custom radius / shadow tokens. These define the project palette β€” bind components to these vars, not to ibl.ai brand hex codes.
tailwind.config.{ts,mjs,js} extends colors / fontsrepo roottheme.extend.colors, theme.extend.fontFamily, etc. carry intent. Match them.
Tailwind v4 inline theme in CSS@theme { ... } block in globals.cssSame as above for Tailwind v4.
Custom font loaded via next/fontapp/layout.tsxDon't replace it. Wrap SDK components inside elements that inherit the font.
Existing app shell componentscomponents/{navbar,sidebar,header,footer,app-shell}.tsxThe project already has its layout. Plug SDK content INTO that shell, don't add a second navbar/sidebar.
BRAND.md / DESIGN.md / design-tokens.* filesrepo root, docs/, lib/The project documents its own visual language. Read it before generating anything.
Build output came from v0comments like // v0 generated, from "v0", or app/page.tsx containing v0-style scaffoldsTreat the existing components as the source of truth for style.

What "follow it" means concretely

When the project has its own design system:

  1. Use the project's CSS variables for color, radius, shadow, and spacing wherever you'd otherwise reach for an ibl.ai brand hex. If the project defines --primary, bind to that β€” not #0058cc.
  2. Reuse existing shadcn primitives in components/ui/. Don't install a duplicate (e.g. a second <Button> from a different library) and don't restyle the existing one.
  3. Plug SDK components into the existing shell, don't replace it. If the project has components/navbar.tsx, add the SDK <NotificationDropdown> and <UserProfileDropdown> inside it; don't write a new navbar.
  4. Wrap SDK components in the project's card pattern, not the ibl.ai default white card. If the project uses bg-card border border-border rounded-xl everywhere, mirror that when wrapping <Profile>, <Account>, <AnalyticsLayout>, etc.
  5. Match the project's container widths and spacing scale. If pages use max-w-screen-xl mx-auto px-6, don't introduce md:w-[75vw].
  6. Don't add the ibl.ai logo unless the project's navbar uses a logo at all. If the project has a custom wordmark or no logo, match it.
  7. Don't override SDK component internals. SDK components ship their own styling β€” your job is to bind the surrounding container to the project's tokens, not to restyle the SDK's internals.

When to fall back to the ibl.ai defaults below

If you find none of the signals above, the project has no design system yet β€” use the patterns in Layout & Page Patterns as the starting point. Those defaults are derived from vibe-starter and the reference apps in iblai/vibe.

Tell the user what you detected

Before generating, surface what you found in one line so the user can correct you:

Detected: shadcn-new-york + custom --primary (oklch(0.55 0.18 250)), existing components/navbar.tsx. I'll bind SDK components to your tokens and plug them into the existing navbar instead of creating a new one.

If you find nothing:

No existing design system detected. I'll use the ibl.ai defaults from BRAND.md.

An app on @iblai/iblai-js (the dependency, or an iblai.env) is an ibl.ai app: BRAND.md is its design system, and diverging from it β€” font, scale, accent colour, SDK internals, shell, spinner, dark mode β€” is a question for the user, never a decision. Ask with AskUserQuestion: what the language says, what would change, what it costs. The components and the probe are in House components below; the wiring and the type scale are in BRAND.md.

Creating a New App

For a brand-new project, scaffold from vibe-starter β€” a pre-wired Next.js 16 + Tailwind v4 + shadcn/ui template with ibl.ai SSO auth, a responsive navbar, and profile/account/notifications pages already in place. It ships as the iblai-vibe-ops-init skill's assets/vibe-starter/ directory; copy it into the project root, or fetch it from the vibe repo if those assets are not installed (tell the user which path you took):

cp -a <skills-dir>/iblai-vibe-ops-init/assets/vibe-starter/. .
# or, without local assets:
git clone --depth 1 https://github.com/iblai/vibe.git vibe-tmp && cp -a vibe-tmp/skills/start/iblai-vibe-ops-init/assets/vibe-starter/. . && rm -rf vibe-tmp

pnpm install --ignore-scripts

Run with --ignore-scripts to skip package lifecycle (postinstall) scripts.

Fill iblai.env with PLATFORM/TOKEN, then map them into .env.local (NEXT_PUBLIC_MAIN_TENANT_KEY ← PLATFORM, IBLAI_API_KEY ← TOKEN).

To build up from a bare Next.js app instead, start with npx create-next-app@latest, run the /iblai-vibe-auth skill (it creates the auth files), then add features with the skills below. The whole-app scaffold (base/agent project templates) lives in /iblai-vibe-scaffold.

Available Components

FeatureWhat It AddsSkill
MCP + skills@iblai/mcp server + skills (set up first)
AuthenticationSSO authentication/iblai-vibe-auth
Agent chatFull in-process agent chat surface/iblai-vibe-agent-chat
ProfileUser profile dropdown/iblai-vibe-profile
AccountAccount/organization settings/iblai-vibe-account
AnalyticsAnalytics dashboard/iblai-vibe-analytics
NotificationsNotification bell/iblai-vibe-notification
InvitationsUser invitation dialogs/iblai-vibe-invite
WorkflowsWorkflow builder components/iblai-vibe-workflow
Desktop/mobileTauri v2 desktop/mobile shell/iblai-vibe-ops-build

Layout & Page Patterns

Use these only when the project has no existing design system (see the detection step above). When the project already defines its own tokens, navbar, page widths, or card styling, mirror those instead of the patterns below.

Page background

The page background should be var(--sidebar-bg, #fafbfc) (light gray). Set in globals.css:

@layer base {
  body {
    background-color: var(--sidebar-bg, #fafbfc);
  }
}

SDK component wrappers

SDK components (Profile, Account, AnalyticsLayout) have no outer background. Wrap them in a white container so they render as cards:

<div className="mx-auto w-full flex-1 overflow-auto px-4 py-8 md:w-[75vw] md:px-0">
  <div className="rounded-lg border border-[var(--border-color)] bg-white overflow-hidden">
    <SdkComponent ... />
  </div>
</div>

Responsive width

Use w-full px-4 on mobile, md:w-[75vw] md:px-0 on desktop for all page content and the navbar inner container. This keeps everything aligned.

Use a sticky top navbar with frosted glass effect, ibl.ai logo on the left, nav links next to it, and profile dropdown on the right:

<header className="sticky top-0 z-50 flex-shrink-0 border-b border-[var(--border-color)] bg-white/80 backdrop-blur-xl backdrop-saturate-150">
  <div className="mx-auto flex h-14 w-full items-center px-4 md:w-[75vw] md:px-0">
    {/* Mobile hamburger (Sheet) */}
    {/* Logo */}
    {/* Desktop nav links with bottom-border active state */}
    {/* Profile dropdown ml-auto */}
  </div>
</header>

Key navbar details:

  • Active link: border-b-2 border-[var(--primary-color)] text-[var(--primary-color)]
  • Inactive link: border-transparent text-[var(--text-secondary)] hover:text-[var(--text-primary)]
  • Mobile: Use shadcn Sheet with side="left" for a slide-out drawer. Note: shadcn Sheet uses @base-ui/react/dialog, NOT Radix. The asChild prop is NOT available on SheetTrigger.
<footer className="flex-shrink-0 border-t border-[var(--border-color)]">
  <div className="mx-auto flex h-11 w-full items-center justify-between px-4 text-xs text-[var(--text-muted)] md:w-[75vw] md:px-0">
    <p>&copy; {new Date().getFullYear()} ibl.ai</p>
    <div className="flex items-center gap-5">
      {/* Docs, Privacy, Terms links */}
    </div>
  </div>
</footer>

House components

In an app on @iblai/iblai-js the three starter files come first: components/page-header.tsx, components/empty-state.tsx and components/loading-screen.tsx. A project that did not start from the starter copies them from https://raw.githubusercontent.com/iblai/vibe/refs/heads/main/skills/start/iblai-vibe-ops-init/assets/vibe-starter/components/<file>. The examples in this skill's assets/ are copy-ready and typechecked against the starter (test.json maps each to its path).

ComponentUseExample
Page headertitle (+ count) left, actions right; a page is the header, then flex-1 overflow-autoassets/notes-page.tsx
Empty statedashed card, icon tile in the brand tint, one line of help, one actionassets/notes-empty.tsx
Loadingthe OS arc, full page or an opaque overlay while saving; never grey "Loading..." textassets/notes-loading.tsx
Section cardthe starter's Card with the house border, text-sm font-semibold titleassets/note-card.tsx
Form fieldLabel + Input + text-xs text-muted-foreground help, text-xs text-red-500 errorassets/note-form.tsx
Dialog footeroutline cancel, ibl-button-primary confirm with the SDK Spinner size="sm" while pendingassets/delete-note-dialog.tsx
Tablea plain table in the bordered white box; shadcn table only for its wrappersassets/notes-table.tsx
Status badgeBadge with a dot: grey by default, emerald/rose for good/bad, the brand tint for selectedassets/note-status.tsx
Toast, shellsonner (toast.success); the SDK SidebarProvider β†’ PlatformSidebar + SidebarInset, never a local copy; top navbar: /iblai-vibe-navbarβ€”

Primary action ibl-button-primary, cancel variant="outline"; Lucide strokeWidth={1.75}; a status dot is grey unless it means good or bad.

Check painted values, on a page that is still your app (unauthenticated routes leave for sign-in within seconds), because the minifier rewrites oklch() to lab():

const probe = (cls) => { const d = document.createElement("div"); d.className = cls; document.body.appendChild(d); const cs = getComputedStyle(d); d.remove(); return cs; };
getComputedStyle(document.body).fontFamily; // starts with "Open Sans"
probe("bg-primary").backgroundColor; // "rgb(0, 88, 204)"; probe("font-semibold").fontWeight β†’ "500"

All components below are from @iblai/iblai-js/web-containers. Use MCP tools (get_component_info, get_hook_info) for full props and usage examples.

Auto-generated from @iblai/web-containers type declarations. Re-generate with iblai update-gallery <path> β€” behavior + --screenshots flags in references/update-gallery-command.md.

Authentication & SSO

ExportImportDescription
DEFAULT_SSO_STORAGE_KEYSssoDefault localStorage key constants for SSO
LoginButtonrootAuth login button -- redirects to authUrl with redirect options
SignupButtonrootSignup button -- opens signup flow, optionally in new tab
SsoLoginnextSSO callback handler -- stores tokens from URL into localStorage and redirects
import { DEFAULT_SSO_STORAGE_KEYS } from "@iblai/iblai-js/web-containers/sso";
import { LoginButton, SignupButton } from "@iblai/iblai-js/web-containers";
import { SsoLogin } from "@iblai/iblai-js/web-containers/next";

User Profile & Account

ExportImportDescription
AccountnextAccount/org settings with tabs (Organization, Management, Integrations, Advanced, Billing)
CompanyDialogrootCompany selection dialog
EducationDialogrootDialog for adding/editing education
EducationTabrootEducation background management
ExperienceDialogrootDialog for adding/editing experience
ExperienceTabrootProfessional experience management
InstitutionDialogrootInstitution selection dialog
InviteUserDialogrootDialog to invite users to a platform
InvitedUsersDialogrootDialog showing pending invitations
LocalLLMTabrootLocal LLM model management (Tauri desktop)
OrganizationTabnextOrganization settings tab
ProfilerootFull inline profile management (use for /profile page)
ResumeTabrootResume upload and display
UserProfileDropdownnextAvatar dropdown with profile, organization, platform switcher, logout
UserProfileModalnextProfile editing modal/dialog (use for overlay, NOT for a page)
import { Account, OrganizationTab, UserProfileDropdown, UserProfileModal } from "@iblai/iblai-js/web-containers/next";
import { Profile, CompanyDialog, EducationDialog, EducationTab, ExperienceDialog, ExperienceTab, InstitutionDialog, ... } from "@iblai/iblai-js/web-containers";

Profile vs UserProfileModal: Profile renders inline (full page). UserProfileModal renders as a dialog overlay. Use Profile for a dedicated /profile route. Use UserProfileModal for a quick-edit overlay.

Platform & Organization

ExportImportDescription
TenantSwitcherrootSwitch between platforms/organizations with RBAC support
import { TenantSwitcher } from "@iblai/iblai-js/web-containers";

Analytics

ExportImportDescription
AccessTimeHeatmaprootAccess time heatmap visualization
AnalyticsCourseDetailrootSingle course detail view
AnalyticsCoursesrootCourse analytics listing
AnalyticsFinancialStatsrootFinancial/billing statistics
AnalyticsLayoutrootLayout wrapper for analytics pages with built-in tab navigation
AnalyticsOverviewrootOverview dashboard with key metrics
AnalyticsProgramDetailrootSingle program detail view
AnalyticsProgramsrootProgram analytics listing
AnalyticsReportDownloadrootDownload analytics reports
AnalyticsReportsrootReport listing and management
AnalyticsSettingsProviderrootContext provider for analytics settings (required wrapper)
AnalyticsTopicsStatsrootTopic/conversation statistics
AnalyticsTranscriptsStatsrootTranscript browsing and search
AnalyticsUsersStatsrootUser activity statistics
ChartCardWrapperrootWrapper for chart visualizations
ChartFiltersProviderrootContext provider for chart filter state
CustomDateRangePickerrootCustom date range selector
EmptyStatsrootEmpty state placeholder for stats
GroupsFilterDropdownrootFilter analytics by user groups
StatCardrootSingle statistic card
TimeFilterrootTime range filter dropdown
import { AnalyticsLayout, AnalyticsSettingsProvider, AnalyticsOverview, AnalyticsCourses, AnalyticsPrograms, AnalyticsFinancialStats, AnalyticsUsersStats, AnalyticsTopicsStats, AnalyticsTranscriptsStats, AnalyticsReports } from "@iblai/iblai-js/web-containers";

AnalyticsFinancialStats does NOT accept a basePath prop. All other analytics sub-page components do.

Notifications

ExportImportDescription
AlertsTabrootAlert management tab
EditAlertDialogrootDialog to create/edit alerts
NotificationDisplayrootFull notification center with Inbox and Alerts tabs
NotificationDropdownrootBell icon with unread badge -- compact navbar widget
SendNotificationDialogrootDialog to compose and send notifications (admin)
import { AlertsTab, EditAlertDialog, NotificationDisplay, NotificationDropdown, SendNotificationDialog } from "@iblai/iblai-js/web-containers";

Agent UI (App Shell)

ExportImportDescription
AppSidebarnextCollapsible sidebar with menu items, projects, pinned/recent messages
ConversationStartersnextGuided prompt cards for starting conversations
NavBarnextTop navigation bar with user menu, agent dropdown, new chat action
import { AppSidebar, ConversationStarters, NavBar } from "@iblai/iblai-js/web-containers/next";

Workflows

ExportImportDescription
ConnectorManagementDialogrootConnector setup and management
CreateWorkflowModalrootCreate new workflow modal
DeleteWorkflowModalrootDelete workflow confirmation
ToolDialogsrootTool configuration dialogs
WorkflowSidebarrootWorkflow node type browser sidebar
import { ConnectorManagementDialog, CreateWorkflowModal, DeleteWorkflowModal, ToolDialogs, WorkflowSidebar } from "@iblai/iblai-js/web-containers";

Content & Display

ExportImportDescription
CopyButtonIconrootCopy-to-clipboard button icon
LoaderrootLoading overlay component
MarkdownrootMarkdown renderer with syntax highlighting and copy buttons
RichTextEditorrootTiptap-based rich text editor (HTML or Markdown output)
SearchableMultiSelectrootMulti-select dropdown with search filtering
SpinnerrootLoading spinner (sm, md, lg)
TimeTrackingProviderrootProvider for automatic time tracking
TopBannerrootDismissible top banner notification bar
VersionrootApp version display footer
import { CopyButtonIcon, Loader, Markdown, RichTextEditor, SearchableMultiSelect, Spinner, ... } from "@iblai/iblai-js/web-containers";

Error Handling

ExportImportDescription
ClientErrorPagenextClient-side error boundary page
ErrorPagenextError page with code, message, support link, home button
import { ClientErrorPage, ErrorPage } from "@iblai/iblai-js/web-containers/next";

Hooks & Utilities

ExportImportDescription
TAURI_COMMANDSrootTauri IPC command name constants
TAURI_EVENTSrootTauri event name constants
import { TAURI_COMMANDS, TAURI_EVENTS } from "@iblai/iblai-js/web-containers";

UI Primitives (Shadcn/Radix)

These are bundled with the SDK and share the ibl.ai Tailwind theme. Available when you need lower-level building blocks inside SDK component customizations:

AlertDialog, Avatar, Badge, Button, Calendar, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Chart, Checkbox, Dialog, DropdownMenu, Input, Label, Pagination, Popover, Progress, RadioGroup, Select, Separator, Sheet, Sidebar, Skeleton, Sonner, Switch, Table, Tabs, Textarea, Toast, Toaster, Toggle, Tooltip

Note: For your own UI, install shadcn/ui directly (npx shadcn@latest add ...) rather than importing these from the SDK. The SDK exports are for internal use and SDK component customization.

Component Priority

  1. ibl.ai components first -- always use the native component when one exists
  2. shadcn/ui for everything else -- forms, tables, modals, date pickers, etc.:
    npx shadcn@latest add button dialog table form
  3. shadcnspace blocks -- pre-built page sections:
    npx shadcn@latest add @shadcn-space/hero-01
    Full block catalog, install flow, and brand-consistency rules: references/shadcnspace-blocks.md.

ibl.ai and shadcn components share the same Tailwind theme and are visually seamless.

SDK Styling Notes

  • SDK components use Tailwind classes internally (bg-white, bg-gray-50, bg-[#f5f7fb]). Do NOT override these globally.
  • To make SDK components look correct on a gray page background, wrap them in a bg-white rounded-lg border border-[var(--border-color)] overflow-hidden container.
  • The AnalyticsLayout hardcodes bg-[#f5f7fb] for its background. If you need white, add a targeted CSS override in globals.css:
    .bg-\[\#f5f7fb\] {
      background-color: #ffffff !important;
    }
  • shadcn Sheet uses @base-ui/react/dialog, NOT Radix. The asChild prop is NOT available on SheetTrigger.

Requirements

  • Next.js App Router project (app/ directory)
  • Node.js 18+
  • The @iblai/mcp server + skills configured in .mcp.json
  • Auth set up first via /iblai-vibe-auth (other components depend on the auth providers) β€” or start from vibe-starter, which already has it
  • Brand guidelines: BRAND.md

Copyright Β© ibl.ai | support@iblai.zendesk.com