chordia-ui
v3.9.6
Published
Chordia Design System - UI components, tokens, and Tailwind preset
Downloads
2,618
Maintainers
Readme
chordia-ui
Chordia Design System — UI components, design tokens, and Tailwind CSS preset for the Chordia conversation intelligence platform. Published to npm as chordia-ui.
Philosophy
- Evidence-based, explainable interfaces
- "No Judgment" principle: colors categorize, never indicate good/bad
- Clarity over cleverness
- Calm interfaces that build trust through transparency
Installation
npm install chordia-uiPeer Dependencies
Make sure your app has these installed (they are peer deps of chordia-ui):
npm install react react-dom lucide-react rechartsUsage
1. Import the Tailwind Preset (optional)
In your tailwind.config.js:
module.exports = {
presets: [require('chordia-ui/tailwind-preset')],
content: [
'./src/**/*.{js,jsx,ts,tsx}',
// If you want Tailwind to see chordia-ui classNames:
'./node_modules/chordia-ui/dist/**/*.{js,jsx}',
],
// your overrides...
};2. Import Design Tokens
In your global CSS (e.g. globals.css):
@import 'chordia-ui/tokens';Or import individual token files:
@import 'chordia-ui/tokens/colors.css';
@import 'chordia-ui/tokens/typography.css';
@import 'chordia-ui/tokens/spacing.css';3. Use Components
import { Card, SmallButton, SignalCard, ScoreDriverCard, DeviationIndicator } from 'chordia-ui';You can also import feature-specific shells, like the reusable overlay panel for modals/dialogs:
import { OverlayPanel } from 'chordia-ui/components/models';4. Optional toast integration (DataTable)
Some components (like DataTable) emit semantic events instead of importing a toast library directly. For example, DataTable exposes an onMaxColumnsError callback that fires when a user tries to select more than the allowed number of columns, or makes an invalid drag-and-drop move involving the pinned action column. How you surface that error is up to the host app:
npm install react-hot-toast// In your app root/layout
import { Toaster } from 'react-hot-toast';
export function RootLayout({ children }) {
return (
<>
{children}
<Toaster position="bottom-right" reverseOrder={false} />
</>
);
}// Where you render DataTable
import toast from 'react-hot-toast';
import { DataTable } from 'chordia-ui/components/data';
<DataTable
{...props}
onMaxColumnsError={(message) => toast.error(message, { id: 'max-columns-toast' })}
/>;If you omit onMaxColumnsError, the table still works; users just will not see feedback for these blocked column actions.
5. DataTable theming note
DataTable uses design tokens for top surfaces (header row, filter row, and top control strip). Set --primary-foreground in your host theme to control these backgrounds consistently across table chrome.
LoginPage Integration
LoginPage delegates all auth behavior to host callbacks.
Expected props
<LoginPage
descopeProjectId={process.env.NEXT_PUBLIC_DESCOPE_PROJECT_ID}
loading={loading}
error={error}
codeError={codeError}
onLogin={handleLogin}
onOneTimeCode={handleOneTimeCode}
onVerifyCode={handleVerifyCode}
onResendCode={handleResendCode}
onSignUp={handleSignUp}
onGoToLogin={() => { setError(null); setCodeError(false); }}
onDescopeSuccess={() => router.push('/')}
onDescopeError={() => setError('Could not log in via SSO. Please try again.')}
/>Button -> callback mapping
Sign In->onLogin(email, password)Send One-time Code->onOneTimeCode(email)Verify Code->onVerifyCode(email, otp)Verify & Sign In->onOneTimeCode(email, fullName, otp)Resend->onResendCode(email)
Important: onOneTimeCode has 2 signatures
Handle both host-side:
handleOneTimeCode(email)for send OTPhandleOneTimeCode(email, fullName, otp)for verify + sign in flow
Example:
async function handleOneTimeCode(email, fullName, otp) {
if (!email) return;
if (fullName && otp) {
return handleVerifyCode(email, otp, fullName);
}
// otherwise: send OTP API call
}OTP error display
LoginPage renders the external error prop on OTP verification screens.
If your verify API returns:
{ "detail": "Invalid or expired OTP" }set error to that message in host state to show it in the UI.
ChatHistoryPanel Integration
ChatHistoryPanel shows a searchable list of chat threads and exposes optional inline rename and inline delete behaviors on each thread row. Both behaviors are opt-in — they appear only when the corresponding callback prop is provided.
Props
<ChatHistoryPanel
threads={threads} // [{ id, title, created_at, updated_at, message_count, last_message_preview, pinned, ... }]
activeThreadId={activeThreadId}
onSelectThread={(id) => setActive(id)}
onNewChat={() => createThread()}
onRenameThread={(id, newTitle) => renameThread(id, newTitle)} // optional — enables inline rename (Pencil icon)
onDeleteThread={(id) => deleteThread(id)} // optional — enables inline delete (Trash2 icon)
loading={loading}
/>Inline edit / delete behavior
- Hover a thread row →
PencilandTrash2icons (fromlucide-react) appear, absolutely positioned to the right of the title with a row-colored backdrop so they overlay the title text instead of pushing it. Clicking either icon does not select the thread (event propagation is stopped). - Inline rename (
Pencil) — replaces the title with an auto-focused input. ASave/Canceltext row appears below the input.Entersaves,Esccancels. Empty/whitespace-only titles are rejected. On save,onRenameThread(id, trimmedTitle)is invoked. - Inline delete (
Trash2) — shows a compact confirmation row below the title:Confirm: delete this thread?+ a neutralDeletebutton + a plainCancellink. No modal, nowindow.confirm. On confirm,onDeleteThread(id)is invoked. - Backwards compatible — if
onRenameThread/onDeleteThreadare omitted, no hover icons are rendered and the panel behaves identically to before.
Component Categories
| Category | Components | |---|---| | Primitives | Card, DetailCard, SmallButton, Tag, Badge, SectionLabel, Checkbox, TextInput, TextArea, Select, FormLabel, InlineConfirm, Tabs, Tooltip, DeviationIndicator, ColorPalette | | Data | DataTable, DataTableFilters, SummaryStatsPanel | | Interaction Details / Compass | SignalCard, ObservationCard, SmallObservationCard, ScoreDriverCard, ScoreDriverCardVariant, ConditionCard, ModelScoreCard, SummarySection, ExpandPatternComparison | | Media | TranscriptCard, Timeline, ConversationTurn, InteractionSummaryCard | | Chat | ChatInterface, ChatMessage, ChatHistoryPanel, MessageThread | | Navigation | Sidebar, NavigationBar | | Layout | FirstCallScreen, OnboardingChecklist, DemoProjectBanner, IntegrationCard, SplitPane | | Notifications | NotificationPanel, NotificationItem |
Utilities
import { cn } from 'chordia-ui/utils';
// Tailwind class merging utility (clsx + tailwind-merge)Development
This package now ships a built library in dist/. Consuming apps import from the npm package (chordia-ui) and do not need special transpile configuration in most bundlers. Tailwind-specific configuration is only needed if you want Tailwind to scan chordia-ui’s class names.
Docs
See docs/UIComponentsPage.jsx for a comprehensive component showcase with sample data.
