Harmony Components
Reference for Harmony Design System React components including buttons, modals, panels, form controls, navigation, and data display elements.
Components
you can fetch offical documentation from https://storybook-harmony.ofp-elr.optum.com/?path=/docs/getting-started-overview--docs&e2e=1&globals=viewport:mastheadSidebar275 and review each component for example https://storybook-harmony.ofp-elr.optum.com/?path=/docs/components-actions-button--docs&e2e=1&globals=viewport:mastheadSidebar275 to gain offical storybook documentation.
you can also use the OTC AWESOME LLM search for "Harmony" to find a skills for Harmony.
Specifically, you can use the "harmony-sdk-discovery" skill to explore available Harmony components and APIs from installed packages, and the "harmony-version-management" skill to check for the latest Harmony packages and update dependencies safely.
The following components are detailed below
- Button
- DropdownButton
- IconButton
- SplitButton
- Accordion
- Modal
- Panel
- TabbedPanel
- HelperText
- Label
- Tooltip
- Avatar
- Badge
- Chip
- Count
- LoadingIndicator
- ProgressIndicator
- StepTracker
- Checkbox
- DatePicker
- DropdownMulti
- DropdownSingle
- Fieldset
- RadioButtonGroup
- SearchField
- TextArea
- TextInput
- ToggleSwitch
- Breadcrumb
- Link
- Modal
- ReadOnly
- Wizard
- Card
- Footer
- Navigation
- Pagination
- Select
- Table
Components
The Harmony React component library provides the following components:
Actions
Button
Buttons are fundamental interactive elements that trigger actions such as form submission, dialog launching, or task execution. It supports text, icons, or both with appropriate styling for visibility and accessibility. Harmony has three Button variants: Standard, Dropdown, and Split Dropdown.
import { Button, ButtonProps } from '@uhg-harmony/react';
import styled from 'styled-components';
const StoryWrapper = styled.div`
background-color: ${(props) => props.theme.HarmonySemanticColorBgCanvas};
padding: 10px 20px 20px 20px;
.harmony-button {
margin-right: 15px;
margin-top: 10px;
}
`;
const _onPress = () => console.log('clicked');
export const BasicExample: React.FC<ButtonProps> = ({
className,
size,
disabled,
buttonRef,
onPress = _onPress,
block,
inverse,
}: ButtonProps) => (
<StoryWrapper>
<Button
className={className}
onPress={onPress}
size={size}
disabled={disabled}
buttonRef={buttonRef}
block={block}
inverse={inverse}
>
Primary
</Button>
<Button
className={className}
onPress={onPress}
size={size}
variant="secondary"
disabled={disabled}
buttonRef={buttonRef}
block={block}
inverse={inverse}
>
Secondary
</Button>
<Button
className={className}
onPress={onPress}
size={size}
variant="tertiary"
disabled={disabled}
buttonRef={buttonRef}
block={block}
inverse={inverse}
>
Tertiary
</Button>
<Button
className={className}
onPress={onPress}
size={size}
variant="destructive"
disabled={disabled}
buttonRef={buttonRef}
block={block}
inverse={inverse}
>
Destructive
</Button>
<Button
className={className}
onPress={onPress}
size={size}
variant="ghost"
disabled={disabled}
buttonRef={buttonRef}
block={block}
inverse={inverse}
>
Ghost
</Button>
</StoryWrapper>
);
DropdownButton
A Dropdown Button combines standard button functionality with an expandable dropdown menu. It uses ARIA attributes and custom hooks to manage interactions, with intelligent positioning to ensure visibility within the viewport. When clicked, it reveals a Dropdown List. The text for a Dropdown Button should be either the selected Dropdown List Item or describe the Dropdown List Items.
import { useState } from 'react';
import { DropdownButtonProps, DropdownButton, IDropdownButtonItem } from '@uhg-harmony/react';
import styled from 'styled-components';
const StoryWrapper = styled.div`
background-color: ${(props) => props.theme.HarmonySemanticColorBgCanvas};
padding: 10px 20px 20px 20px;
display: flex;
flex-wrap: wrap;
gap: 15px;
.harmony-button {
margin-top: 10px;
}
`;
const _onPress = () => console.log('clicked');
const buttondropdownoptions: IDropdownButtonItem[] = [
{ id: '1', label: 'option1', value: 'OPT1' },
{ id: '2', label: 'option2', value: 'OPT2' },
{ id: '3', label: 'option3', value: 'OPT3' },
];
export const BasicExample: React.FC<DropdownButtonProps> = ({
className,
size = 'm',
disabled,
buttonRef,
onPress = _onPress,
inverse,
dropdownoptions,
}: DropdownButtonProps) => {
const [openDropdownId, setOpenDropdownId] = useState<string | null>(null);
return (
<StoryWrapper>
<DropdownButton
className={className}
onPress={onPress}
size={size}
disabled={disabled}
buttonRef={buttonRef}
inverse={inverse}
id="dropdown1"
onItemSelect={(selectedItem: IDropdownButtonItem) => console.log('Selected:', selectedItem.value)}
openDropdownId={openDropdownId}
setOpenDropdownId={setOpenDropdownId}
dropdownoptions={dropdownoptions ?? buttondropdownoptions}
>
Primary
</DropdownButton>
<DropdownButton
className={className}
onPress={onPress}
size={size}
variant="secondary"
disabled={disabled}
buttonRef={buttonRef}
inverse={inverse}
id="dropdown2"
onItemSelect={(selectedItem: IDropdownButtonItem) => console.log('Selected:', selectedItem.value)}
openDropdownId={openDropdownId}
setOpenDropdownId={setOpenDropdownId}
dropdownoptions={dropdownoptions ?? buttondropdownoptions}
>
Secondary
</DropdownButton>
<DropdownButton
className={className}
onPress={onPress}
size={size}
variant="tertiary"
disabled={disabled}
buttonRef={buttonRef}
inverse={inverse}
id="dropdown3"
onItemSelect={(selectedItem: IDropdownButtonItem) => console.log('Selected:', selectedItem.value)}
openDropdownId={openDropdownId}
setOpenDropdownId={setOpenDropdownId}
dropdownoptions={dropdownoptions ?? buttondropdownoptions}
>
Tertiary
</DropdownButton>
<DropdownButton
className={className}
onPress={onPress}
size={size}
variant="destructive"
disabled={disabled}
buttonRef={buttonRef}
inverse={inverse}
id="dropdown4"
onItemSelect={(selectedItem: IDropdownButtonItem) => console.log('Selected:', selectedItem.value)}
openDropdownId={openDropdownId}
setOpenDropdownId={setOpenDropdownId}
dropdownoptions={dropdownoptions ?? buttondropdownoptions}
>
Destructive
</DropdownButton>
<DropdownButton
className={className}
onPress={onPress}
size={size}
variant="ghost"
disabled={disabled}
buttonRef={buttonRef}
inverse={inverse}
id="dropdown5"
onItemSelect={(selectedItem: IDropdownButtonItem) => console.log('Selected:', selectedItem.value)}
openDropdownId={openDropdownId}
setOpenDropdownId={setOpenDropdownId}
dropdownoptions={dropdownoptions ?? buttondropdownoptions}
>
Ghost
</DropdownButton>
</StoryWrapper>
);
};
IconButton
Icon Buttons are compact clickable elements that display an icon instead of text and are ideal for space-constrained interfaces where visual symbols clearly convey functionality. Like the Standard Button, it supports triggering actions such as submitting forms, opening dialogs, or performing specific tasks, while maintaining accessibility and visual clarity.
import React from 'react';
import { IconButton, IconButtonProps } from '@uhg-harmony/react';
import { CloseIcon } from '@uhg-harmony/icons-react';
import styled from 'styled-components';
const StoryWrapper = styled.div`
background-color: ${(props) => props.theme.HarmonyIconButtonColorPrimaryDisabled};
padding: 20px 20px 20px 20px;
`;
const _onPress = () => console.log('clicked');
export const BasicExample: React.FC<IconButtonProps> = ({
className,
onPress = _onPress,
disabled,
buttonRef,
size,
}: IconButtonProps) => (
<StoryWrapper>
<IconButton
className={className}
onPress={onPress}
disabled={disabled}
buttonRef={buttonRef}
icon={<CloseIcon focusable="false" />}
label="Close"
size={size}
/>
</StoryWrapper>
);
SplitButton
Split Buttons are compound components that combine a primary action button with an adjacent dropdown menu. It offers quick access to a default action while providing additional options in a compact format.
Split Buttons have two actionable areas: the text area and the arrow:
- Clicking the text label functions like a Standard Button.
- Clicking on the dropdown arrow functions like a Dropdown Button (i.e., it opens a dropdown list).
import React, { useState } from 'react';
import { SplitButton, SplitButtonProps, ISplitDropdownButtonItem } from '@uhg-harmony/react';
import styled from 'styled-components';
const StoryWrapper = styled.div`
background-color: ${(props) => props.theme.HarmonySemanticColorBgCanvas};
padding: 10px 20px 20px 20px;
gap: 12px;
display: flex;
flex-wrap: wrap;
.split-button {
margin-top: 10px;
}
`;
const _onPress = () => console.log('clicked');
const splitDropdownOptions: ISplitDropdownButtonItem[] = [
{ id: '1', label: 'option1', value: 'OPT1' },
{ id: '2', label: 'option2', value: 'OPT2' },
{ id: '3', label: 'option3', value: 'OPT3' },
];
export const BasicExample: React.FC<Omit<SplitButtonProps, 'onPress' | 'buttonRef'>> = ({
className,
size = 'm',
buttonRef,
onPress = _onPress,
inverse,
options,
}: SplitButtonProps) => {
const [openSplitDropdownId, setOpenSplitDropdownId] = useState<string | null>(null);
return (
<StoryWrapper>
<SplitButton
className={className}
onPress={onPress}
size={size}
buttonRef={buttonRef}
inverse={inverse}
id="splitdropdown1"
onItemSelect={(selectedItem) => console.log('Selected:', selectedItem.value)}
openSplitDropdownId={openSplitDropdownId}
setOpenSplitDropdownId={setOpenSplitDropdownId}
options={options ?? splitDropdownOptions}
>
Primary
</SplitButton>
<SplitButton
className={className}
onPress={onPress}
size={size}
variant="secondary"
buttonRef={buttonRef}
inverse={inverse}
id="splitdropdown2"
onItemSelect={(selectedItem) => console.log('Selected:', selectedItem.value)}
openSplitDropdownId={openSplitDropdownId}
setOpenSplitDropdownId={setOpenSplitDropdownId}
options={options ?? splitDropdownOptions}
>
Secondary
</SplitButton>
<SplitButton
className={className}
onPress={onPress}
size={size}
variant="tertiary"
buttonRef={buttonRef}
inverse={inverse}
id="splitdropdown3"
onItemSelect={(selectedItem) => console.log('Selected:', selectedItem.value)}
openSplitDropdownId={openSplitDropdownId}
setOpenSplitDropdownId={setOpenSplitDropdownId}
options={options ?? splitDropdownOptions}
>
Tertiary
</SplitButton>
</StoryWrapper>
);
};
Containers
Accordion
Accordions are vertically stacked collapsible sections. Each section is controlled by a header that, when clicked, reveals or hides the associated content. Typically, only one section is expanded at a time, promoting a clean and focused layout for dense or categorized information.
import { FC } from 'react';
import { Accordion, Text, IAccordionProps } from '@uhg-harmony/react';
export const BasicExample: FC<IAccordionProps> = ({ collapsible, noBorder }) => {
return (
<>
<Accordion title="Accordion label" collapsible={collapsible} initiallyClosed={true} noBorder={noBorder}>
<Text>Description text goes here</Text>
</Accordion>
<Accordion title="Accordion label" collapsible={collapsible} initiallyClosed={true} noBorder={noBorder}>
<Text>Description text goes here</Text>
</Accordion>
<Accordion title="Accordion label" collapsible={collapsible} initiallyClosed={true} noBorder={noBorder}>
<Text>Description text goes here</Text>
</Accordion>
</>
);
};
Modal
A Modal is an overlay dialog that focuses user attention on a single task or piece of information using a temporary window that covers part of the page. Modals intentionally prevent further interaction with the page until the modal task is completed or dismissed by the user. Modals should be used sparingly due to their disruptive nature.
import { FC, useEffect, useState } from 'react';
import { Button, Modal, ModalProps } from '@uhg-harmony/react';
import styled from 'styled-components';
const VisuallyHidden = styled.span`
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
`;
export const BasicExample: FC<ModalProps> = ({ title, open }) => {
const [isOpen, setOpen] = useState(open);
const dismiss = () => setOpen(false);
useEffect(() => {
setOpen(open);
}, [open]);
return (
<>
{/* Button used for example purposes to trigger the modal */}
<Button onPress={() => setOpen(true)}>
Open Modal
<VisuallyHidden>Opens modal window</VisuallyHidden>
</Button>
{isOpen && (
<Modal open={isOpen} title={title} onClose={dismiss}>
<Modal.Body></Modal.Body>
<Modal.Actions>
<Button onPress={dismiss}>Button label</Button>
<Button variant="secondary" onPress={dismiss}>
Button label
</Button>
</Modal.Actions>
</Modal>
)}
</>
);
};
Panel
The Panel is a fixed container used to display persistent content. It remains visible at all times and is ideal for organizing information in a clear, structured layout, contributing to a seamless and consistent user experience.
import { FC } from 'react';
import { Panel, Text } from '@uhg-harmony/react';
export const BasicExample: FC = () => (
<Panel title="My Panel" showBorder={true}>
<Text>Panel content goes here</Text>
</Panel>
);
TabbedPanel
Tabs organize related content at the same hierarchy level, allowing users to switch between information groups within a shared context. They reduce vertical space and always include at least two tabs, with one active at a time. Tabs can contain nested components such as text, forms, images, cards, or lists.
import { FC } from 'react';
import { TabbedPanel, TabbedPanelProps } from '@uhg-harmony/react';
import styled from 'styled-components';
const ParagraphContent = styled.p`
margin: 0;
`;
const panels = [
{
header: 'Tab 1',
content: (
<>
<TabbedPanel.Heading>Heading for tab 1</TabbedPanel.Heading>
<TabbedPanel.Content>
<ParagraphContent>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex
ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit
anim id est laborum.
</ParagraphContent>
</TabbedPanel.Content>
</>
),
},
{
header: 'Tab 2',
content: (
<>
<TabbedPanel.Heading>Heading for tab 2</TabbedPanel.Heading>
<TabbedPanel.Content>
<ParagraphContent>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex
ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit
anim id est laborum.
</ParagraphContent>
</TabbedPanel.Content>
</>
),
},
{
header: 'Tab 3',
content: (
<>
<TabbedPanel.Heading>Heading for tab 3</TabbedPanel.Heading>
<TabbedPanel.Content>
<ParagraphContent>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex
ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat
nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit
anim id est laborum.
</ParagraphContent>
</TabbedPanel.Content>
</>
),
},
];
export const BasicExample: FC<TabbedPanelProps> = ({ className }: TabbedPanelProps) => {
return <TabbedPanel panels={panels} className={className} />;
};
Feedback
HelperText
The Helper Text component provides additional guidance or context for form fields. It helps users understand expectations such as formatting rules or usage tips. It improves form usability and reduces user errors without cluttering the interface.
import { FC } from 'react';
import { HelperText, HelperTextProps } from '@uhg-harmony/react';
export const BasicExample: FC = ({ className }: HelperTextProps) => (
<div>
<HelperText className={className}>Helper Text</HelperText>
</div>
);
Label
The Label is a text element that provides context for form fields. It clearly identifies the purpose of an input, ensuring users understand what information is required.
import { FC } from 'react';
import { generateClasses } from '../../../../utilities/generateClasses';
import { Label, LabelProps } from '@uhg-harmony/react';
export const BasicExample: FC<LabelProps> = ({
isLarge = true,
required = false,
forLegend,
children,
asProp,
className,
tooltip,
tooltipPlacement,
tooltipContent,
tooltipFontSize,
}: LabelProps) => {
const classes = `${generateClasses(isLarge, required)} ${className}`;
return (
<div className="row">
<Label
className={`${classes}`}
required={required}
isLarge={isLarge}
asProp={asProp}
forLegend={forLegend}
tooltip={tooltip}
tooltipPlacement={tooltipPlacement}
tooltipContent={tooltipContent}
tooltipFontSize={tooltipFontSize}
>
{children || 'Field label'}
</Label>
</div>
);
};
Tooltip
The Tooltip is a contextual UI element that displays informative text when users hover over, focus on, or tap a target element. It is commonly used to provide additional explanations or guidance without taking up space in the main interface.
import { Tooltip, TooltipProps } from '@uhg-harmony/react';
import { InfoOutlineIcon } from '@uhg-harmony/icons-react';
import styled, { css } from 'styled-components';
const StyledInfoFilled = styled(InfoOutlineIcon)`
${({ theme }) => css`
fill: ${theme.HarmonyTooltipColorIndicator};
`}
`;
export const BasicExample: React.FC<TooltipProps> = ({
placement,
className,
visible,
maxWidth,
appearOnFocus,
content,
fontSize,
}) => {
return (
<Tooltip
placement={placement ?? 'top'}
content={content ?? 'Tooltip label'}
className={className}
visible={visible}
maxWidth={maxWidth}
appearOnFocus={appearOnFocus}
fontSize={fontSize}
>
<StyledInfoFilled size="18" />
</Tooltip>
);
};
Indicators
Avatar
An Avatar is a graphical representation of users, organizations, groups, projects, or characters. It enables identity expression through customizable visuals.
import { FC } from 'react';
import { Avatar, AvatarProps } from '@uhg-harmony/react';
export const SizeExample: FC<AvatarProps> = ({
className,
initials,
size,
placeHolderIcon,
label,
hideLabel,
subLabel,
labelOrientation,
customSize,
src,
alt,
linkUrl,
newTab,
isButtonContent,
}) => (
<div style={{ display: 'flex', gap: '16px', flexWrap: 'wrap' }}>
<Avatar
label={label}
initials={initials ?? 'JF'}
subLabel={subLabel}
size={size ?? 'xs'}
src={src}
className={className}
placeHolderIcon={placeHolderIcon}
hideLabel={hideLabel}
labelOrientation={labelOrientation}
customSize={customSize}
alt={alt}
linkUrl={linkUrl}
newTab={newTab}
isButtonContent={isButtonContent}
/>
<Avatar
label={label}
initials={initials ?? 'JF'}
subLabel={subLabel}
size={size ?? 's'}
src={src}
className={className}
placeHolderIcon={placeHolderIcon}
hideLabel={hideLabel}
labelOrientation={labelOrientation}
customSize={customSize}
alt={alt}
linkUrl={linkUrl}
newTab={newTab}
isButtonContent={isButtonContent}
/>
<Avatar
label={label}
initials={initials ?? 'JF'}
size={size ?? 'm'}
src={src}
className={className}
placeHolderIcon={placeHolderIcon}
hideLabel={hideLabel}
subLabel={subLabel}
labelOrientation={labelOrientation}
customSize={customSize}
alt={alt}
linkUrl={linkUrl}
newTab={newTab}
isButtonContent={isButtonContent}
/>
<Avatar
label={label}
initials={initials ?? 'JF'}
size={size ?? 'l'}
src={src}
className={className}
placeHolderIcon={placeHolderIcon}
hideLabel={hideLabel}
subLabel={subLabel}
labelOrientation={labelOrientation}
customSize={customSize}
alt={alt}
linkUrl={linkUrl}
newTab={newTab}
isButtonContent={isButtonContent}
/>
<Avatar
label={label}
initials={initials ?? 'JF'}
size={size ?? 'xl'}
src={src}
className={className}
placeHolderIcon={placeHolderIcon}
hideLabel={hideLabel}
subLabel={subLabel}
labelOrientation={labelOrientation}
customSize={customSize}
alt={alt}
linkUrl={linkUrl}
newTab={newTab}
isButtonContent={isButtonContent}
/>
<Avatar
label={label}
initials={initials ?? 'JF'}
size={size ?? 'xxl'}
src={src}
className={className}
placeHolderIcon={placeHolderIcon}
hideLabel={hideLabel}
subLabel={subLabel}
labelOrientation={labelOrientation}
customSize={customSize}
alt={alt}
linkUrl={linkUrl}
newTab={newTab}
isButtonContent={isButtonContent}
/>
</div>
);
Badge
The Badge is a compact UI element used to categorize or label items. It can display text or icons and supports different visual variants.
import { FC } from 'react';
import { Badge, BadgeProps } from '@uhg-harmony/react';
import styled from 'styled-components';
const Layout = styled.div`
display: flex;
flex-wrap: wrap;
align-items: flex-start;
.harmony-badge {
margin: 8px;
}
`;
export const BadgeBasicExample: FC<BadgeProps> = ({ variant, className, label, iconRight }) => (
<div>
<Layout>
<Badge label={label ?? 'Neutral'} variant={variant ?? 'neutral'} iconRight={iconRight} className={className} />
<Badge label={label ?? 'Positive'} variant={variant ?? 'positive'} iconRight={iconRight} className={className} />
<Badge label={label ?? 'Warning'} variant={variant ?? 'warning'} iconRight={iconRight} className={className} />
<Badge label={label ?? 'Negative'} variant={variant ?? 'negative'} iconRight={iconRight} className={className} />
<Badge label={label ?? 'Info'} variant={variant ?? 'info'} iconRight={iconRight} className={className} />
<Badge
label={label ?? 'Info alt light'}
variant={variant ?? 'info-alt-light'}
iconRight={iconRight}
className={className}
/>
<Badge
label={label ?? 'Info alt dark'}
variant={variant ?? 'info-alt-dark'}
iconRight={iconRight}
className={className}
/>
</Layout>
</div>
);
Chip
A chip displays a choice inputted by the user. The user can choose to remove the filter if they wish.
import { FC, useEffect, useState } from 'react';
import { Chip, ChipProps } from '@uhg-harmony/react';
export const SelectableChipExample: FC<ChipProps> = ({ id, className, label, selected }) => {
const [selectedChip, setIsSelected] = useState(selected ?? false);
useEffect(() => {
setIsSelected(selected ?? false);
}, [selected]);
return (
<Chip
id={id}
className={className}
label={label ?? 'Label'}
selected={selectedChip ?? true}
aria-pressed={selectedChip}
onSelectClick={() => {
setIsSelected((prev) => !prev);
}}
/>
);
};
Count
The Count component displays numerical data, such as item totals or notifications.
import { FC } from 'react';
import { Count, CountProps } from '@uhg-harmony/react';
export const BasicExample: FC<CountProps> = ({ id, value, size, className, announceChanges, labelledBy }) => {
return (
<Count
id={id}
className={className}
aria-labelledby={labelledBy}
announceChanges={announceChanges ?? true}
value={value ?? '+1'}
size={size}
/>
);
};
LoadingIndicator
The Loading Indicator is a visual cue that informs users of ongoing processes. It manages expectations during wait times.
import { FC } from 'react';
import { LoadingIndicator, Heading, LoadingIndicatorProps } from '@uhg-harmony/react';
export const BasicExample: FC<LoadingIndicatorProps> = ({
className,
loading,
size,
loadingText,
displayOverlay,
centerSpinner,
accessibilityText,
wrapText,
}) => (
<>
<Heading level="h2">Loader</Heading>
<LoadingIndicator
size={size}
loading={loading}
loadingText={loadingText}
className={className}
centerSpinner={centerSpinner}
displayOverlay={displayOverlay}
accessibilityText={accessibilityText}
wrapText={wrapText}
/>
</>
);
ProgressIndicator
The Progress Indicator visually represents the completion status of a task or process. It provides feedback on how much of the task has been completed and how much remains.
import { FC, useEffect, useRef, useState } from 'react';
import styled from 'styled-components';
import { CloseIcon, CachedIcon } from '@uhg-harmony/icons-react';
import { Button, ProgressIndicator, ProgressIndicatorProps } from '@uhg-harmony/react';
const StyledButton = styled.div`
display: flex;
align-items: center;
gap: 5px; /* Adjust the gap between elements as needed */
`;
export const BasicExample: FC<ProgressIndicatorProps> = ({ className, config, variant }) => {
const [progress, setProgress] = useState(0);
const [complete, setComplete] = useState(false);
const [shouldFocus, setShouldFocus] = useState(false);
const startButtonRef = useRef<HTMLButtonElement>(null);
const progressInterval = useRef<number>(undefined);
useEffect(() => {
return () => clearInterval(progressInterval.current);
}, []);
useEffect(() => {
if (shouldFocus && startButtonRef.current) {
startButtonRef.current.focus();
setShouldFocus(false);
}
}, [shouldFocus]);
const progressIndicatorConfig = {
...config,
progress: progress,
complete: complete,
};
const getProgress = () => {
let x = 0;
progressInterval.current = window.setInterval(() => {
if (x < 100) {
x = x + 1;
setProgress(x);
} else {
setComplete(true);
clearInterval(progressInterval.current);
}
}, 100);
};
const resetProgress = () => {
// Reset progress and complete states
setProgress(0);
setComplete(false);
// Clear the setInterval timer
clearInterval(progressInterval.current);
// Manually focus on the start button element.
setShouldFocus(true);
};
return (
<>
<ProgressIndicator
className={className}
id="basic-progress-indicator"
config={progressIndicatorConfig}
variant={variant}
/>
{progress === 0 && (
<Button buttonRef={startButtonRef as React.MutableRefObject<HTMLButtonElement>} size="s" onPress={getProgress}>
Start
</Button>
)}
{progress > 0 && !complete && (
<Button variant="secondary" size="s" onPress={resetProgress}>
<StyledButton>
<CloseIcon size="18" />
Cancel
</StyledButton>
</Button>
)}
{complete && (
<Button variant="secondary" size="s" onPress={resetProgress}>
<StyledButton>
<CachedIcon size="18" />
Reset
</StyledButton>
</Button>
)}
</>
);
};
StepTracker
The Step Tracker breaks down complex workflows into sequential steps, helping users understand their progress and what actions are required next. It enhances clarity and reduces cognitive load in multi-step processes.
import { StepTracker, StepperProps } from '@component';
import { FC } from 'react';
export const stepTrackerItems = [
{ label: '1. Step one', status: 'completed', id: 1, isCurrentProcessComplete: false },
{ label: '2. Step two', status: 'completed', id: 2, isCurrentProcessComplete: false },
{ label: '3. Step three', status: 'current', id: 3, isCurrentProcessComplete: false },
{ label: '4. Step four', status: 'incomplete', id: 4, isCurrentProcessComplete: false },
{ label: '5. Step five', status: 'incomplete', id: 5, isCurrentProcessComplete: false },
{ label: '6. Step six', status: 'incomplete', id: 6, isCurrentProcessComplete: false },
];
export const BasicExample: FC<StepperProps> = ({ isHorizontal, withStatus }) => {
return <StepTracker isHorizontal={isHorizontal} stepTrackerItems={stepTrackerItems} withStatus={withStatus} />;
};
Inputs
Checkbox
Checkboxes allow users to select multiple options from a list. They are essential for forms, filters, and preference settings where multiple selections are appropriate.
import { ChangeEvent, FC, useState } from 'react';
import { Checkbox, CheckboxProps, FormControl } from '@uhg-harmony/react';
export const BasicExample: FC<CheckboxProps> = ({ checked, disabled, required }) => {
const [ischecked, setChecked] = useState(checked);
return (
<FormControl id="checkbox-basic" required={required} disabled={disabled}>
<Checkbox
checked={ischecked || checked}
onChange={(e: ChangeEvent<HTMLInputElement>) => setChecked(e.target.checked)}
>
Checkbox
</Checkbox>
</FormControl>
);
};
DatePicker
The Date Picker is an input component used for selecting dates. It can display past, present, or future dates, as they are relevant to the task. It allows users to view and pick dates from a calendar-based interface or manually type the date in the text field. It is typically used in forms and interfaces where date input is required.
import { FC } from 'react';
import { FormControl, HelperText, Label, DatePicker, DatePickerProps } from '@uhg-harmony/react';
import styled from 'styled-components';
import 'react-day-picker/dist/style.css';
const StoryWrapper = styled.div`
margin-left: 3.125rem;
`;
export const BasicExample: FC<DatePickerProps> = ({ className, disabled, required }) => {
return (
<StoryWrapper>
<FormControl
id={'date-picker-basic'}
required={required ?? false}
disabled={disabled ?? false}
reasonForDisabled="This date picker is disabled"
>
<Label>Field Label</Label>
<HelperText>Date Format (MM/DD/YYYY)</HelperText>
<DatePicker
className={className ?? 'harmony-date-picker-basic'}
disabled={disabled ?? false}
invalidInputMessage="Invalid date format"
/>
</FormControl>
</StoryWrapper>
);
};
DropdownMulti
The Multi Select Dropdown enables the selection of multiple options from a dropdown list. It is ideal for scenarios where multiple selections are needed, such as filtering results or setting preferences. This component enhances flexibility while maintaining a compact and user-friendly interface.
import { FC } from 'react';
import { Dropdown, FormControl, HelperText, IDropdownItem, Label, DropdownMultiProps } from '@uhg-harmony/react';
export const countries: IDropdownItem[] = [
{ id: '1', label: 'England', value: 'ENG' },
{ id: '2', label: 'Ireland', value: 'IRE' },
{ id: '3', label: 'Scotland', value: 'SCOT' },
{ id: '4', label: 'France', value: 'FRANC' },
{ id: '5', label: 'Germany', value: 'GER' },
];
export const MultiExample: FC<DropdownMultiProps> = ({ items, fieldsetLabel, placeholderText, selectAllLabel }) => (
<FormControl id="dropdown-multi">
<Label>My label</Label>
<HelperText>My helper text</HelperText>
<Dropdown
type="multi"
items={items}
fieldsetLabel={fieldsetLabel}
placeholderText={placeholderText}
selectAllLabel={selectAllLabel}
/>
</FormControl>
);
DropdownSingle
The Single Select Dropdown allows for the selection of one option from a dropdown list. It is a core element that improves user experience by simplifying selection tasks in forms and menus.
import { FC } from 'react';
import { Dropdown, FormControl, HelperText, IDropdownItem, Label } from '@uhg-harmony/react';
const countries: IDropdownItem[] = [
{ id: '1', label: 'England', value: 'ENG' },
{ id: '2', label: 'Ireland', value: 'EIR' },
{ id: '3', label: 'Scotland', value: 'SCOT' },
{ id: '4', label: 'France', value: 'FRANC' },
{ id: '5', label: 'Germany', value: 'GER' },
];
interface BasicExampleProps {
id?: string;
label?: string;
helperText?: string;
items?: IDropdownItem[];
}
export const BasicExample: FC<BasicExampleProps> = ({ id, label, helperText, items }) => {
return (
<FormControl id={id ?? 'dropdown-basic'}>
<Label id={id ?? 'dropdown-basic-lbl'}>{label ?? 'My label'}</Label>
<HelperText>{helperText ?? 'My helper text'}</HelperText>
<Dropdown type="single" items={items ?? countries} />
</FormControl>
);
};
Fieldset
The Fieldset component groups related form elements under a shared legend or label. It enhances accessibility and visual organization, especially in complex forms, by clearly separating sections and guiding user input.
import { FC } from 'react';
import { Fieldset, HelperText, Legend } from '@uhg-harmony/react';
export const BasicExample: FC = () => {
return (
<Fieldset>
<Legend>Personal details</Legend>
<HelperText>
All fields marked with an asterisk (<span className="optum-asterisk"></span>) are required
</HelperText>
</Fieldset>
);
};
RadioButtonGroup
Radio Buttons enable selection of a single option from a predefined set. They are useful for mutually exclusive choices in forms and surveys.
import { FC, useState, ChangeEvent } from 'react';
import { FormControl, HelperText, Label, RadioButton, RadioButtonProps } from '@uhg-harmony/react';
export const BasicExample: FC = ({
className,
disabled,
required,
errorMsgOrientation,
alignHorizontal,
}: RadioButtonProps) => {
const [checked, setChecked] = useState('');
const [blurred, setBlurred] = useState(false);
const error = required && checked.length === 0 && blurred ? 'A minimum of one value is required' : '';
const setValue = (e: ChangeEvent<HTMLInputElement>) => {
setChecked(e.target.value);
};
return (
<FormControl
id="radio-group-basic"
disabled={disabled}
error={error}
required={required ?? false}
useHorizontalLayout={alignHorizontal}
errorMsgOrientation={errorMsgOrientation}
reasonForDisabled="Explain disabled logic"
>
<Label forLegend>Field label</Label>
<HelperText>Helper text</HelperText>
<RadioButton
name={'radio-group-basic'}
value={'Option-1'}
checked={checked === 'Option-1'}
onChange={setValue}
onBlur={() => setBlurred(required ? true : false)}
className={className}
>
Option 1
</RadioButton>
<RadioButton
name={'radio-group-basic'}
value={'Option-2'}
checked={checked === 'Option-2'}
onChange={setValue}
className={className}
>
Option 2
</RadioButton>
<RadioButton
name={'radio-group-basic'}
value={'Option-3'}
checked={checked === 'Option-3'}
onChange={setValue}
className={className}
>
Option 3
</RadioButton>
</FormControl>
);
};
SearchField
The Search Field is a specialized input for text search functionality. It features placeholder text, change callbacks, and search action triggers with adaptable styling. Designed for flexibility, it accepts all standard HTML input props and adapts to various use cases in web applications.
import { FC } from 'react';
import { SearchField, SearchFieldProps, FormControl } from '@uhg-harmony/react';
import { SearchIcon } from '@uhg-harmony/icons-react';
export const BasicExample: FC<SearchFieldProps> = ({className, placeholder, width}) => {
return (
<FormControl id="search-field-basic">
<SearchField
initialValue=""
className={className}
placeholder={placeholder}
width= {width}
searchIcon={<SearchIcon />}
/>
</FormControl>
);
};
TextArea
A Text Area is a multi-line input field for longer text entries. It is ideal for collecting longer responses, comments, or detailed input.
import { FC } from 'react';
import { FormControl, HelperText, Label, TextArea, TextAreaProps } from '@uhg-harmony/react';
export const BasicExample: FC = ({
className,
remainingCharsMessage,
textAreaRef,
maxLength,
placeholder,
resize,
minHeight,
disabled,
required,
}: TextAreaProps) => (
<FormControl id={'text-area'} disabled={disabled} required={required}>
<Label>Field label</Label>
<HelperText>Helper text</HelperText>
<TextArea
className={className}
remainingCharsMessage={remainingCharsMessage}
textAreaRef={textAreaRef}
maxLength={maxLength}
placeholder={placeholder}
resize={resize}
minHeight={minHeight}
/>
</FormControl>
);
TextInput
A Text Input is a single-line field for capturing text data. It is a foundational element of form interfaces with support for various input types and validation.
import { FC } from 'react';
import { TextInput, Label, HelperText, FormControl, TextInputProps, FormControlProps } from '@uhg-harmony/react';
export const BasicExample: FC = ({
width,
className,
disabled,
required,
}: TextInputProps & Omit<FormControlProps, 'children' | 'id'>) => (
<FormControl id={'text-input'} disabled={disabled} required={required}>
<Label isLarge tooltip tooltipPlacement="right" tooltipContent="This is a tooltip" tooltipFontSize="small">
Field label
</Label>
<HelperText>Helper text</HelperText>
<TextInput className={className} width={width} />
</FormControl>
);
ToggleSwitch
A Toggle Switch is a binary control that toggles between two states: on/off or enable/disable. It is best suited for immediate actions that take effect upon toggling.
import { FC, useState } from 'react';
import { FormControl, Label, ToggleSwitch, ToggleSwitchProps } from '@uhg-harmony/react';
export const BasicExample: FC<Partial<ToggleSwitchProps>> = ({
className,
customLabelForOffState,
customLabelForOnState,
disabled,
size,
}) => {
const [isToggledOn, setIsToggledOn] = useState(false);
const handleToggleChange = (state: boolean) => {
setIsToggledOn(state);
};
return (
<FormControl disabled={disabled} id="toggle-switch-formcontrol" className="mb-l">
<Label>Field label</Label>
<ToggleSwitch
id="label-helpertext-toggle-switch"
className={className}
customLabelForOffState={customLabelForOffState}
customLabelForOnState={customLabelForOnState}
size={size}
initialState={isToggledOn}
onChange={handleToggleChange}
/>
</FormControl>
);
};
Navigation
Breadcrumb
The Breadcrumb component displays a navigational trail showing the user's current location within the application hierarchy. It helps users understand their path and easily navigate back to previous pages or views.
import { FC } from 'react';
import { Breadcrumb, BreadcrumbProps } from '@uhg-harmony/react';
import styled from 'styled-components';
const StoryWrapper = styled.div`
display: flex;
flex-direction: column;
gap: 20px;
`;
export const breadcrumbItems = [
{ href: '#', title: 'Breadcrumb Title 1', supplementalText: 'Supplemental text' },
{ href: '#', title: 'Breadcrumb Title 2', supplementalText: 'Supplemental text' },
{ href: '#', title: 'Breadcrumb Title 3', supplementalText: 'Supplemental text' },
{ href: '#', title: 'Current Page', supplementalText: 'Supplemental text' },
];
export const BasicExample: FC<BreadcrumbProps> = ({ className, breadcrumbItems }) => {
return (
<StoryWrapper>
<Breadcrumb breadcrumbItems={breadcrumbItems} showSupplementalText={false} className={className} />
<Breadcrumb breadcrumbItems={breadcrumbItems} showSupplementalText={true} className={className} />
</StoryWrapper>
);
};
Link
Links are navigational elements that direct users to other sections of the application or external resources. They implement accessible design patterns for intuitive and consistent navigation.
import { FC } from 'react';
import { Link, LinkProps } from '@uhg-harmony/react';
import { ChevronRightIcon } from '@uhg-harmony/icons-react';
export const BasicExample: FC<LinkProps> = ({
href,
className,
size,
iconLeft,
openInNewTab,
screenReaderOnlyText,
underline,
inverse,
}) => {
return (
<Link
href={href ?? '#'}
icon={<ChevronRightIcon />}
className={className}
size={size}
iconLeft={iconLeft}
openInNewTab={openInNewTab}
screenReaderOnlyText={screenReaderOnlyText}
underline={underline}
inverse={inverse}
>
Basic link with chevron
</Link>
);
};
Patterns
Modal
A Modal is an overlay dialog that focuses user attention on a single task or piece of information using a temporary window that covers part of the page. Modals intentionally prevent further interaction with the page until the modal task is completed or dismissed by the user. Modals should be used sparingly due to their disruptive nature.
This pattern features customizable slots that allow for flexible content composition and consistent structure.
import { FC, useEffect, useRef, useState } from 'react';
import { Button, Modal, ModalProps } from '@uhg-harmony/react';
import styled from 'styled-components';
const VisuallyHidden = styled.span`
clip: rect(0 0 0 0);
clip-path: inset(50%);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
`;
const Container = styled.div`
display: flex;
padding: 56px 32px;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 16px;
align-self: stretch;
background-color: rgba(12, 85, 184, 0.1);
border-radius: 12px;
`;
const BodyHeading = styled.h2`
line-height: 120%;
color: #0c55b8;
`;
const ParagraphHeading = styled.p`
line-height: 150%;
color: #0c55b8;
`;
const RootContainer = styled.div`
display: flex;
flex-direction: column;
gap: 16px;
width: 100%;
height: 550px;
max-height: 100%;
overflow-y: auto;
`;
export const SlotsExample: FC<ModalProps> = ({ title, open }) => {
const [isOpen, setOpen] = useState(open);
const dismiss = () => setOpen(false);
const [tabIndex, setTabIndex] = useState<number | undefined>(undefined);
const rootContainerRef = useRef<HTMLDivElement>(null);
useEffect(() => {
setOpen(open);
}, [open]);
useEffect(() => {
const checkHeight = () => {
if (rootContainerRef.current) {
const contentHeight = rootContainerRef.current.scrollHeight;
setTabIndex(contentHeight > 550 ? 0 : undefined);
}
};
checkHeight();
window.addEventListener('resize', checkHeight);
return () => {
window.removeEventListener('resize', checkHeight);
};
}, [isOpen]);
return (
<>
<Button onPress={() => setOpen(true)}>
Open Modal
<VisuallyHidden>Opens modal window</VisuallyHidden>
</Button>
{isOpen && (
<Modal open={isOpen} title={title} onClose={dismiss}>
<Modal.Body>
<RootContainer ref={rootContainerRef} tabIndex={tabIndex}>
<Container>
<BodyHeading>Slot 1</BodyHeading>
<ParagraphHeading>Section containing content.</ParagraphHeading>
</Container>
<Container>
<BodyHeading>Slot 2</BodyHeading>
<ParagraphHeading>Section containing content.</ParagraphHeading>
</Container>
</RootContainer>
</Modal.Body>
<Modal.Actions>
<Button onPress={dismiss}>Button label</Button>
<Button variant="secondary" onPress={dismiss}>
Button label
</Button>
</Modal.Actions>
</Modal>
)}
</>
);
};
ReadOnly
The Read Only pattern is used to display previously entered form values in a non-editable format. It is commonly used in review or confirmation states where users need to see what they’ve submitted without making changes. It is implemented using the ReadOnlyFieldValueList component.
This pattern is especially useful for summarizing user input such as values from a Text Input or selections from a Checkbox group.
It ensures clarity and consistency while maintaining accessibility and visual alignment with the original form layout.
In this example, a value that was previously supplied to a Text Input is rendered.
import { FC } from 'react';
import { ReadOnlyFieldValueList } from '@uhg-harmony/react';
export const ReadOnlyExample: FC = () => (
<ReadOnlyFieldValueList
id="read-only-field"
label="Field label"
helperText="Helper text"
displayValues={['Value']}
tooltip={true}
tooltipPlacement="right"
tooltipContent="This is a tooltip"
tooltipFontSize="small"
/>
);
Wizard
The Wizard is a UI pattern designed to guide users through complex workflows by dividing them into a series of sequential steps.
It is implemented using the StepTracker component to visually indicate progress, combined with the button component that allows users to move through each step.
This pattern helps simplify multi-step processes by providing structure, clarity, and actionable guidance.
import { Button, StepperProps, StepTracker } from '@uhg-harmony/react';
import { FC, useEffect, useState } from 'react';
export const wizardItems = [
{ label: '1. Step one', status: 'completed', id: 1, isCurrentProcessComplete: false },
{ label: '2. Step two', status: 'current', id: 2, isCurrentProcessComplete: false },
{ label: '3. Step three', status: 'incomplete', id: 3, isCurrentProcessComplete: false },
{ label: '4. Step four', status: 'incomplete', id: 4, isCurrentProcessComplete: false },
{ label: '5. Step five', status: 'incomplete', id: 5, isCurrentProcessComplete: false },
{ label: '6. Step six', status: 'incomplete', id: 6, isCurrentProcessComplete: false },
];
export const BasicExample: FC<StepperProps> = ({ isHorizontal, stepTrackerItems, withStatus }) => {
const [wizardArray, setwizardItems] = useState(stepTrackerItems||[]);
const [enableNextButton, setEnableNextButton] = useState(false);
const [disabledCompleted, setDisabledCompleted] = useState(false);
useEffect(() => {
setwizardItems(wizardItems);
}, [wizardItems]);
useEffect(() => {
setDisabledCompleted(wizardArray?.every((item) => item.status === 'completed'));
}, [wizardArray]);
const handleButtonClick = () => {
const updatedJson = wizardArray.map((step) => {
if (step.status === 'current') {
return { ...step, status: 'completed', isCurrentProcessComplete: true };
}
return step;
});
setEnableNextButton(true);
setwizardItems(updatedJson);
};
const onClickNext = () => {
const count = wizardArray.filter((step) => step.status === 'current');
const updatedJson = wizardArray.map((step, index, array) => {
if (
index > 0 &&
(array[index - 1].status === 'current' || (index > 0 && array[index - 1].status === 'completed')) &&
step.status === 'incomplete' &&
count.length === 0
) {
// Mark the next step as current
return { ...step, status: 'current', isCurrentProcessComplete: true };
}
if (step.status === 'completed' && step.isCurrentProcessComplete === true) {
return { ...step, status: 'completed', isCurrentProcessComplete: false };
}
return step;
});
setEnableNextButton(false);
setwizardItems(updatedJson);
};
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '5rem' }}>
<StepTracker
isHorizontal={isHorizontal ?? true}
stepTrackerItems={wizardArray ?? wizardItems}
withStatus={withStatus}
/>
<div style={{ display: 'flex', flexDirection: 'row', gap: '7px' }}>
<Button
onPress={handleButtonClick}
onKeyDown={(e) => {
if (e.key === 'Enter') handleButtonClick();
}}
tabIndex={0}
disabled={disabledCompleted}
>
Complete Step
</Button>
<Button
onPress={onClickNext}
onKeyDown={(e) => {
if (e.key === 'Enter') onClickNext();
}}
disabled={disabledCompleted || !enableNextButton}
>
Next
</Button>
</div>
</div>
);
};
Coming Soon
Card
The Card component is a versatile container that can be used to display content and actions on a single topic. It can contain various elements such as text, images, and buttons, making it a great choice for showcasing information in a structured and visually appealing way. The Card component supports optional header, subheader, and media elements, allowing for a high degree of customization.
import { FC } from 'react';
import { Card, CardProps, Heading } from '@uhg-harmony/react';
export const BasicExample: FC<CardProps> = ({ className }) => (
<Card className={className} header={<Heading level="h2">Card header</Heading>}>
<p>This is the card content text.</p>
</Card>
);
Footer
The Footer component helps improve the user experience by providing easy access to essential information and resources, ensuring consistency and accessibility throughout the site.
import { FC } from 'react';
import { Footer, FooterProps } from '@uhg-harmony/react';
export const linkConfig = {
links: [
{
href: '/',
label: 'Link1',
},
{
href: 'https://react-alpha-harmony.ofp-elr-dev.optum.com/?path=/docs/getting-started-overview--docs',
label: 'Link2',
openInNewTab: true,
},
{
href: 'https://react-alpha-harmony.ofp-elr-dev.optum.com/?path=/docs/getting-started-overview--docs',
label: 'Link3',
openInNewTab: true,
},
],
};
export const BasicExample: FC<FooterProps> = ({ linkConfig, copyrightText, className }) => {
return (
<Footer linkConfig={linkConfig} copyrightText={copyrightText} className={className}>
This is placeholder text. This is where you should place your legal text and/or privacy notice. It is recommended
that you consult with your legal advisors for text that is relevant and adequate for your context and use. Harmony
cannot offer advice on legal text or privacy notices, this is outside our remit as a design system. Thank you for
using Harmony.
</Footer>
);
};
Navigation
The navigation component is a user interface element that allows users to move between different sections or pages of an application or website. It typically includes links, buttons, or menus that are organized in a way that helps users find and access content efficiently. Navigation components are essential for enhancing user experience by providing clear and intuitive pathways to various parts of the site or app.
import { FC } from 'react';
import { HeaderComponent as Header } from '@uhg-harmony/react';
import Logo from '../../../../../svg/Optum.svg';
const defaultLogo = <img src={Logo} className="harmony-header__logo" alt="logo" />;
export const HeaderExample: FC<{ logoContent?: React.ReactNode }> = ({ logoContent = defaultLogo }) => (
<Header logoContent={logoContent} productName="Product name A" productLink="#" />
);
Header
Demonstrates the basic usage of the Header component, showcasing its default behavior and appearance.
import { FC } from 'react';
import { HeaderComponent as Header } from '@uhg-harmony/react';
import Logo from '../../../../../svg/Optum.svg';
const defaultLogo = <img src={Logo} className="harmony-header__logo" alt="logo" />;
export const HeaderExample: FC<{ logoContent?: React.ReactNode }> = ({ logoContent = defaultLogo }) => (
<Header logoContent={logoContent} productName="Product name A" productLink="#" />
);
Global
Illustrates the basic usage and functionality of the Global Navigation component.
import { FC, useEffect, useRef } from 'react';
import {
anchorProperties,
Button,
getNativeProps,
HeaderComponent as Header,
Heading,
NavigationLinkProps,
} from '@uhg-harmony/react';
import { Link, MemoryRouter, useLocation } from 'react-router-dom';
import Logo from '../../../../../svg/Optum.svg';
import styled from 'styled-components';
const AppContent = styled.div`
margin: 24px 32px;
`;
const CurrentRouteWrapper = styled.div`
padding: 12px 0;
`;
const CurrentRoute = styled.span`
margin-left: 8px;
`;
const CurrentRouteContainer: FC = () => (
<CurrentRouteWrapper>
<strong>Current Route:</strong>
<CurrentRoute>{useCurrentRoute()}</CurrentRoute>
</CurrentRouteWrapper>
);
const defaultLogo = <img src={Logo} className="harmony-header__logo" alt="logo" />;
// create hook to return the current route
const useCurrentRoute = () => {
const { pathname: route } = useLocation();
return route;
};
// define our custom link so client side routing works
const RoutableLink: FC<NavigationLinkProps> = (item) => {
const { children, url = '/' } = item;
const anchorProps = getNativeProps(item, anchorProperties);
return (
<Link to={url} {...anchorProps}>
{children}
</Link>
);
};
// define our navigation config
// Note: do not define this in the body of a function component unless you give
// it a stable identity via useRef
const globalNavigationConfig = {
linkAs: RoutableLink,
links: [
{
label: 'Home',
links: [
{ label: 'My account', url: '/account' },
{
label: 'My orders',
links: [
{ label: 'Delivered', url: '/delivered' },
{ label: 'Pending', url: '/pending' },
{
label: 'Archived',
links: [
{
label: '2018',
url: '/2018',
},
{
label: '2019',
url: '/2019',
},
{
label: '2020',
url: '/2020',
},
],
},
],
},
{ label: 'My profile', url: '/profile' },
],
},
{
label: 'About',
links: [
{
label: 'History',
url: '/history',
},
{
label: 'Locations',
links: [
{
label: 'Europe',
url: '/eu',
},
{
label: 'U.S',
url: '/us',
},
],
},
],
},
{ label: 'Contact', url: '/contact' },
],
};
export const GlobalExample: FC<{ logoContent?: React.ReactNode }> = ({ logoContent = defaultLogo }) => {
const mainRef = useRef<HTMLElement>(null);
useEffect(() => {
const url = window.location.href;
if (mainRef?.current && url.includes('#main')) {
mainRef.current.focus();
}
}, []);
return (
<>
<MemoryRouter>
<Header
logoContent={logoContent}
globalNavigation={globalNavigationConfig}
useLocation={useCurrentRoute}
skipLink={{ id: 'main' }}
productName="Product name A"
productLink="#"
/>
<AppContent>
<CurrentRouteContainer />
<main tabIndex={-1} id="main" ref={mainRef}>
<Heading>Main content</Heading>
<Button onPress={() => alert('click')}>Focusable button</Button>
</main>
</AppContent>
</MemoryRouter>
</>
);
};
Primary Horizontal
Demonstrates the horizontal navigation setup and usage.
import { FC, useEffect, useRef } from 'react';
import {
anchorProperties,
Button,
getNativeProps,
HeaderComponent as Header,
Heading,
NavigationLinkProps,
} from '@uhg-harmony/react';
import { Link, MemoryRouter, useLocation } from 'react-router-dom';
import Logo from '../../../../../svg/Optum.svg';
import styled from 'styled-components';
const AppContent = styled.div`
margin: 24px 32px;
`;
const CurrentRouteWrapper = styled.div`
padding: 12px 0;
`;
const CurrentRoute = styled.span`
margin-left: 8px;
`;
const CurrentRouteContainer: FC = () => (
<CurrentRouteWrapper>
<strong>Current Route:</strong>
<CurrentRoute>{useCurrentRoute()}</CurrentRoute>
</CurrentRouteWrapper>
);
const defaultLogo = <img src={Logo} className="harmony-header__logo" alt="logo" />;
// create hook to return the current route
const useCurrentRoute = () => {
const { pathname: route } = useLocation();
return route;
};
// define our custom link so client side routing works
const RoutableLink: FC<NavigationLinkProps> = (item) => {
const { children, url = '/' } = item;
const anchorProps = getNativeProps(item, anchorProperties);
return (
<Link to={url} {...anchorProps}>
{children}
</Link>
);
};
// define our navigation config
// Note: do not define this in the body of a function component unless you give
// it a stable identity via useRef
const horizontalNavigationConfig = {
linkAs: RoutableLink,
links: [
{
label: 'Home',
links: [
{ label: 'My account', url: '/account' },
{
label: 'My orders',
links: [
{ label: 'Delivered', url: '/delivered' },
{ label: 'Pending', url: '/pending' },
{
label: 'Archived',
links: [
{
label: '2018',
url: '/2018',
},
{
label: '2019',
url: '/2019',
},
{
label: '2020',
url: '/2020',
},
],
},
],
},
{ label: 'My profile', url: '/profile' },
],
},
{
label: 'About',
links: [
{
label: 'History',
url: '/history',
},
{
label: 'Locations',
links: [
{
label: 'Europe',
url: '/eu',
},
{
label: 'U.S',
url: '/us',
},
],
},
],
},
{ label: 'Contact', url: '/contact' },
],
};
export const PrimaryHorizontalExample: FC<{ logoContent?: React.ReactNode }> = ({ logoContent = defaultLogo }) => {
const mainRef = useRef<HTMLElement>(null);
useEffect(() => {
const url = window.location.href;
if (mainRef?.current && url.includes('#main')) {
mainRef.current.focus();
}
}, []);
return (
<>
<MemoryRouter>
<Header
logoContent={logoContent}
horizontalNavigation={horizontalNavigationConfig}
useLocation={useCurrentRoute}
skipLink={{ id: 'main' }}
productName="Product name A"
productLink="#"
/>
<AppContent>
<CurrentRouteContainer />
<main tabIndex={-1} id="main" ref={mainRef}>
<Heading>Main content</Heading>
<Button onPress={() => alert('click')}>Focusable button</Button>
</main>
</AppContent>
</MemoryRouter>
</>
);
};
Primary Vertical
Demonstrates the vertical navigation setup and usage.
import { FC, useEffect, useRef, useState } from 'react';
import {
anchorProperties,
Button,
getNativeProps,
HeaderComponent as Header,
Heading,
NavigationLinkProps,
NavType,
Navigation,
} from '@uhg-harmony/react';
import { Link, MemoryRouter, useLocation } from 'react-router-dom';
import Logo from '../../../../../svg/Optum.svg';
import styled from 'styled-components';
const App = styled.div`
height: 100%;
@media only screen and (min-width: 980px) {
display: flex;
flex-direction: column;
}
`;
const AppContent = styled.div`
height: 100%;
display: flex;
flex-direction: column;
@media only screen and (min-width: 980px) {
flex-direction: row;
}
`;
const CurrentRouteWrapper = styled.div`
padding: 12px 0;
`;
const CurrentRoute = styled.span`
margin-left: 8px;
`;
const Main = styled.main`
margin: 20px;
`;
const VerticalNavigation = styled(Navigation)`
@media only screen and (min-width: 980px) {
position: sticky;
top: 0;
height: calc(100vh - 86px);
li:first-of-type > button,
li:first-of-type > a {
&:before {
display: none;
}
}
}
`;
const CurrentRouteContainer: FC = () => (
<CurrentRouteWrapper>
<strong>Current route:</strong>
<CurrentRoute>{useCurrentRoute()}</CurrentRoute>
</CurrentRouteWrapper>
);
const defaultLogo = <img src={Logo} className="harmony-header__logo" alt="logo" />;
// create hook to return the current route
const useCurrentRoute = () => {
const { pathname: route } = useLocation();
return route;
};
// define our custom link so client side routing works
const RoutableLink: FC<NavigationLinkProps> = (item) => {
const { children, url = '/' } = item;
const anchorProps = getNativeProps(item, anchorProperties);
return (
<Link to={url} {...anchorProps}>
{children}
</Link>
);
};
// define our navigation config
// Note: do not define this in the body of a function component unless you give
// it a stable identity via useRef
const verticalNavigationConfig = {
linkAs: RoutableLink,
links: [
{
label: 'Home',
links: [
{ label: 'My account', url: '/account' },
{
label: 'My orders',
links: [
{ label: 'Delivered', url: '/delivered' },
{ label: 'Pending', url: '/pending' },
{
label: 'Archived',
links: [
{
label: '2018',
url: '/2018',
},
{
label: '2019',
url: '/2019',
},
{
label: '2020',
url: '/2020',
},
],
},
],
},
{ label: 'My profile', url: '/profile' },
],
},
{
label: 'About',
links: [
{
label: 'History',
url: '/history',
},
{
label: 'Locations',
links: [
{
label: 'Europe',
url: '/eu',
},
{
label: 'U.S',
url: '/us',
},
],
},
],
},
{ label: 'Contact', url: '/contact' },
],
};
export const PrimaryVerticalExample: FC<{ logoContent?: React.ReactNode }> = ({ logoContent = defaultLogo }) => {
const mainRef = useRef<HTMLElement>(null);
useEffect(() => {
const url = window.location.href;
if (mainRef?.current && url.includes('#main')) {
mainRef.current.focus();
}
}, []);
// define state to track if the vertical nav should be shown
const [verticalNavShow, setVerticalNavShow] = useState(false);
// handle resizing of the window to show/hide the vertical nav
useEffect(() => {
const handleResize = () => {
if (window.innerWidth < 980) {
setVerticalNavShow(false);
} else {
setVerticalNavShow(true);
}
};
window.addEventListener('resize', handleResize);
handleResize();
return () => window.removeEventListener('resize', handleResize);
}, []);
return (
<MemoryRouter>
<App>
<Header
logoContent={logoContent}
skipLink={{ id: 'main' }}
productName="Product name A"
productLink="#"
horizontalNavigation={!verticalNavShow ? verticalNavigationConfig : undefined} // only show horizontal nav if vertical nav is hidden
useLocation={useCurrentRoute}
/>
<AppContent>
{/* only show vertical nav if the window is wide enough */}
{verticalNavShow && (
<VerticalNavigation
useLocation={useCurrentRoute}
variant={NavType.VERTICAL}
config={verticalNavigationConfig}
/>
)}
<Main tabIndex={-1} id="main" ref={mainRef}>
<Heading>Main content</Heading>
<Button onPress={() => alert('click')}>Focusable button</Button>
<CurrentRouteContainer />
</Main>
</AppContent>
</App>
</MemoryRouter>
);
};
Global Nav Button with Avatar
Showcases the Global Navigation Button with an avatar, demonstrating its setup and usage.
import { FC, useEffect, useRef } from 'react';
import {
anchorProperties,
Avatar,
Button,
getNativeProps,
HeaderComponent as Header,
Heading,
NavigationLinkProps,
} from '@uhg-harmony/react';
import { Link, MemoryRouter, useLocation } from 'react-router-dom';
import Logo from '../../../../../svg/Optum.svg';
import styled from 'styled-components';
import JohnImg from '../../../../../assets/man1.png';
const AppContent = styled.div`
margin: 24px 32px;
`;
const CurrentRouteWrapper = styled.div`
padding: 12px 0;
`;
const CurrentRoute = styled.span`
margin-left: 8px;
`;
const CurrentRouteContainer: FC = () => (
<CurrentRouteWrapper>
<strong>Current Route:</strong>
<CurrentRoute>{useCurrentRoute()}</CurrentRoute>
</CurrentRouteWrapper>
);
const defaultLogo = <img src={Logo} className="harmony-header__logo" alt="logo" />;
// create hook to return the current route
const useCurrentRoute = () => {
const { pathname: route } = useLocation();
return route;
};
// define our custom link so client side routing works
const RoutableLink: FC<NavigationLinkProps> = (item) => {
const { children, url = '/' } = item;
const anchorProps = getNativeProps(item, anchorProperties);
return (
<Link to={url} {...anchorProps}>
{children}
</Link>
);
};
// define our navigation config
// Note: do not define this in the body of a function component unless you give
// it a stable identity via useRef
const globalNavButtonAvatarConfig = {
linkAs: RoutableLink,
links: [
{
label: 'About',
links: [
{
label: 'History',
url: '/history',
},
{
label: 'Locations',
links: [
{
label: 'Europe',
url: '/eu',
},
{
label: 'U.S',
url: '/us',
},
],
},
],
},
{
label: 'Profile',
//@ts-expect-error fix later
customContent: <Avatar as={'span'} label={'John'} size={'xs'} src={JohnImg} hideLabel isButtonContent />,
links: [
{ label: 'Settings', url: '/settings' },
{ label: 'Log out', url: '/logout' },
],
},
],
};
export const GlobalButtonAvatarExample: FC<{ logoContent?: React.ReactNode }> = ({ logoContent = defaultLogo }) => {
const mainRef = useRef<HTMLElement>(null);
useEffect(() => {
const url = window.location.href;
if (mainRef?.current && url.includes('#main')) {
mainRef.current.focus();
}
}, []);
return (
<>
<MemoryRouter>
<Header
logoContent={logoContent}
globalNavigation={globalNavButtonAvatarConfig}
useLocation={useCurrentRoute}
skipLink={{ id: 'main' }}
productName="Product name A"
productLink="#"
/>
<AppContent>
<CurrentRouteContainer />
<main tabIndex={-1} id="main" ref={mainRef}>
<Heading>Main content</Heading>
<Button onPress={() => alert('click')}>Focusable button</Button>
</main>
</AppContent>
</MemoryRouter>
</>
);
};
Global Nav Link with Avatar
Showcases the Global Navigation Link with an avatar, demonstrating its setup and usage.
import { FC, useEffect, useRef } from 'react';
import {
anchorProperties,
Avatar,
Button,
getNativeProps,
HeaderComponent as Header,
Heading,
NavigationLinkProps,
} from '@uhg-harmony/react';
import { Link, MemoryRouter, useLocation } from 'react-router-dom';
import Logo from '../../../../../svg/Optum.svg';
import styled from 'styled-components';
import JohnImg from '../../../../../assets/man1.png';
const AppContent = styled.div`
margin: 24px 32px;
`;
const CurrentRouteWrapper = styled.div`
padding: 12px 0;
`;
const CurrentRoute = styled.span`
margin-left: 8px;
`;
const CurrentRouteContainer: FC = () => (
<CurrentRouteWrapper>
<strong>Current route:</strong>
<CurrentRoute>{useCurrentRoute()}</CurrentRoute>
</CurrentRouteWrapper>
);
const defaultLogo = <img src={Logo} className="harmony-header__logo" alt="logo" />;
// create hook to return the current route
const useCurrentRoute = () => {
const { pathname: route } = useLocation();
return route;
};
// define our custom link so client side routing works
const RoutableLink: FC<NavigationLinkProps> = (item) => {
const { children, url = '/' } = item;
const anchorProps = getNativeProps(item, anchorProperties);
return (
<Link to={url} {...anchorProps}>
{children}
</Link>
);
};
// define our navigation config
// Note: do not define this in the body of a function component unless you give
// it a stable identity via useRef
const globalNavLinkAvatarConfig = {
linkAs: RoutableLink,
links: [
{ label: 'Home', url: '/home' },
{
label: 'John',
url: '/profile',
customContent: (
//@ts-expect-error fix later
<Avatar label={'Tara'} size={'xs'} avatarShape={'square'} hideLabel src={JohnImg} isButtonContent />
),
},
],
};
export const GlobalLinkAvatarExample: FC<{ logoContent?: React.ReactNode }> = ({ logoContent = defaultLogo }) => {
const mainRef = useRef<HTMLElement>(null);
useEffect(() => {
const url = window.location.href;
if (mainRef?.current && url.includes('#main')) {
mainRef.current.focus();
}
}, []);
return (
<>
<MemoryRouter>
<Header
logoContent={logoContent}
globalNavigation={globalNavLinkAvatarConfig}
useLocation={useCurrentRoute}
skipLink={{ id: 'main' }}
productName="Product name A"
productLink="#"
/>
<AppContent>
<CurrentRouteContainer />
<main tabIndex={-1} id="main" ref={mainRef}>
<Heading>Main content</Heading>
<Button onPress={() => alert('click')}>Focusable button</Button>
</main>
</AppContent>
</MemoryRouter>
</>
);
};
InlineNotification
The inline notification component provides users with important information or feedback within the context of their current task. It can display success, info, warning, and error messages without breaking the current workflow.
import { FC } from 'react';
import { InlineNotification } from '@uhg-harmony/react';
export const BasicExample: FC<{ className?: string }> = ({ className }) => (
<>
<InlineNotification className={className} variant="info" id={'notification-info'}>
Info Message Goes Here
</InlineNotification>
<InlineNotification className={className} variant="success" id={'notification-success'}>
Success Message Goes Here
</InlineNotification>
<InlineNotification className={className} variant="warning" id={'notification-warning'}>
Warning Message Goes Here
</InlineNotification>
<InlineNotification className={className} variant="error" id={'notification-error'}>
Error Message Goes Here
</InlineNotification>
</>
);
Pagination
Pagination component provides a way to navigate through a large set of data. It allows users to navigate through pages, change the number of items displayed per page, and jump to a specific page.
import { FC } from 'react';
import { IPaginationState, Pagination, PaginationProps } from '@uhg-harmony/react';
import styled from 'styled-components';
const ExampleContent = styled.div`
padding: 14px;
border: 1px solid #888b8d;
display: flex;
align-items: center;
justify-content: center;
height: 200px;
`;
export const paginationBasicConfig = {
pageSize: 10,
totalItemsCount: 100,
};
export const BasicExample: FC<PaginationProps> = ({ id, config }) => {
return (
<Pagination id={id} config={config}>
{({ page }: IPaginationState) => (
<ExampleContent>
<p>Page Content {page}</p>
</ExampleContent>
)}
</Pagination>
);
};
Select
The Select component is a customizable dropdown selector for user input. It provides a list of options, from which users can select one, enhancing the user interaction in form-based interfaces.
The caretIcon prop in the Select component is used to customize the dropdown indicator in the select box. You can pass a React element (typically an SVG icon) to this prop to replace the default caret icon. This allows for better visual integration of the Select component into your application's design system.
import { FC } from 'react';
import { FormControl, HelperText, Label, Select, SelectProps } from '@uhg-harmony/react';
export const BasicExample: FC<SelectProps> = ({ className, disabled }) => (
<FormControl id={'select'} disabled={disabled}>
<Label>Field label</Label>
<HelperText>Helper text</HelperText>
<Select data-testid={'test-select'} className={className}>
<option value="">Month…</option>
<option value="january">January</option>
<option value="february">February</option>
<option value="march">March</option>
<option value="april">April</option>
<option value="may">May</option>
<option value="june">June</option>
<option value="july">July</option>
<option value="august">August</option>
<option value="september">September</option>
<option value="october">October</option>
<option value="november">November</option>
<option value="december">December</option>
</Select>
</FormControl>
);
Table
a basic table
import { FC } from 'react';
import { Table, TableProps } from '@uhg-harmony/react';
export const config = {
columns: [
{ label: 'First name', key: 'firstName' },
{ label: 'Last name', key: 'lastName' },
{ label: 'Date', key: 'date' },
{ label: 'SSN', key: 'ssn' },
],
caption: {
headerText: 'Basic table',
},
};
export const data = [
{
id: '1',
firstName: 'Joe',
lastName: 'Blogs',
date: '1987-08-12',
ssn: 'SSN_000005',
},
{
id: '2',
firstName: 'Stephen',
lastName: 'Cruise',
date: '2000-05-23',
ssn: 'SSN_000002',
},
{
id: '3',
firstName: 'Daniel',
lastName: 'Henderson',
date: '1968-02-03',
ssn: 'SSN_000007',
},
{
id: '4',
firstName: 'Julia',
lastName: "O'Sullivan",
date: '2013-12-11',
ssn: 'SSN_000003',
},
{
id: '5',
firstName: 'Paul',
lastName: 'Murphy',
date: '1938-03-11',
ssn: 'SSN_000009',
},
{
id: '6',
firstName: 'Jimmy',
lastName: 'Newman',
date: '2016-01-22',
ssn: 'SSN_000004',
},
{
id: '7',
firstName: 'Siobhan',
lastName: 'Gibbons',
date: '1983-05-04',
ssn: 'SSN_000006',
},
{
id: '8',
firstName: 'Aoife',
lastName: 'McCann',
date: '1955-03-06',
ssn: 'SSN_000008',
},
];
export const BasicExample: FC<TableProps> = ({ className, data, config }) => {
return <Table data={data} config={config} className={className} />;
};
Related Assets
harmony-form-pattern
Build accessible healthcare forms using the Harmony Design System (@uhg-harmony/react). Provides component patterns, layout templates, and state management guidance for TextInput, DatePicker, Checkbox, Select, FormControl, and multi-step form flows. Use when creating React forms with Harmony components, fixing layout or accessibility issues, or scaffolding new healthcare intake forms.
Owner: pcorazao
harmony-modal-pattern
Skill for implementing a Harmony modal pattern using Harmony Modal components.
Owner: pcorazao
harmony-app-layout-pattern
Skill for implementing a responsive app layout pattern using Harmony components.
Owner: pcorazao
harmony-sdk-discovery
Discover and explore available Harmony components and APIs from installed packages
Owner: pcorazao
Optum Harmony Healthcare Demo App
Create a Harmony-based example healthcare application that showcases eligibility, claims, and remittance concepts using current Harmony skills, instructions, navigation, forms, and components.
Owner: harmony-platform
Harmony Overview
Overview of the Harmony Design System — Optum's unified React component library combining UITK and UICL for building scalable, brand-compliant, and accessible healthcare web applications.
Owner: pcorazao

