Katrina Liao
In February 2020 we released version 1.0.0 of DLS React, which is built off DLS version 6.
axp-base is on DLS version 5 while dls-react is on DLS version 6. dls-react has built in CSS obj styling with Emotion, but will still need a DLS stylesheet for global styling.
Use DLS version 6. If you cannot upgrade to version 6, use DLS Mini or <DefaultStyle /> from dls-react.
DLS Mini includes all the global element styling that will allow axp-base and dls-react components live together on the same page. <DefaultStyle /> is a helmet component that will peek at the stylesheet in the page head and inject DLS Mini if there is no version 6+ DLS stylesheet.
Replace the axp-base imports with @americanexpress/dls-react.
AccordionThe Accordion component from axp-base is named Collapsible in DLS React, which also has CollapsibleContent, CollapsibleHeading, and CollapsiblePanel sub-components.
axp-base uses a single component and props for the icon. dls-react icon is built in and handled by CollapsiblePanel.
Accordion to Collapsible and remove props.CollapsibleContent, CollapsibleHeading, or CollapsiblePanel components.label prop with labelledBy referencing the appropriate id.axp-base
/* eslint-disable semi */
<Accordion>
<Collapsible label="some label" privateKey="item1Key">
<p>Content 1</p>
</Collapsible>
<Collapsible label="some other label" privateKey="item2Key">
<p>Content 1</p>
</Collapsible>
</Accordion>;
DLS React
<Collapsible>
<CollapsiblePanel id="collapsible-p-h1" icon={<IconHotel />}>
Hotel
</CollapsiblePanel>
<CollapsibleContent labelledBy="collapsible-p-h1">
<p className="pad">Content 1</p>
</CollapsibleContent>
<CollapsiblePanel id="collapsible-p-h2" icon={<IconAirplane />}>
Air
</CollapsiblePanel>
<CollapsibleContent labelledBy="collapsible-p-h2">
<p className="pad">Content 2</p>
</CollapsibleContent>
<CollapsiblePanel id="collapsible-p-h3" icon={<IconCar />}>
Car
</CollapsiblePanel>
<CollapsibleContent labelledBy="collapsible-p-h3">
<p className="pad">Content 3</p>
</CollapsibleContent>
</Collapsible>;
AlertAlert component from axp-base is named PageLevelMessage in DLS React. The Alert component in DLS React is meant for use with form inputs.PageLevelMessage hides itself when the close button is clicked. Alert in axp-base requires manually hiding the component.Alert to PageLevelMessage.type prop. “positive” becomes “success” and “negative” becomes “failure”.icon prop unless you are using a custom icon.onClose prop.dismissible prop to false.closeTitle prop.onClose prop to onDismiss.axp-base
<Alert type="positive" label="Alert Message" icon="dls-icon-success-filled" onClose={closeHandler} />;
DLS React
<PageLevelMessage type="success" onDismiss={closeHandler}>
Alert Message
</PageLevelMessage>;
AmexLogoBlueBoxAmexLogoBlueBox component in axp-base uses the size of the containing div, while the DLS React Logo component takes an explicit size prop.Logo component does not support arbitrary colors.AmexLogoBlueBox to Logo.styleType prop to "bluebox-solid".size prop to the appropriate value for the design.axp-base
<div>
<AmexLogoBlueBox />
</div>;
DLS React
<Logo styleType="bluebox-solid" size="lg" />;
AmexLogoHorizontalAmexLogoHorizontal component in axp-base uses the size of the containing div, while the DLS React Logo component takes an explicit size prop.Logo component does not support arbitrary colors.AmexLogoHorizontal to Logo.styleType prop to “line”.size prop to the appropriate value for the design.axp-base
<div>
<AmexLogoHorizontal />
</div>;
DLS React
<Logo styleType="bluebox-solid" size="lg" />;
AnchorAnchor.label prop in axp-base is children in dls-react.Analytics(Anchor) component with name Anchor.label prop as children within the Anchor.axp-base
<Anchor label="Anchor Label" href="http://www.americanexpress.com" />;
DLS React
<Anchor href="http://www.americanexpress.com">Anchor Label</Anchor>;
Badgetheme prop rather than the type prop.type prop to the value for the desired badge style.theme prop if needed for coloring.axp-base
<Badge text="Success" type="success" />;
DLS React
<Badge type="text" theme={dlsColorWarningBg}>
Success
</Badge>;
axp-base
<Badge text="All" type="pill" />;
DLS React
<Badge type="outline">All</Badge>;
BarProgressSegmentedLinearTracker.SegmentedLinearTrackerStep, not props.SegmentedLinearTracker.SegmentedLinearTrackerStep components for each step and add them as children inside SegmentedLinearTracker.currentStep is the same logic handled by SegmentedLinearTracker.axp-base
<BarProgress
steps={[
'Step 1',
'Step 2',
'Step 3',
]}
currentStep={2}
/>;
DLS React
<SegmentedLinearTracker currentStep={2}>
<SegmentedLinearTrackerStep label="Step 1" />
<SegmentedLinearTrackerStep label="Step 2" />
<SegmentedLinearTrackerStep label="Step 3" />
</SegmentedLinearTracker>;
BreadcrumbsBreadcrumbTrail.crumbs prop.Breadcrumbs tag to BreadcrumbTrail.crumbs prop with Breadcrumb component children.axp-base
<Breadcrumbs
crumbs={[
{ content: 'Link 1', url: '#example1' },
{ content: 'Link 2', url: '#example2' },
{ content: 'Link 3' },
]}
/>;
DLS React
<BreadcrumbTrail>
<Breadcrumb href="#example1">Link 1</Breadcrumb>
<Breadcrumb href="#example2">Link 2</Breadcrumb>
<Breadcrumb>Link 3</Breadcrumb>
</BreadcrumbTrail>;
ButtonstyleType prop instead.label prop in DLS React so labels must be added as children.className prop with the appropriate styleType prop.label prop value inside the Button as a child.working prop to isLoading.axp-base
<Button className="btn-block margin-auto-lr btn-primary" working={true}>
Button text
</Button>;
DLS React
<Button styleType="primary" isLoading={true}>
Button text
</Button>;
axp-base
<Button className="btn-block margin-auto-lr btn-secondary" label="Button text" />;
DLS React
<Button styleType="secondary">Button text</Button>;
CheckboxonChange prop for Checkbox in axp-base receives a boolean value with the checked state. In DLS React, it receives the entire event, and the checked state is available as event.target.checked.onChange handlers for your checkbox to use the target.checked value from the event.axp-base:
toggle = (checked) => {
this.setState({ isChecked: checked });
};
DLS React:
toggle = (event) => {
this.setState({ isChecked: event.target.checked });
};
CollapsibleCollapsible component uses the id to connect the panel to the content it expands, while axp-base uses a parent-child relationship.Collapsible wrapper.label prop to a CollapsiblePanel component.CollapsibleContent component.id prop to the CollapsiblePanel and a matching labelledBy prop to the CollapsibleContent.axp-base:
<Collapsible label="Collapsible Header">
<div>Collapsible Content</div>
</Collapsible>;
DLS React:
<Collapsible>
<CollapsiblePanel id="collapsible-id">
Collapsible Header
</CollapsiblePanel>
<CollapsibleContent labelledBy="collapsible-id">
<div>Collapsible Content</div>
</CollapsibleContent>
</Collapsible>;
CurrencyInputdecimalDigits is showFractions in dls-react.Defaults are the same, so no major changes necessary
axp-base:
<CurrencyInput />;
DLS React:
<CurrencyInput />;
DropdownThe Dropdown component in axp-base is named Select in dls-react
The Select component in DLS React uses children for the options, while axp-base uses an options prop.
DLS React uses separate Label and Alert components, rather than props.
options prop with SelectOption children.label prop to a separate Label component before the Select.warning prop to a separate Alert component after the Select.warning to set the status prop on the Select to “default”, “error”, or “success”.onChange method to use a signature of (event) rather than (value, event). The value can be found at event.target.value.axp-base:
<Dropdown
label="Select a size"
id="size"
value={size}
options={[
{ value: '', id: '', label: 'Select' },
{ value: 'sm', id: 'sm', label: 'Small' },
{ value: 'md', id: 'md', label: 'Medium' },
{ value: 'lg', id: 'lg', label: 'Large' },
]}
onChange={(value, event) => setSize(value.value, event)}
warning={!valid && <span>Invalid size</span>}
/>;
DLS React:
<Fragment>
<Label htmlFor="size">
Select a size
</Label>
<Select
id="size"
value={size}
onChange={(event) => setSize(event.value.target, event)}
status={!valid ? 'error' : 'default'}
>
<SelectOption value="">Select</SelectOption>
<SelectOption value="sm">Small</SelectOption>
<SelectOption value="md">Medium</SelectOption>
<SelectOption value="lg">Large</SelectOption>
</Select>
{!valid && <Alert>Invalid size</Alert>}
</Fragment>;
FlagSelectorFlag supports multiple sizes using the size prop. The default size is "sm" and the axp-base component corresponds to “lg”.FlagSelector to Flag.size prop.axp-base
<FlagSelector countryCode="US" />;
DLS React
<Flag countryCode="US" size="lg" />;
IconIcon component with the appropriate specific icon component.axp-base
<Icon className="dls-icon-alert" />;
DLS React
<IconAlert />;
InputInput component in DLS React uses separate Label and Alert components, rather than props.label prop to a separate Label component before the Input.warning prop to a separate Alert component after the Input.warning to set the status prop on the Input and Label to “default”, “success”, or “error”.onChange method to use a signature of (event) rather than (value, event). The value can be found at event.target.value.
b. Rewrite the onBlur method to use a signature of (event) rather than (value, event).axp-base:
<Input
label="Input label"
id="example-input"
value={value}
onChange={(value) => setValue(value)}
onBlur={(value) => checkValidity(value)}
warning={!valid && <span>Invalid value</span>}
/>;
DLS React:
<Fragment>
<Label htmlFor="example-input">
Input label
</Label>
<Input
id="example-input"
value={value}
onChange={(event) => setValue(event.target.value)}
onBlur={(event) => checkValidity(event.target.value)}
status={!valid ? 'error' : 'default'}
/>
{!valid && <Alert>Invalid value</Alert>}
</Fragment>;
LoaderLoader in axp-base is named ProgressCircle in DLS React.Loader to ProgressCircle.axp-base:
if (isLoading()) {
return <Loader />;
}
return <Component />;
DLS React:
if (isLoading()) {
return <ProgressCircle />;
}
return <Component />;
ModalModal is shown or hidden using the shown prop. The DLS React Modal is shown or hidden like any other React component that is conditionally displayed.shown prop with logic to hide or show the modal.ModalHeader.ModalBody.ModalFooter.axp-base:
<Modal shown={isShown}>Modal content</Modal>;
DLS React:
isShown && <Modal>Modal content</Modal>;
axp-base:
<div className="modal-header dls-bright-blue-bg dls-white">
<h2 className="fluid text-align-center heading-3">Modal Title</h2>
<Button
id="closeModalButton"
onClick={this.hideModal}
className="btn-inline dls-glyph-close pad-0"
/>
</div>;
DLS React:
<ModalHeader onCloseClick={this.hideModal}>
<h2 className="fluid heading-3">Modal Title</h2>
</ModalHeader>;
RadioGroupRadio component in axp-base is named RadioButton in DLS React.onChange prop in axp-base receives the value directly. In DLS React, it receives the entire event, and the value is available as event.target.value.Radio to RadioButton.selectedValue prop to checked.onChange handlers to use the target.value from the event.axp-base
<RadioGroup selectedValue={value} onChange={setValue} name="test">
<Radio id="radio-1" label="Choice A" value="A" />
<Radio id="radio-2" label="Choice B" value="B" />
</RadioGroup>;
DLS React
<RadioGroup checked={value} onChange={(event) => setValue(event.target.value)}>
<Legend>Pick a choice:</Legend>
<RadioButton id="radio-3" label="Choice A" value="A" />
<RadioButton id="radio-4" label="Choice B" value="B" />
</RadioGroup>;
StepProgressMultiStepTracker in dls-react and has significant visual differences.MultiStepTracker.StepProgress toMultiStepTracker.Step components for each step as children within MultiStepTracker.axp-base:
<StepProgress
steps={[
'Step 1',
'Step 2',
'Step 3',
]}
currentStep={2}
/>;
DLS React:
<MultiStepTracker currentStep={2}>
<Step label="Step 1" />
<Step label="Step 2" />
<Step label="Step 3" />
</MultiStepTracker>;
Tabsid in DLS React and by numeric index in axp-base.Tabs is now TabGroupTabList is now TabMenuTabPanels is now TabContentGroupTabPanel is now TabContentid prop to every Tab.TabContent component as the labelledBy prop.mobileLabel props.className="fluid" if present.TabGroup onSelect prop to onChange.TabGroup selectedIndex prop to selectedTab.axp-base:
<Tabs onSelect={(selectedIndex) => selectTab(selectedIndex)} selectedIndex={selectedIndex}>
<TabList>
<Tab>Tab 1</Tab>
<Tab>Tab 2</Tab>
</TabList>
<TabPanels>
<TabPanel>Tab 1 content</TabPanel>
<TabPanel>Tab 2 content</TabPanel>
</TabPanels>
</Tabs>;
DLS React:
<TabGroup onChange={(event, id) => selectTab(id)} selectedTab={selectedTab}>
<TabMenu>
<Tab id="tab-1">Tab 1</Tab>
<Tab id="tab-2">Tab 2</Tab>
</TabMenu>
<TabContentGroup>
<TabContent labelledBy="tab-1"> Tab 1 content</TabContent>
<TabContent labelledBy="tab-2"> Tab 2 content</TabContent>
</TabContentGroup>
</TabGroup>;
TextAreaTextarea component in DLS React uses separate Label and Alert components, rather than props.TextArea to Textarealabel prop to a separate Label component before the Textarea.warning prop to a separate Alert component after the Textarea.warning to set the status prop on the Textarea and Label to “default”, “error”, or “success”.axp-base:
<TextArea
label="Text area label"
id="example-textarea"
value={value}
warning={!valid && <span>Invalid value</span>}
/>;
DLS React:
<Fragment>
<Label htmlFor="example-textarea" valid={valid}>
Text area label
</Label>
<Textarea id="example-textarea" value={value} valid={valid} />
{!valid && <Alert>Invalid value</Alert>}
</Fragment>;
TooltipTooltip component in dls-react uses separate Tooltip and TooltipButton components.tooltipBox or toggleBox positioning since it is handled out of the box in dls-react.Analytics(Tooltip) to Tooltipposition prop to placement.triggerElement.className="tooltip-content" since it’s already styled by dls-react.axp-base:
<AnalyticsTooltip
className="test-class"
label="tooltip label"
position="bottom"
contentId="myTooltipContent"
tooltipBox={{
left: 10,
right: 190,
bottom: 90,
}}
toggleBox={{
left: 150,
right: 170,
bottom: 20,
}}
>
<span className="tooltip-content">
Charles Frost
</span>
</AnalyticsTooltip>;
DLS React:
<Tooltip
id="tooltip-info-top"
triggerElement={(
<TooltipButton info={true} active={true} icon={<GlyphInfo />} />
)}
placement="top"
info={true}
open={true}
>
Charles Frost
</Tooltip>;
If you have any more questions about the migration or on DLS in general, please ask in the dls-tech channel in Slack.
Connect with the DLS Team on Slack or by email.
Check out additional resources.
