@texakey/ui-kit
v0.2.2
Published
Reusable NEEM React UI kit with shared components, theme tokens, and dark mode support.
Maintainers
Readme
@texakey/ui-kit
Reusable React UI kit for NEEM and related product repos, with shared components, layout primitives, sidebar/topbar chrome, feedback states, theme tokens, and dark mode support.
Install
npm install @texakey/ui-kit@^0.2.0 next-themesreact, react-dom, and next-themes are peer dependencies. The consuming app owns those versions.
lucide-react is installed as a package dependency for shared icon-based controls.
Use
Wrap the app once with ThemeProvider:
import { ThemeProvider } from '@texakey/ui-kit';
export function AppProviders({ children }: { children: React.ReactNode }) {
return (
<ThemeProvider defaultTheme="system" enableSystem>
{children}
</ThemeProvider>
);
}Import components from the package:
import { Button, Card, Input, ThemeToggle } from '@texakey/ui-kit';
export function IntakeForm() {
return (
<Card>
<Input placeholder="Patient name" />
<ThemeToggle />
<Button>Save</Button>
</Card>
);
}Use the authentication layout primitives for sign-in, registration, password reset, MFA, and invitation screens:
import {
AuthAsideBrand,
AuthAsideContent,
AuthAsideDescription,
AuthAsideEyebrow,
AuthAsideFooter,
AuthAsidePanel,
AuthAsidePulseLine,
AuthAsideTitle,
AuthBody,
AuthBrand,
AuthCheckboxRow,
AuthCodeInput,
AuthCodeMeta,
AuthDivider,
AuthField,
AuthForm,
AuthHeader,
AuthLayout,
AuthLink,
AuthMfaActions,
AuthMfaBody,
AuthMfaFooter,
AuthMfaHeader,
AuthMfaPanel,
AuthPanel,
AuthPasswordField,
AuthProviderButton,
AuthSecurityNote,
AuthSubmitButton,
AuthTopLink,
AuthTrustBar,
} from '@texakey/ui-kit';
export function SignInPage() {
return (
<AuthLayout
asidePosition="start"
aside={
<AuthAsidePanel>
<AuthAsideBrand>
<AuthBrand name="NEEM" highlight="AI" />
</AuthAsideBrand>
<AuthAsideContent>
<AuthAsideEyebrow>Ambient clinical intelligence</AuthAsideEyebrow>
<AuthAsideTitle>
Documentation that <strong>disappears</strong> into the visit.
</AuthAsideTitle>
<AuthAsideDescription>
NEEM listens, drafts the note, and surfaces the codes so clinicians stay present.
</AuthAsideDescription>
</AuthAsideContent>
<AuthAsidePulseLine />
<AuthAsideFooter>
<AuthTrustBar
items={[
{ label: 'HIPAA compliant' },
{ label: 'SOC 2 Type II' },
{ label: '2,400+ clinicians' },
]}
/>
</AuthAsideFooter>
</AuthAsidePanel>
}
>
<AuthTopLink
label="New to NEEM?"
action={<AuthLink href="/request-access">Request access</AuthLink>}
/>
<AuthPanel variant="plain">
<AuthHeader title="Sign in" subtitle="Sign in to your clinical workspace to continue." />
<AuthBody>
<AuthForm onSubmit={handleSignIn}>
<AuthField
icon="email"
label="Email address"
inputProps={{ name: 'email', placeholder: '[email protected]', type: 'email' }}
/>
<AuthPasswordField
label={<>Password <AuthLink href="/forgot-password">Forgot password?</AuthLink></>}
inputProps={{ name: 'password', placeholder: 'Password' }}
/>
<AuthCheckboxRow checked>Remember this device</AuthCheckboxRow>
<AuthSubmitButton>Sign in</AuthSubmitButton>
<AuthDivider />
<AuthProviderButton label="Continue with hospital SSO" />
<AuthSecurityNote>
By signing in you agree to the product terms and privacy policy.
</AuthSecurityNote>
</AuthForm>
</AuthBody>
</AuthPanel>
</AuthLayout>
);
}For MFA, keep the same package primitives and swap the page composition:
export function MfaPage() {
return (
<AuthLayout>
<AuthMfaPanel>
<AuthMfaHeader
title="Security verification"
subtitle="Enter the 6-digit code from your authenticator app."
/>
<AuthMfaBody>
<AuthCodeInput inputName="mfaCode" value={code} onValueChange={setCode} />
<AuthCodeMeta>Code expires in 4:07</AuthCodeMeta>
</AuthMfaBody>
<AuthMfaActions>
<AuthSubmitButton disabled={code.length !== 6}>Verify & continue</AuthSubmitButton>
</AuthMfaActions>
<AuthMfaFooter>
<AuthLink href="/resend">Resend code</AuthLink>
<span>|</span>
<AuthLink href="/login">Back to login</AuthLink>
</AuthMfaFooter>
</AuthMfaPanel>
</AuthLayout>
);
}The auth package components are layout-only. Product repos own authentication providers, validation, routing, MFA state, SSO redirects, and API calls.
For split auth screens, prefer the generic AuthAsidePanel composition when the product is not NEEM AI or needs different left-panel content. AuthMarketingAside remains available as a shortcut for simple brand/eyebrow/title/description/trust-item layouts.
Use the dashboard primitives when a product repo needs its own dashboard composition:
import {
DashboardBrand,
DashboardContent,
DashboardHero,
DashboardLayout,
DashboardNav,
DashboardPanel,
DashboardPanelHeader,
DashboardSidebar,
DashboardSidebarToggle,
DashboardSidebarUser,
DashboardTopbar,
ThemeToggle,
TopbarActions,
} from '@texakey/ui-kit';
const navItems = [
{ label: 'Dashboard', href: '/dashboard', active: true },
{ label: 'Patients', href: '/patients' },
];
export default function DashboardPage() {
return (
<DashboardLayout
sidebar={
<DashboardSidebar>
<DashboardBrand name="NEEM" highlight="AI" subtitle="Clinical documentation" />
<DashboardSidebarToggle />
<DashboardNav items={navItems} />
<DashboardSidebarUser user={{ initials: 'MD', name: 'Dr. Maya Desai', role: 'Internal Medicine' }} />
</DashboardSidebar>
}
topbar={
<DashboardTopbar
title="Dashboard"
actions={
<TopbarActions
beforeActions={<ThemeToggle />}
showNationSelector={false}
searchPlaceholder="Search patients, encounters, notes..."
/>
}
/>
}
>
<DashboardContent>
<DashboardHero title="Good afternoon, Dr. Desai" subtitle="You have 6 encounters waiting." />
<DashboardPanel>
<DashboardPanelHeader title="Today's encounters" />
{/* product-specific dashboard content goes here */}
</DashboardPanel>
</DashboardContent>
</DashboardLayout>
);
}DashboardLayout supports uncontrolled and controlled sidebar collapse:
<DashboardLayout defaultSidebarCollapsed sidebar={<DashboardSidebar>{/* ... */}</DashboardSidebar>}>
{/* ... */}
</DashboardLayout>
<DashboardLayout
sidebarCollapsed={collapsed}
onSidebarCollapsedChange={setCollapsed}
sidebar={<DashboardSidebar>{/* ... */}</DashboardSidebar>}
>
{/* ... */}
</DashboardLayout>When collapsed, the sidebar reduces to an icon rail. Menu labels remain available on hover and keyboard focus.
TopbarActions includes the enlarge-screen control by default on tablet and desktop viewports. Set showFullscreen={false} only in repos that should not enter browser fullscreen.
Use the full clinical dashboard template when a product repo wants the NEEM AI dashboard layout with minimal setup:
import { ClinicalDashboard } from '@texakey/ui-kit';
const encounters = [
{
time: '9:00 AM',
initials: 'AK',
patient: 'Amina Khan',
reason: 'Follow-up',
status: 'Live',
statusTone: 'live',
},
];
export function ClinicDashboard() {
return (
<ClinicalDashboard
brand={{ name: 'NEEM', highlight: 'AI', subtitle: 'Clinical documentation' }}
encounters={encounters}
showFullscreen
showThemeToggle
primaryAction={{ label: 'New encounter', href: '/encounters/new' }}
/>
);
}Use the clinical workspace screens when a repo needs shared clinical menu pages. Full screens are available for fast adoption, and the same module exports the smaller units for custom page composition across NEEM AI web, EHR products, portals, and platform admin:
import {
ClinicalWorkspaceLayout,
WorkspacePage,
WorkspacePanel,
} from '@texakey/ui-kit/workspace/layout';
import {
WorkspaceActionGroup,
WorkspaceSearchField,
WorkspaceTabs,
} from '@texakey/ui-kit/workspace/controls';
import { WorkspacePatientList } from '@texakey/ui-kit/workspace/patients';
import {
WorkspaceNoteSections,
WorkspaceRecordBar,
WorkspaceTranscript,
} from '@texakey/ui-kit/workspace/encounter';
import { WorkspaceCodingSuggestions } from '@texakey/ui-kit/workspace/coding';
import {
AddPatientDialog,
MagicEditDialog,
NewEncounterDialog,
NewTemplateDialog,
} from '@texakey/ui-kit/workspace/dialogs';
import {
AmbientEncounterScreen,
EncounterReviewScreen,
PatientsScreen,
TemplatesScreen,
} from '@texakey/ui-kit/workspace/screens';
export function EncountersPage() {
return <EncounterReviewScreen dialog="magic-edit" />;
}Available workspace subpaths:
@texakey/ui-kit/workspace: all workspace exports.@texakey/ui-kit/workspace/layout: shell, page, panel, and shared layout primitives.@texakey/ui-kit/workspace/controls: buttons, tabs, search, status, and action groups.@texakey/ui-kit/workspace/patients: patient avatar, queue, row, and rail components.@texakey/ui-kit/workspace/encounter: recording bar, transcript, waveform, and note sections.@texakey/ui-kit/workspace/coding: ICD/CPT suggestion cards and lists.@texakey/ui-kit/workspace/forms: form grid, option cards, summary rows, and check cards.@texakey/ui-kit/workspace/dialogs: modal shell plus Magic Edit, New Encounter, Add Patient, and New Template dialogs.@texakey/ui-kit/workspace/screens: assembled Encounter, Ambient, Patients, and Templates pages.
The reusable pieces map to the screenshots as:
ClinicalWorkspaceLayout: shared collapsible sidebar, topbar search, profile actions, and page title context.WorkspacePageHeader,WorkspacePanel,WorkspaceCardPanel: common page/menu framing.WorkspaceSearchField,WorkspaceTabs,WorkspaceActionGroup,WorkspaceStatusPill: toolbar controls.WorkspacePatientList,WorkspacePatientRail,WorkspaceAvatar: queue and patient selection.WorkspaceTranscript,WorkspaceRecordBar,WorkspaceNoteSections,WorkspaceCodingSuggestions: encounter workspace panes.WorkspaceModal,MagicEditDialog,NewEncounterDialog,AddPatientDialog,NewTemplateDialog: reusable dialog and wizard flows.
Use the shared sidebar shell for product navigation:
import {
AppShell,
Footer,
Sidebar,
SidebarBrand,
SidebarContent,
SidebarHeader,
SidebarInset,
SidebarNav,
SidebarProvider,
SidebarRail,
SidebarTrigger,
Topbar,
TopbarActions,
} from '@texakey/ui-kit';
import { LayoutDashboard, UsersRound } from 'lucide-react';
const navItems = [
{ label: 'Dashboard', href: '/dashboard', icon: <LayoutDashboard size={16} />, active: true },
{ label: 'Patients', href: '/patients', icon: <UsersRound size={16} /> },
];
export function ProductShell({ children }: { children: React.ReactNode }) {
return (
<SidebarProvider>
<AppShell>
<Topbar>
<SidebarTrigger />
<TopbarActions
nations={[
{ code: 'ke', label: 'Kenya', flag: '🇰🇪' },
{ code: 'us', label: 'United States', flag: '🇺🇸' },
]}
notifications={[
{ label: 'New lab result ready', unread: true },
{ label: 'Medication review pending' },
]}
profile={{ name: 'Care Team Admin', role: 'Platform admin', initials: 'CA' }}
/>
</Topbar>
<div style={{ display: 'flex', minHeight: '100vh' }}>
<Sidebar mobileWidth="100vw">
<SidebarHeader>
<SidebarBrand
name="Client name"
subtitle="Clinical workspace"
logoSrc="/client-logo.svg"
endSlot={<SidebarTrigger closeLabel="Close sidebar" />}
/>
</SidebarHeader>
<SidebarContent>
<SidebarNav items={navItems} />
</SidebarContent>
</Sidebar>
<SidebarRail />
<SidebarInset>
{children}
<Footer>Copyright 2026 Client</Footer>
</SidebarInset>
</div>
</AppShell>
</SidebarProvider>
);
}Theme Contract
The package exports:
ThemeProviderfor app runtime light/dark mode.StaticThemeProviderfor static previews and Storybook.createTenantThemefor tenant-specific overrides.- shared components that read the theme CSS variables.
Change design-system defaults in this repository at src/theme/tokens.ts, then publish a new package version.
Publishing
From the repository root:
npm run release:check
npm publish -w @texakey/ui-kit --access publicnpm run release:check runs DOCX generation, lint, unit tests, Storybook tests, Next build, Storybook build, consumer smoke test, and package dry-run before publishing.
