@metricinsights/concierge v1.0.0
@metricinsights/concierge
Metric Insights Concierge Component
A versatile chat interface component that can be integrated into any React application. It provides a customizable chat experience with support for rich content, themes, and custom actions.
Key Features
- Real-time chat interface with streaming support
- Customizable themes (light/dark)
- Rich content blocks with HTML support
- Custom positioning and styling
- Action system for custom interactions
- Message history management
- Custom rendering capabilities
Installation
npm install @metricinsights/concierge
# or
yarn add @metricinsights/conciergeBasic Usage
import { ConciergeProvider, Concierge } from '@metricinsights/concierge';
import '@metricinsights/concierge/dist/styles.css';
import 'katex/dist/katex.min.css'; // KaTeX styles support
function App() {
return (
<ConciergeProvider defaultOpen={false} defaultTheme="light" defaultPosition="bottom-right">
<Concierge title="Basic Concierge" />
</ConciergeProvider>
);
}Theme Customization
The component supports both light and dark themes:
// Light Theme
<ConciergeProvider defaultTheme="light">
<Concierge title="Light Theme" />
</ConciergeProvider>
// Dark Theme
<ConciergeProvider defaultTheme="dark">
<Concierge title="Dark Theme" />
</ConciergeProvider>Position Variants
The component can be positioned in four different corners:
// Top Left
<ConciergeProvider defaultPosition="top-left">
<Concierge title="Top Left" />
</ConciergeProvider>
// Top Right
<ConciergeProvider defaultPosition="top-right">
<Concierge title="Top Right" />
</ConciergeProvider>
// Bottom Left
<ConciergeProvider defaultPosition="bottom-left">
<Concierge title="Bottom Left" />
</ConciergeProvider>
// Bottom Right
<ConciergeProvider defaultPosition="bottom-right">
<Concierge title="Bottom Right" />
</ConciergeProvider>Custom Components
You can customize the rendering of different message types:
<ConciergeProvider>
<Concierge
title="Custom Components"
components={{
Text: ({ block, message }) => (
<div style={{
padding: '10px',
backgroundColor: message.type === 'user' ? '#e3f2fd' : '#f5f5f5',
borderRadius: '8px',
}}>
{block.content}
</div>
),
Element: ({ block, message }) => (
<div style={{
padding: '10px',
backgroundColor: '#fff',
border: '1px solid #eee',
borderRadius: '8px',
}}>
<Element markdown={block.raw} />
</div>
),
Error: ({ block, message }) => (
<div style={{
padding: '10px',
backgroundColor: '#fee2e2',
color: '#dc2626',
borderRadius: '8px',
display: 'flex',
alignItems: 'center',
gap: '8px',
}}>
<span>⚠️</span>
{block.content}
</div>
),
}}
/>
</ConciergeProvider>Custom Actions
You can register custom actions using the useActionContext hook:
const CustomActionsConcierge = () => {
const { registerAction } = useActionContext();
useEffect(() => {
registerAction('click', 'customAction', () => {
console.log('Custom action triggered!');
});
}, [registerAction]);
return (
<Concierge
title="Custom Actions Concierge"
components={{
Element: ({ block }) => (
<div onClick={() => block.raw === 'custom' && console.log('Custom element clicked!')}>
<Element markdown={block.raw} />
</div>
),
}}
/>
);
};Message History
Initialize the component with message history:
const exampleMessagesWithBlocks: Message[] = [
{
id: '1',
content: '',
timestamp: new Date(),
type: 'assistant',
blocks: [
{
type: 'html',
content: '<div class="action-badge">Analyzing request...</div>',
startIndex: 0,
endIndex: 0,
raw: '',
},
{
type: 'html',
content: '<div class="links">Here are some helpful links...</div>',
startIndex: 0,
endIndex: 0,
raw: '',
}
],
}
];
<ConciergeProvider defaultMessages={exampleMessagesWithBlocks}>
<Concierge title="Message History" />
</ConciergeProvider>Custom Render
You can completely customize the UI using the render prop:
<ConciergeProvider>
<Concierge
title="Custom Render"
render={({
isOpen,
toggleOpen,
messages,
addMessage,
updateMessage,
clearMessages,
isLoading,
error,
theme,
position,
input,
setInput,
sendMessage,
cancelRequest,
components,
}) => (
<div style={{
position: 'relative',
width: '100%',
backgroundColor: theme === 'dark' ? '#1f2937' : '#ffffff',
color: theme === 'dark' ? '#f3f4f6' : '#1f2937',
borderRadius: '12px',
boxShadow: '0 4px 6px -1px rgb(0 0 0 / 0.1)',
overflow: 'hidden',
display: 'flex',
flexDirection: 'column',
height: '400px',
maxWidth: '400px',
margin: '0 auto',
}}>
{/* Custom UI implementation */}
</div>
)}
/>
</ConciergeProvider>Component Structure
1. ConciergeProvider
Context provider for Concierge functionality.
Props:
defaultOpen: boolean - Initial open statedefaultTheme: 'light' | 'dark' - Initial themedefaultPosition: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' - Initial positiondefaultMessages: Message[] - Initial message historyapiOptions:useStreaming: booleanheaders: Record<string, string>
2. Concierge
Main chat interface component.
Props:
title: string - Chat window titlecomponents:Element: (props: { block: Block }) => React.ReactNode - Custom component renderers
render: (props: ConciergeRenderProps) => React.ReactNode - Custom render function
Data Structures
Message Structure
interface Message {
id: string;
content: string;
timestamp: Date;
type: 'user' | 'assistant';
blocks?: Block[];
}Block Structure
interface Block {
type: string;
content: string;
startIndex: number;
endIndex: number;
raw: string;
}Styling
The component uses SCSS for styling with the following structure:
styles.scss- Main styles file_variables.scss- Theme variables and configuration_mixins.scss- Reusable style mixinsaction-badge.scss- Action badge styles
Theme Customization
The component supports light and dark themes with the following classes:
.light- Light theme (default).dark- Dark theme
Position Customization
The component can be positioned using the following classes:
.bottom-right- Bottom right corner (default).bottom-left- Bottom left corner.top-right- Top right corner.top-left- Top left corner
Available Variables
// Colors
$primary-color: #2563eb;
$secondary-color: #1e40af;
$background-light: #ffffff;
$background-dark: #1f2937;
$text-light: #1f2937;
$text-dark: #f3f4f6;
// Layout
$border-radius: 8px;
$shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
$transition: all 0.3s ease;
// Component dimensions
$concierge-width: 380px;
$concierge-height: 500px;
$concierge-max-width: 90vw;
$concierge-max-height: 80vh;
$concierge-z-index: 1000;
// Spacing
$spacing-xs: 0.5rem;
$spacing-sm: 0.75rem;
$spacing-md: 1rem;
$spacing-lg: 1.25rem;
$spacing-xl: 1.5rem;
// Typography
$font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
$font-size-sm: 0.875rem;
$font-size-base: 1rem;
$font-size-lg: 1.25rem;Available Components
Core Components
Element Component
import { Element } from 'concierge-component/src/components/concierge/components';
// Usage
<Element markdown={markdownContent} />Renders markdown content with support for HTML elements.
Input Component
import { ConciergeInput } from 'concierge-component/src/components/concierge/components';
// Usage
<ConciergeInput
value={input}
onChange={setInput}
onSend={sendMessage}
placeholder="Type your message..."
/>Custom input component with send button and keyboard shortcuts.
Button Components
import { ToggleButton } from 'concierge-component/src/components/concierge/components';
// Usage
<ToggleButton
isOpen={isOpen}
onClick={toggleOpen}
theme={theme}
/>Toggle button for opening/closing the chat interface.
Context Usage
Available Contexts
UI Context
import { useUIContext } from 'concierge-component/src/components/concierge/contexts';
// Usage
const {
isOpen,
toggleOpen,
close,
open,
theme,
setTheme,
position,
setPosition
} = useUIContext();Message Context
import { useMessageContext } from 'concierge-component/src/components/concierge/contexts';
// Usage
const {
messages,
addMessage,
updateMessage,
clearMessages
} = useMessageContext();Action Context
import { useActionContext } from 'concierge-component/src/components/concierge/contexts';
// Usage
const {
registerAction,
unregisterAction,
handleEvent
} = useActionContext();API Context
import { useAPIContext } from 'concierge-component/src/components/concierge/contexts';
// Usage
const {
isLoading,
error,
sendMessage,
cancelRequest
} = useAPIContext();License
ISC
5 months ago