@zuperscore/support-help
v1.0.0
Published
Enterprise-grade React support help widget component for customer support chat interfaces
Maintainers
Readme
@zuperscore/support-help
Enterprise-grade React support help widget component for customer support chat interfaces. Framework-agnostic, SSR-compatible, and fully accessible.
Features
- 🚀 Framework Agnostic - Works with Next.js, Vite, Create React App, and any React framework
- 📱 Responsive Design - Mobile-first design that adapts to all screen sizes
- 🎨 Customizable - Extensive styling options and prop customization
- ♿ Accessible - Full ARIA support and keyboard navigation
- 🌙 Dark Mode - Automatic dark mode detection and support
- 📁 File Upload - Built-in file upload functionality with validation
- 🛡️ Type Safe - Full TypeScript support with comprehensive types
- 🎭 SSR Compatible - Works perfectly with server-side rendering
- 🧪 Well Tested - Comprehensive test suite with high coverage
- 🔒 Secure - Input sanitization and XSS protection
Installation
npm install @zuperscore/support-help
# or
yarn add @zuperscore/support-help
# or
pnpm add @zuperscore/support-helpQuick Start
Basic Usage
import React from 'react';
import { SupportHelp } from '@zuperscore/support-help';
import '@zuperscore/support-help/styles.css';
function App() {
return (
<div>
<h1>My App</h1>
<SupportHelp
onSendMessage={(message, files) => {
console.log('New message:', message);
console.log('Files:', files);
}}
/>
</div>
);
}With Custom Configuration
import React, { useState } from 'react';
import { SupportHelp, type SupportMessage } from '@zuperscore/support-help';
import '@zuperscore/support-help/styles.css';
function App() {
const [messages, setMessages] = useState<SupportMessage[]>([]);
const [isOpen, setIsOpen] = useState(false);
const handleSendMessage = (message: string, files: any[]) => {
const newMessage: SupportMessage = {
id: Date.now(),
direction: 'outbound',
message_type: 'text',
text_body: message,
created_at: new Date().toISOString(),
};
setMessages(prev => [...prev, newMessage]);
// Simulate assistant response
setTimeout(() => {
setMessages(prev => [...prev, {
id: Date.now() + 1,
direction: 'inbound',
message_type: 'text',
text_body: 'Thank you for your message. How can I help you today?',
created_at: new Date().toISOString(),
}]);
}, 1000);
};
return (
<div>
<h1>My App with Custom Support</h1>
<SupportHelp
supportTitle="Help Center"
assistantName="AI Assistant"
welcomeMessage="Welcome! How can I assist you today?"
messagePlaceholder="Type your question here..."
position="bottom-left"
messages={messages}
onSendMessage={handleSendMessage}
onToggle={setIsOpen}
allowFileUpload
maxFiles={3}
styles={{
button: { backgroundColor: '#10b981' },
panel: { border: '2px solid #10b981' }
}}
/>
</div>
);
}Props API
SupportHelpProps
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| className | string | - | Custom CSS class for the widget |
| defaultOpen | boolean | false | Whether widget opens by default |
| helpIcon | React.ComponentType<{className?: string}> \\| string | Built-in icon | Custom help button icon |
| brandIcon | React.ComponentType<{className?: string}> \\| string | Built-in icon | Custom brand icon in header |
| supportTitle | string | "Support" | Title displayed in header |
| assistantName | string | "Zuperscore Assistant" | Assistant name in welcome |
| welcomeMessage | string | "Please choose a topic below..." | Welcome message text |
| messagePlaceholder | string | "Type your message..." | Input placeholder text |
| allowFileUpload | boolean | true | Enable file upload feature |
| maxFiles | number | 5 | Maximum files allowed |
| onSendMessage | (message: string, files?: FileUpload[]) => void | - | Message send handler |
| onToggle | (isOpen: boolean) => void | - | Widget toggle handler |
| onFileUpload | (files: FileUpload[]) => void | - | File upload handler |
| messages | SupportMessage[] | - | External messages array |
| formatTime | (timestamp: string \\| Date \\| number) => string | Built-in formatter | Custom time formatter |
| hideOnModalOpen | boolean | true | Hide when modals are open |
| position | 'bottom-right' \\| 'bottom-left' \\| 'top-right' \\| 'top-left' | 'bottom-right' | Widget position |
| styles | StylesConfig | {} | Custom style overrides |
SupportMessage
interface SupportMessage {
id: number;
direction: "inbound" | "outbound";
message_type: "text";
text_body: string;
created_at: string;
}StylesConfig
interface StylesConfig {
button?: React.CSSProperties;
panel?: React.CSSProperties;
header?: React.CSSProperties;
content?: React.CSSProperties;
messageInput?: React.CSSProperties;
}Styling
CSS Import
Always import the CSS file for default styling:
import '@zuperscore/support-help/styles.css';Custom Styling
The component provides several ways to customize styling:
1. CSS Classes
/* Override default styles */
.support-help-widget {
/* Custom widget styles */
}
.support-help-button {
background: linear-gradient(45deg, #667eea 0%, #764ba2 100%);
}
.support-help-panel {
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
}2. Style Props
<SupportHelp
styles={{
button: {
backgroundColor: '#10b981',
borderRadius: '50%',
},
panel: {
border: '2px solid #10b981',
borderRadius: '16px',
},
messageInput: {
borderColor: '#10b981',
}
}}
/>3. CSS Custom Properties
.support-help-widget {
--support-primary-color: #10b981;
--support-text-color: #1f2937;
--support-bg-color: #ffffff;
}Dark Mode
The component automatically detects and adapts to dark mode:
@media (prefers-color-scheme: dark) {
.support-help-panel > div {
background-color: #1f2937;
color: #f9fafb;
}
}Framework Integration
Next.js
'use client'; // Add this for Next.js 13+ app directory
import { SupportHelp } from '@zuperscore/support-help';
import '@zuperscore/support-help/styles.css';
export default function Page() {
return (
<div>
<SupportHelp />
</div>
);
}Vite
import { SupportHelp } from '@zuperscore/support-help';
import '@zuperscore/support-help/styles.css';
function App() {
return <SupportHelp />;
}Create React App
import { SupportHelp } from '@zuperscore/support-help';
import '@zuperscore/support-help/styles.css';
function App() {
return (
<div className="App">
<SupportHelp />
</div>
);
}Server-Side Rendering (SSR)
The component is fully SSR-compatible. It uses hooks to detect server environment and safely handles DOM operations:
// ✅ Safe for SSR
import { SupportHelp } from '@zuperscore/support-help';
function MyPage() {
return (
<div>
<h1>SSR Page</h1>
<SupportHelp />
</div>
);
}The component will not render the UI elements on the server and will hydrate properly on the client.
Accessibility
The component follows WCAG guidelines and includes:
- ARIA labels on all interactive elements
- Keyboard navigation support
- Screen reader compatibility
- Focus management for modal behavior
- High contrast mode support
- Reduced motion respect
// Accessibility is built-in
<SupportHelp
// All buttons have proper aria-labels
// Keyboard navigation works out of the box
// Screen readers can navigate the interface
/>Error Handling
The component includes comprehensive error handling:
import { SupportHelp, SupportHelpErrorBoundary } from '@zuperscore/support-help';
function App() {
return (
<SupportHelpErrorBoundary
onError={(error, errorInfo) => {
console.error('Support widget error:', error);
// Send to error reporting service
}}
fallback={({ error, retry }) => (
<div>
<p>Support widget failed to load</p>
<button onClick={retry}>Retry</button>
</div>
)}
>
<SupportHelp />
</SupportHelpErrorBoundary>
);
}File Upload
Built-in file upload with validation:
<SupportHelp
allowFileUpload
maxFiles={5}
onFileUpload={(files) => {
files.forEach(fileObj => {
console.log('File:', fileObj.file.name);
console.log('Progress:', fileObj.progress);
console.log('Uploading:', fileObj.uploading);
});
}}
/>Supported file types:
- Images: JPEG, PNG, GIF, WebP
- Documents: PDF, DOC, DOCX, TXT
Advanced Usage
Custom Icons
import { Heart, MessageCircle } from 'lucide-react';
<SupportHelp
helpIcon={Heart}
brandIcon={MessageCircle}
// or with image URLs
helpIcon="/custom-help-icon.svg"
brandIcon="/brand-logo.svg"
/>Integration with State Management
import { useDispatch, useSelector } from 'react-redux';
import { SupportHelp } from '@zuperscore/support-help';
function SupportWidget() {
const dispatch = useDispatch();
const { messages, isOpen } = useSelector(state => state.support);
return (
<SupportHelp
messages={messages}
onSendMessage={(message) => {
dispatch(sendSupportMessage(message));
}}
onToggle={(open) => {
dispatch(setSupportOpen(open));
}}
/>
);
}Custom Message Formatting
<SupportHelp
formatTime={(timestamp) => {
return new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: '2-digit',
hour12: true
}).format(new Date(timestamp));
}}
/>Browser Support
- Chrome 90+
- Firefox 88+
- Safari 14+
- Edge 90+
TypeScript
Full TypeScript support with comprehensive types:
import type {
SupportHelpProps,
SupportMessage,
FileUpload,
DateGroup
} from '@zuperscore/support-help';Contributing
We welcome contributions! Please see our Contributing Guide for details.
Development Setup
# Clone the repo
git clone https://github.com/yourusername/support-help.git
# Install dependencies
npm install
# Run tests
npm test
# Build the package
npm run build
# Run linting
npm run lintScripts
npm run build- Build the packagenpm run dev- Watch mode developmentnpm run test- Run testsnpm run test:coverage- Run tests with coveragenpm run lint- Lint the codenpm run format- Format the code
License
MIT License - see LICENSE file for details.
Support
Changelog
See CHANGELOG.md for release history.
