Component basics
DialStack's embedded components are ready-made UI for voice features: call history, voicemail, phone numbers, routing, onboarding and a softphone. Most of them exist both as a React component in @dialstack/sdk-react and as a Web Component (a custom element) in @dialstack/sdk-js. The React component is a thin wrapper around the Web Component, so both render the same UI and take the same options. React passes them as props and the Web Component takes them through setter methods.
Before you use a component, initialize the SDK and, in React, wrap your tree in DialstackComponentsProvider. See Setup.
Component inventory
| Component | React import | Web Component | Page |
|---|---|---|---|
| CallHistory | CallHistory from @dialstack/sdk-react/call-history | <dialstack-call-history> | Call history |
| CallLogs | CallLogs from @dialstack/sdk-react/call-logs | <dialstack-call-logs> | Call logs |
| Voicemails | Voicemails from @dialstack/sdk-react/voicemails | <dialstack-voicemails> | Voicemails |
| PhoneNumbers | PhoneNumbers from @dialstack/sdk-react/phone-numbers | <dialstack-phone-numbers> | Phone numbers |
| PhoneNumberOrdering | PhoneNumberOrdering from @dialstack/sdk-react/phone-number-ordering | <dialstack-phone-number-ordering> | Phone number ordering |
| AIAgent | AIAgent from @dialstack/sdk-react/ai-agent | <dialstack-ai-agent> | AI agent |
| DialPlan | DialPlan from @dialstack/sdk-react/dial-plan | React only | Dial plan |
| OnboardingPortal | OnboardingPortal from @dialstack/sdk-react/onboarding | React only | Onboarding portal |
| Softphone | SoftphoneProvider, Softphone from @dialstack/sdk-react/softphone | React only | Softphone |
Each React component has its own import path, so your bundle only includes the components you import.
Wiring a component
- React
- Web Component
Render the component anywhere inside DialstackComponentsProvider. It reads the instance from the provider.
import { CallLogs } from '@dialstack/sdk-react/call-logs';
function Dashboard() {
return <CallLogs limit={20} layoutVariant="compact" />;
}
Either let the instance create the element, which wires it for you:
const callLogs = dialstack.create('call-logs');
document.getElementById('container').appendChild(callLogs);
Or put the tag in your markup and hand it the instance with setInstance():
<dialstack-call-logs></dialstack-call-logs>
<script>
const callLogs = document.querySelector('dialstack-call-logs');
callLogs.setLimit(20);
callLogs.setLayoutVariant('compact');
callLogs.setInstance(dialstack);
</script>
Common options
Every list component (CallHistory, CallLogs, Voicemails, PhoneNumbers) accepts these options. The component pages only list what is specific to each one.
| React prop | Web Component method | Type | Description |
|---|---|---|---|
| — | setInstance(instance) | DialStackInstance | Connect the element to an initialized instance |
locale | setLocale(locale) | Locale | UI strings. See Internationalization |
formatting | setFormatting(options) | FormattingOptions | Date, time and phone number formatting (see below) |
icons | setIcons(icons) | ComponentIcons | Replace some or all of the default SVG icons |
layoutVariant | setLayoutVariant(variant) | 'compact' | 'comfortable' | 'default' | Spacing density (see below) |
classes | setClasses(classes) | Component-specific …Classes | Extra CSS classes. See Theming |
onLoaderStart | setOnLoaderStart(cb) | (event: LoaderStart) => void | Called when the component starts loading data |
onLoadError | setOnLoadError(cb) | (event: LoadError) => void | Called when loading fails |
className | — | string | Class on the React wrapper's container element |
style | — | React.CSSProperties | Inline style on the React wrapper's container |
LoaderStart is { elementTagName }. LoadError is { error, elementTagName }, where error is a message string.
- React
- Web Component
<CallLogs
onLoaderStart={() => setLoading(true)}
onLoadError={(event) => {
console.error(`${event.elementTagName} failed to load:`, event.error);
}}
/>
callLogs.setOnLoaderStart(() => setLoading(true));
callLogs.setOnLoadError((event) => {
console.error(`${event.elementTagName} failed to load:`, event.error);
});
FormattingOptions
| Option | Type | Default | Description |
|---|---|---|---|
defaultCountry | string | 'US' | Country used to format phone numbers (ISO 3166-1 alpha-2) |
dateLocale | string | 'en-US' | Locale for dates and times (BCP 47 language tag) |
use24HourTime | boolean | false | Use 24-hour time |
showTimezone | boolean | true | Show the time zone in dates and times |
{
defaultCountry: 'US',
dateLocale: 'en-US',
use24HourTime: false,
showTimezone: true,
}
Layout variants
layoutVariant sets spacing density: 'compact' for tight spaces such as a side panel, 'default', or 'comfortable' for more breathing room.
- React
- Web Component
<CallHistory phoneNumber="+14155551234" layoutVariant="compact" />
callHistory.setLayoutVariant('compact');
Pagination
The list components page through their data for you. You never handle cursors or page state:
- Call logs show Previous and Next controls under the table.
limitsets the page size (default 10). - Voicemails load 20 at a time, with a Load more button at the end of the list.
- Phone numbers load the whole account up front, then page client-side with Previous and Next.
limitsets the page size (default 10). - Call history is not paginated. It shows the most recent calls, up to
limit(default 5, maximum 20).
To page through the same data yourself, see Pagination.
The CallLog model
Call logs and call history render CallLog records, and CallLogs passes one to onRowClick and to a custom row renderer. These are the fields you are most likely to use:
interface CallLog {
id: string;
direction: 'inbound' | 'outbound' | 'internal';
from_number: string;
from_label: string | null; // caller's display name, when known
to_number: string | null; // null while an inbound call is still in progress
to_label: string | null;
started_at: string; // ISO 8601
answered_at: string | null;
connected_at: string | null;
ended_at: string | null;
duration_seconds: number | null;
status: 'completed' | 'no-answer' | 'busy' | 'failed' | 'voicemail' | null; // null while live
summary: string | null; // AI-generated summary
recording_url: string | null;
// …plus user, did, related_call, sentiment, quality_metrics and more
}
The full type is in the SDK reference.
Next steps
- Setup — initialize the SDK and add the provider
- Theming — colors, fonts and CSS classes
- Internationalization — translate UI strings