Try Live
Add Docs
Rankings
Pricing
Enterprise
Docs
Install
Theme
Install
Docs
Pricing
Enterprise
More...
More...
Try Live
Rankings
Create API Key
Add Docs
Carbon for IBM Products
https://github.com/carbon-design-system/ibm-products
Admin
Carbon for IBM Products is an open source component library built on IBM's Carbon Design System that
...
Tokens:
109,110
Snippets:
1,252
Trust Score:
9.5
Update:
6 days ago
Context
Skills
Chat
Benchmark
70.15
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Carbon for IBM Products Carbon for IBM Products is an open source implementation of IBM's Software Pattern Asset Library (PAL), building on the foundation of IBM's Carbon Design System and React implementation. It provides a curated set of advanced React components and patterns beyond what typical component libraries offer, specifically designed for enterprise IBM software applications. Previously known as Carbon for Cloud and Cognitive, this library enables teams to build consistent, accessible, and production-ready user interfaces. The library supports Carbon 11 with `@carbon/react` and is compatible with React 18, 17, and 16. It follows a bi-weekly release schedule and provides both stable components and preview/experimental components through a canary system. Components are categorized as stable, previewCandidate, preview, or deprecated, allowing teams to adopt new patterns gradually while maintaining production stability. ## Installation and Setup Install the package and import styles to start using Carbon for IBM Products components in your React application. ```bash # Install using npm npm install @carbon/ibm-products # Or using Yarn yarn add @carbon/ibm-products ``` ```scss // Include all styles (Carbon + IBM Products + experimental) @use '@carbon/ibm-products/css/index.min.css'; // Include only IBM Products styles (requires separate Carbon import) @use '@carbon/ibm-products/css/index-without-carbon.css'; // Include only released component styles (no experimental) @use '@carbon/ibm-products/css/index-without-carbon-released-only.css'; // Include styles for a specific component @use '@carbon/ibm-products/scss/components/AboutModal'; ``` ## AboutModal The AboutModal component displays product information including version, copyright, and links in a modal dialog. It's triggered by user action and remains visible until dismissed. ```jsx import React, { useState } from 'react'; import { AboutModal } from '@carbon/ibm-products'; import { Link } from '@carbon/react'; const App = () => { const [open, setOpen] = useState(false); return ( <> <button onClick={() => setOpen(true)}>About</button> <AboutModal open={open} onClose={() => setOpen(false)} logo={<img src="/logo.svg" alt="Product Logo" />} title="IBM Cloud Pak for Data" version="Version 4.8.0" copyrightText="Copyright IBM Corp. 2020, 2024" closeIconDescription="Close modal" links={[ <Link href="https://ibm.com/docs" key="docs">Documentation</Link>, <Link href="https://ibm.com/support" key="support">Support</Link>, ]} content="This software is licensed under the Apache License 2.0." additionalInfo={ <div> <img src="/partner-logo.svg" alt="Partner" /> </div> } /> </> ); }; ``` ## SidePanel The SidePanel component keeps users in-context while performing tasks like editing, viewing details, or configuring settings. It supports multiple sizes, overlay modes, and slide-in behavior. ```jsx import React, { useState } from 'react'; import { SidePanel } from '@carbon/ibm-products'; import { TextInput, Button } from '@carbon/react'; const App = () => { const [open, setOpen] = useState(false); return ( <> <Button onClick={() => setOpen(true)}>Open Panel</Button> <SidePanel open={open} onRequestClose={() => setOpen(false)} title="Edit Settings" subtitle="Configure your preferences" size="md" // 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' placement="right" // 'left' | 'right' includeOverlay animateTitle actions={[ { label: 'Save', onClick: () => { console.log('Saved'); setOpen(false); }, kind: 'primary', }, { label: 'Cancel', onClick: () => setOpen(false), kind: 'secondary', }, ]} > <TextInput id="setting-name" labelText="Name" placeholder="Enter name" /> <TextInput id="setting-email" labelText="Email" placeholder="Enter email" /> </SidePanel> </> ); }; ``` ## Tearsheet The Tearsheet is a mostly full-screen dialog that keeps users in-context while presenting actionable content. It supports navigation tabs, influencer panels, header actions, and multiple action buttons. ```jsx import React, { useState } from 'react'; import { Tearsheet } from '@carbon/ibm-products'; import { Button, Tabs, TabList, Tab } from '@carbon/react'; const App = () => { const [open, setOpen] = useState(false); return ( <> <Button onClick={() => setOpen(true)}>Open Tearsheet</Button> <Tearsheet open={open} onClose={() => setOpen(false)} title="Create New Resource" label="Step 1 of 3" description="Configure the basic settings for your new resource." closeIconDescription="Close" actions={[ { kind: 'secondary', label: 'Cancel', onClick: () => setOpen(false) }, { kind: 'primary', label: 'Create', onClick: () => { console.log('Created!'); setOpen(false); }}, ]} influencer={ <div style={{ padding: '1rem' }}> <h4>Quick Tips</h4> <p>Fill in all required fields before proceeding.</p> </div> } influencerPosition="left" // 'left' | 'right' influencerWidth="narrow" // 'narrow' | 'wide' navigation={ <Tabs> <TabList aria-label="Navigation tabs"> <Tab>General</Tab> <Tab>Advanced</Tab> <Tab>Review</Tab> </TabList> </Tabs> } > <div style={{ padding: '1rem' }}> <h3>Main Content Area</h3> <p>Place your form fields and content here.</p> </div> </Tearsheet> </> ); }; ``` ## CreateTearsheet The CreateTearsheet provides a multi-step creation flow with built-in navigation, validation, and progress tracking. Each step can have async validation and custom mount handlers. ```jsx import React, { useState } from 'react'; import { CreateTearsheet, CreateTearsheetStep } from '@carbon/ibm-products'; import { TextInput, NumberInput, RadioButtonGroup, RadioButton, Column, Row } from '@carbon/react'; const App = () => { const [open, setOpen] = useState(false); const [name, setName] = useState(''); const [partitions, setPartitions] = useState(1); const [retention, setRetention] = useState('one-day'); const clearForm = () => { setName(''); setPartitions(1); setRetention('one-day'); setOpen(false); }; return ( <> <button onClick={() => setOpen(true)}>Create Topic</button> <CreateTearsheet open={open} onClose={clearForm} onRequestSubmit={() => { return new Promise((resolve) => { setTimeout(() => { console.log('Created:', { name, partitions, retention }); clearForm(); resolve(); }, 1000); }); }} title="Create topic" description="Specify details for the new topic" label="Topic Configuration" submitButtonText="Create" cancelButtonText="Cancel" backButtonText="Back" nextButtonText="Next" > <CreateTearsheetStep title="Topic name" subtitle="Enter a unique name for your topic" description="This name will be used by producers and consumers." fieldsetLegendText="Topic information" disableSubmit={!name} onNext={() => Promise.resolve()} > <Row> <Column lg={8}> <TextInput id="topic-name" labelText="Topic name" value={name} onChange={(e) => setName(e.target.value)} placeholder="Enter topic name" /> </Column> </Row> </CreateTearsheetStep> <CreateTearsheetStep title="Partitions" subtitle="Configure partition count" fieldsetLegendText="Partition settings" disableSubmit={partitions < 1 || partitions > 100} > <Row> <Column lg={4}> <NumberInput id="partitions" label="Number of partitions" min={1} max={100} value={partitions} onChange={(e) => setPartitions(e.imaginaryTarget.value)} /> </Column> </Row> </CreateTearsheetStep> <CreateTearsheetStep title="Message retention" subtitle="How long messages are retained" fieldsetLegendText="Retention settings" > <RadioButtonGroup name="retention" legendText="Retention period" defaultSelected={retention} onChange={(value) => setRetention(value)} orientation="vertical" > <RadioButton labelText="A day" value="one-day" id="one-day" /> <RadioButton labelText="A week" value="one-week" id="one-week" /> <RadioButton labelText="A month" value="one-month" id="one-month" /> </RadioButtonGroup> </CreateTearsheetStep> </CreateTearsheet> </> ); }; ``` ## PageHeader The PageHeader component provides a consistent header area with breadcrumbs, title, action buttons, tags, and optional navigation tabs. It handles overflow gracefully and supports collapsible behavior. ```jsx import React from 'react'; import { PageHeader } from '@carbon/ibm-products'; import { Tabs, TabList, Tab } from '@carbon/react'; import { Lightning, Settings } from '@carbon/icons-react'; const App = () => { const breadcrumbs = [ { key: 'home', label: 'Home', href: '/' }, { key: 'resources', label: 'Resources', href: '/resources' }, { key: 'current', label: 'Current Page', isCurrentPage: true }, ]; const actionBarItems = [ { key: 'action1', renderIcon: (props) => <Lightning size={16} {...props} />, iconDescription: 'Quick action', onClick: () => console.log('Action 1'), }, { key: 'action2', renderIcon: (props) => <Settings size={16} {...props} />, iconDescription: 'Settings', onClick: () => console.log('Settings'), }, ]; const pageActions = [ { key: 'secondary', kind: 'secondary', label: 'Secondary' }, { key: 'primary', kind: 'primary', label: 'Primary' }, ]; const tags = [ { type: 'blue', label: 'Production', key: 'prod' }, { type: 'green', label: 'Active', key: 'active' }, { type: 'purple', label: 'v2.0', key: 'version' }, ]; return ( <PageHeader title="Resource Dashboard" subtitle="Manage and monitor your resources" breadcrumbs={breadcrumbs} breadcrumbOverflowAriaLabel="Show all breadcrumbs" actionBarItems={actionBarItems} actionBarOverflowAriaLabel="More actions" pageActions={pageActions} pageActionsOverflowLabel="Page actions" tags={tags} showAllTagsLabel="View all tags" allTagsModalTitle="All tags" allTagsModalSearchLabel="Search tags" allTagsModalSearchPlaceholderText="Search" navigation={ <Tabs> <TabList aria-label="Page navigation"> <Tab>Overview</Tab> <Tab>Details</Tab> <Tab>Activity</Tab> </TabList> </Tabs> } > <p>Additional header content can be placed here.</p> </PageHeader> ); }; ``` ## Datagrid The Datagrid component extends Carbon's DataTable with advanced features like sorting, filtering, pagination, row selection, and virtual scrolling. It uses the `useDatagrid` hook for state management. ```jsx import React, { useState, useMemo } from 'react'; import { Datagrid, useDatagrid } from '@carbon/ibm-products'; const App = () => { const columns = useMemo(() => [ { Header: 'Name', accessor: 'name', }, { Header: 'Status', accessor: 'status', }, { Header: 'Created', accessor: 'created', }, { Header: 'Type', accessor: 'type', width: 100, }, ], []); const [data] = useState([ { id: 1, name: 'Resource A', status: 'Active', created: '2024-01-15', type: 'VM' }, { id: 2, name: 'Resource B', status: 'Inactive', created: '2024-01-10', type: 'Storage' }, { id: 3, name: 'Resource C', status: 'Active', created: '2024-01-05', type: 'Network' }, { id: 4, name: 'Resource D', status: 'Pending', created: '2024-01-20', type: 'VM' }, ]); const datagridState = useDatagrid({ columns, data, initialState: { pageSize: 10, pageSizes: [10, 25, 50], }, }); return ( <Datagrid datagridState={datagridState} ariaToolbarLabel="Data table toolbar" /> ); }; ``` ## EmptyState EmptyState components provide consistent empty state patterns with illustrations, actions, and links. Specialized variants include ErrorEmptyState, NoDataEmptyState, NotFoundEmptyState, and more. ```jsx import React from 'react'; import { EmptyState, ErrorEmptyState, NoDataEmptyState, NotFoundEmptyState } from '@carbon/ibm-products'; import { Add } from '@carbon/icons-react'; // Generic EmptyState with custom illustration const CustomEmptyState = () => ( <EmptyState title="No items found" subtitle="Try adjusting your search or filter criteria." illustration="/path/to/illustration.svg" illustrationDescription="Empty box illustration" size="lg" // 'lg' | 'sm' action={{ text: 'Create item', onClick: () => console.log('Create clicked'), renderIcon: (props) => <Add size={20} {...props} />, kind: 'primary', }} link={{ text: 'Learn more', href: 'https://example.com/docs', }} /> ); // ErrorEmptyState for error scenarios const ErrorState = () => ( <ErrorEmptyState title="Something went wrong" subtitle="We were unable to retrieve your data. Please try again." illustrationTheme="dark" // 'light' | 'dark' size="sm" action={{ text: 'Retry', onClick: () => console.log('Retry'), kind: 'primary', }} link={{ text: 'View status page', href: '/status', }} /> ); // NoDataEmptyState for empty collections const NoDataState = () => ( <NoDataEmptyState title="No resources yet" subtitle="Create your first resource to get started." illustrationTheme="light" action={{ text: 'Create resource', onClick: () => console.log('Create'), renderIcon: (props) => <Add size={20} {...props} />, }} /> ); ``` ## NotificationsPanel The NotificationsPanel displays a list of notifications with timestamps, types (error, warning, success, informational), and dismissal capabilities. It includes a "do not disturb" toggle and empty state handling. ```jsx import React, { useState } from 'react'; import { NotificationsPanel } from '@carbon/ibm-products'; const App = () => { const [notifications, setNotifications] = useState([ { id: '1', type: 'success', title: 'Deployment successful', description: 'Your application was deployed to production.', timestamp: new Date(Date.now() - 5 * 60 * 1000), // 5 minutes ago unread: true, onNotificationClick: () => console.log('Clicked notification 1'), }, { id: '2', type: 'warning', title: 'High memory usage', description: 'Instance memory usage exceeded 80%.', timestamp: new Date(Date.now() - 30 * 60 * 1000), // 30 minutes ago unread: true, link: { url: '/monitoring', text: 'View metrics' }, }, { id: '3', type: 'error', title: 'Build failed', description: 'Pipeline execution failed at test stage.', timestamp: new Date(Date.now() - 2 * 60 * 60 * 1000), // 2 hours ago unread: false, }, ]); return ( <NotificationsPanel open={true} data={notifications} title="Notifications" dateTimeLocale="en-US" dateTimeStyle="long" // 'long' | 'short' | 'narrow' dismissAllLabel="Dismiss all" dismissSingleNotificationIconDescription="Dismiss" doNotDisturbLabel="Do not disturb" emptyStateLabel="No notifications" readMoreLabel="Read more" readLessLabel="Read less" todayLabel="Today" yesterdayLabel="Yesterday" onDismissAllNotifications={() => setNotifications([])} onDismissSingleNotification={(id) => { setNotifications(notifications.filter(n => n.id !== id)); }} onDoNotDisturbChange={(enabled) => console.log('DND:', enabled)} /> ); }; ``` ## ExportModal The ExportModal provides a dialog for exporting files with filename input, format selection, loading states, and success/error feedback. ```jsx import React, { useState } from 'react'; import { ExportModal } from '@carbon/ibm-products'; const App = () => { const [open, setOpen] = useState(false); const [loading, setLoading] = useState(false); const [success, setSuccess] = useState(false); const handleExport = (filename) => { setLoading(true); setTimeout(() => { setLoading(false); setSuccess(true); console.log('Exported:', filename); }, 2000); }; return ( <> <button onClick={() => setOpen(true)}>Export</button> <ExportModal open={open} onClose={() => { setOpen(false); setSuccess(false); }} onRequestSubmit={handleExport} filename="my-data" title="Export data" body="Choose a file format and name for your export." inputLabel="File name" inputType="text" // 'text' | 'password' primaryButtonText="Export" secondaryButtonText="Cancel" loading={loading} loadingMessage="Exporting your data..." successful={success} successMessage="Export completed successfully!" preformattedExtensions={[ { extension: 'csv', description: 'Comma-separated values' }, { extension: 'json', description: 'JSON format' }, { extension: 'xlsx', description: 'Excel spreadsheet' }, ]} preformattedExtensionsLabel="File format" validExtensions={['csv', 'json', 'xlsx']} /> </> ); }; ``` ## RemoveModal The RemoveModal handles delete/remove confirmations with optional text confirmation for high-impact operations. It provides danger-styled primary actions and clear resource identification. ```jsx import React, { useState } from 'react'; import { RemoveModal } from '@carbon/ibm-products'; const App = () => { const [open, setOpen] = useState(false); const resourceName = 'production-database'; return ( <> <button onClick={() => setOpen(true)}>Delete Resource</button> <RemoveModal open={open} onClose={() => setOpen(false)} onRequestSubmit={() => { console.log('Deleted:', resourceName); setOpen(false); }} title="Delete resource" body={ <p> Are you sure you want to delete <strong>{resourceName}</strong>? This action cannot be undone. </p> } resourceName={resourceName} primaryButtonText="Delete" secondaryButtonText="Cancel" iconDescription="Close" textConfirmation={true} // Enable high-impact confirmation inputLabelText={`Type "${resourceName}" to confirm`} inputPlaceholderText="Enter resource name" inputInvalidText="Resource name does not match" primaryDangerDescription="This will permanently delete the resource" /> </> ); }; ``` ## TagSet The TagSet component displays a collection of tags with overflow handling, modal view for many tags, and optional search functionality. ```jsx import React from 'react'; import { TagSet } from '@carbon/ibm-products'; const App = () => { const tags = [ { label: 'Production', type: 'red' }, { label: 'Active', type: 'green' }, { label: 'v2.0', type: 'blue' }, { label: 'Critical', type: 'magenta' }, { label: 'Region: US-East', type: 'teal' }, { label: 'Team: Platform', type: 'purple' }, { label: 'Cost Center: 12345', type: 'cyan' }, { label: 'Environment', type: 'warm-gray' }, ]; return ( <TagSet tags={tags} maxVisible={5} align="start" // 'start' | 'center' | 'end' overflowAlign="bottom" // Tooltip alignment overflowType="default" // 'default' | 'tag' allTagsModalTitle="All tags" allTagsModalSearchLabel="Filter tags" allTagsModalSearchPlaceholderText="Search tags" showAllTagsLabel="View all" onOverflowTagChange={(overflowTags) => { console.log('Overflow tags:', overflowTags); }} /> ); }; ``` ## UserAvatar The UserAvatar component displays user profile images, initials, or icons with configurable sizes, colors, and tooltips. ```jsx import React from 'react'; import { UserAvatar } from '@carbon/ibm-products'; import { User } from '@carbon/icons-react'; const App = () => ( <div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}> {/* Avatar with initials from name */} <UserAvatar name="John Doe" size="lg" // 'sm' | 'md' | 'lg' | 'xl' backgroundColor="order-1-cyan" tooltipText="John Doe" tooltipAlignment="bottom" /> {/* Avatar with image */} <UserAvatar image="/path/to/avatar.jpg" imageDescription="Jane Smith's profile picture" size="md" tooltipText="Jane Smith" /> {/* Avatar with custom icon */} <UserAvatar renderIcon={User} size="sm" backgroundColor="order-3-green" tooltipText="Guest User" /> </div> ); ``` ## WebTerminal The WebTerminal component provides a terminal interface that slides in from the bottom of the screen. It supports custom actions, documentation links, and can be controlled programmatically. ```jsx import React from 'react'; import { WebTerminal, WebTerminalProvider, useWebTerminal } from '@carbon/ibm-products'; import { Copy, Renew } from '@carbon/icons-react'; // Terminal content component const TerminalContent = () => ( <div style={{ padding: '1rem', fontFamily: 'monospace' }}> <p>$ kubectl get pods</p> <p>NAME READY STATUS RESTARTS AGE</p> <p>app-6b7c5d9f4-abc12 1/1 Running 0 2d</p> </div> ); // Main app with terminal const App = () => { const { openWebTerminal, closeWebTerminal } = useWebTerminal(); return ( <> <button onClick={openWebTerminal}>Open Terminal</button> <WebTerminal closeIconDescription="Close terminal" isInitiallyOpen={false} webTerminalAriaLabel="Web terminal" actions={[ { renderIcon: Copy, onClick: () => console.log('Copy'), iconDescription: 'Copy output', }, { renderIcon: Renew, onClick: () => console.log('Refresh'), iconDescription: 'Refresh', }, ]} documentationLinks={[ { itemText: 'Kubernetes Docs', href: 'https://kubernetes.io/docs' }, { itemText: 'CLI Reference', href: '/docs/cli' }, ]} documentationLinksIconDescription="Documentation" > <TerminalContent /> </WebTerminal> </> ); }; // Wrap with provider const Root = () => ( <WebTerminalProvider> <App /> </WebTerminalProvider> ); ``` ## Summary Carbon for IBM Products provides a comprehensive suite of enterprise-ready React components that extend the Carbon Design System for IBM software applications. The main use cases include building complex data management interfaces with Datagrid, implementing multi-step creation flows with CreateTearsheet, managing side panel interactions for editing and configuration, and displaying contextual page headers with navigation. The library excels at handling overflow scenarios, accessibility requirements, and consistent styling across enterprise applications. Integration patterns follow React best practices with hooks-based APIs (useDatagrid, useWebTerminal), controlled component patterns for modals and panels, and composable sub-components for complex layouts. Components are designed to work seamlessly with Carbon's theme system and can be styled using Sass variables. For production applications, teams should import only the styles they need and leverage the canary system to gradually adopt preview components while maintaining stability with released components.