Migration guide

axp-base to dls-react Migration Guide

Katrina Liao

  • February 26, 2020
  • 14 min read

Summary

In February 2020 we released version 1.0.0 of DLS React, which is built off DLS version 6.

Dependencies

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.

Imports

Replace the axp-base imports with @americanexpress/dls-react.

Accordion

Major Differences

  • The 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.

Migration Recipe

  1. Rename Accordion to Collapsible and remove props.
  2. Replace Accordion contents with CollapsibleContent, CollapsibleHeading, or CollapsiblePanel components.
  3. Replace the label prop with labelledBy referencing the appropriate id.

Examples

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>;

Alert

Major Differences

  • The Alert 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.

Migration Recipe

  1. Rename Alert to PageLevelMessage.
  2. Change the type prop. “positive” becomes “success” and “negative” becomes “failure”.
  3. Remove the icon prop unless you are using a custom icon.
  4. Remove any show/hide logic tied to the onClose prop.
  5. If you do not want a close button, set the dismissible prop to false.
  6. Remove the closeTitle prop.
  7. Rename the onClose prop to onDismiss.

Examples

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>;

AmexLogoBlueBox

Major Differences
  • The AmexLogoBlueBox component in axp-base uses the size of the containing div, while the DLS React Logo component takes an explicit size prop.
  • The DLS React Logo component does not support arbitrary colors.
Migration Recipe
  1. Rename AmexLogoBlueBox to Logo.
  2. Set the styleType prop to "bluebox-solid".
  3. Set the size prop to the appropriate value for the design.

Examples

axp-base

<div>

<AmexLogoBlueBox />

</div>;

DLS React

<Logo styleType="bluebox-solid" size="lg" />;

AmexLogoHorizontal

Major Differences

  • The DLS React horizontal logo uses the current branding.
  • The AmexLogoHorizontal component in axp-base uses the size of the containing div, while the DLS React Logo component takes an explicit size prop.
  • The DLS React Logo component does not support arbitrary colors.

Migration Recipe

  1. Rename AmexLogoHorizontal to Logo.
  2. Set the styleType prop to “line”.
  3. Set the size prop to the appropriate value for the design.

Examples

axp-base

<div>

<AmexLogoHorizontal />

</div>;

DLS React

<Logo styleType="bluebox-solid" size="lg" />;

Anchor

Major Differences

  • The DLS React Anchor component is named Anchor.
  • The label prop in axp-base is children in dls-react.

Migration Recipe

  1. Replace the Analytics(Anchor) component with name Anchor.
  2. Rewrite the label prop as children within the Anchor.

Examples

axp-base

<Anchor label="Anchor Label" href="http://www.americanexpress.com" />;

DLS React

<Anchor href="http://www.americanexpress.com">Anchor Label</Anchor>;

Badge

Major Differences

  • The DLS React badge color is set by the theme prop rather than the type prop.
  • There is no DLS React equivalent of the parsed badge.

Migration Recipe

  1. Convert the type prop to the value for the desired badge style.
  2. Add a theme prop if needed for coloring.
  3. Add a function if needed to parse the text for a badge.

Examples

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>;

BarProgress

Major Differences

  • The component in dls-react is named SegmentedLinearTracker.
  • The steps are children components called SegmentedLinearTrackerStep, not props.

Migration Recipe

  1. Rename the component to SegmentedLinearTracker.
  2. Create SegmentedLinearTrackerStep components for each step and add them as children inside SegmentedLinearTracker.
  3. currentStep is the same logic handled by SegmentedLinearTracker.

Examples

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>;

Breadcrumbs

Major Differences

  • The DLS React component is named BreadcrumbTrail.
  • DLS React uses child components for the breadcrumb trail, rather than a crumbs prop.

Migration Recipe

  1. Rename the Breadcrumbs tag to BreadcrumbTrail.
  2. Replace the crumbs prop with Breadcrumb component children.

Examples

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>;

Button

Major Differences

  • axp-base uses classes to style buttons. DLS React uses the styleType prop instead.
  • There is no label prop in DLS React so labels must be added as children.

Migration Recipe

  1. Replace the className prop with the appropriate styleType prop.
  2. Move the label prop value inside the Button as a child.
  3. Rename the working prop to isLoading.

Examples

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>;

Checkbox

Major Differences

  • The onChange 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.

Migration Recipe

  1. Rewrite any onChange handlers for your checkbox to use the target.checked value from the event.

Examples

axp-base:

toggle = (checked) => {

this.setState({ isChecked: checked });

};

DLS React:

toggle = (event) => {

this.setState({ isChecked: event.target.checked });

};

Collapsible

Major Differences

  • The DLS React Collapsible component uses the id to connect the panel to the content it expands, while axp-base uses a parent-child relationship.
  • The panel and content are separate components within the Collapsible wrapper.

Migration Recipe

  1. Convert the label prop to a CollapsiblePanel component.
  2. Wrap the collapsible content in a CollapsibleContent component.
  3. Add an id prop to the CollapsiblePanel and a matching labelledBy prop to the CollapsibleContent.

Examples

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>;

CurrencyInput

Major Differences

  • axp-base prop decimalDigits is showFractions in dls-react.

Migration Recipe

Defaults are the same, so no major changes necessary

Examples

axp-base:

<CurrencyInput />;

DLS React:

<CurrencyInput />;

Dropdown

Major Differences

  • The 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.

Migration Recipe

  1. Replace the options prop with SelectOption children.
  2. Move the label prop to a separate Label component before the Select.
  3. Move the warning prop to a separate Alert component after the Select.
  4. Update the logic that was used for warning to set the status prop on the Select to “default”, “error”, or “success”.
  5. If it’s a controlled dropdown: a. Rewrite the onChange method to use a signature of (event) rather than (value, event). The value can be found at event.target.value.

Examples

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>;

FlagSelector

Major Differences

  • The DLS React Flag supports multiple sizes using the size prop. The default size is "sm" and the axp-base component corresponds to “lg”.

Migration Recipe

  1. Rename FlagSelector to Flag.
  2. Add the appropriate size prop.

Examples

axp-base

<FlagSelector countryCode="US" />;

DLS React

<Flag countryCode="US" size="lg" />;

Icon

Major Differences

  • DLS React has separate components for each DLS icon, while axp-base uses CSS classes to specify the icon.
  • DLS React uses SVG elements for icons, while axp-base uses a custom icon font.

Migration Recipe

  1. Replace the generic Icon component with the appropriate specific icon component.

Examples

axp-base

<Icon className="dls-icon-alert" />;

DLS React

<IconAlert />;

Input

Major Differences

  • The Input component in DLS React uses separate Label and Alert components, rather than props.

Migration Recipe

  1. Move the label prop to a separate Label component before the Input.
  2. Move the warning prop to a separate Alert component after the Input.
  3. Update the logic that was used for warning to set the status prop on the Input and Label to “default”, “success”, or “error”.
  4. If it’s a controlled input: a. Rewrite the 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).

Examples

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>;

Loader

Major Differences

  • The default circle Loader in axp-base is named ProgressCircle in DLS React.

Migration Recipe

  1. Rename Loader to ProgressCircle.

Examples

axp-base:

if (isLoading()) {

return <Loader />;

}

return <Component />;

DLS React:

if (isLoading()) {

return <ProgressCircle />;

}

return <Component />;

Modal

Major Differences

  • The axp-base Modal 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.
  • DLS React also contains helper components to make it easier to style modals according to the DLS.

Migration Recipe

  1. Replace the shown prop with logic to hide or show the modal.
  2. Replace the title bar JSX with ModalHeader.
  3. Replace the body JSX with ModalBody.
  4. Replace the footer JSX with ModalFooter.

Examples

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>;

RadioGroup

Major Differences

  • The Radio component in axp-base is named RadioButton in DLS React.
  • The 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.

Migration Recipe

  1. Rename Radio to RadioButton.
  2. Rename the selectedValue prop to checked.
  3. Rewrite any onChange handlers to use the target.value from the event.

Examples

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>;

StepProgress

Major Differences

  • The component is named MultiStepTracker in dls-react and has significant visual differences.
  • Instead of steps props, dls-react has Step components as children within MultiStepTracker.

Migration Recipe

  1. RenameStepProgress toMultiStepTracker.
  2. Remove the steps props and create Step components for each step as children within MultiStepTracker.

Examples

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>;

Tabs

Major Differences

  • The tab sub-components have different names in DLS React.
  • The selected tabs are tracked by id in DLS React and by numeric index in axp-base.

Migration Recipe

  1. Rename the components:
  • Tabs is now TabGroup
  • TabList is now TabMenu
  • TabPanels is now TabContentGroup
  • TabPanel is now TabContent
  1. Add an id prop to every Tab.
  2. Add that id to the corresponding TabContent component as the labelledBy prop.
  3. Remove any mobileLabel props.
  4. Remove className="fluid" if present.
  5. If it’s a controlled set of tabs:
  6. Rename the TabGroup onSelect prop to onChange.
  7. Rename the TabGroup selectedIndex prop to selectedTab.
  8. Rewrite your change handler. Instead of getting an index passed to your function, you will get the event and the tab id.

Examples

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>;

TextArea

Major Differences

  • The Textarea component in DLS React uses separate Label and Alert components, rather than props.

Migration Recipe

  1. Rename TextArea to Textarea
  2. Move the label prop to a separate Label component before the Textarea.
  3. Move the warning prop to a separate Alert component after the Textarea.
  4. Update the logic that was used for warning to set the status prop on the Textarea and Label to “default”, “error”, or “success”.

Examples

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>;

Tooltip

Major Differences

  • The Tooltip component in dls-react uses separate Tooltip and TooltipButton components.
  • There is no need to define tooltipBox or toggleBox positioning since it is handled out of the box in dls-react.

Migration Recipe

  1. Rename Analytics(Tooltip) to Tooltip
  2. Rename the position prop to placement.
  3. Add a triggerElement.
  4. Remove className="tooltip-content" since it’s already styled by dls-react.

Examples

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>;

References

axp-base repo

axp-base docs

dls-react repo

dls-react docs

If you have any more questions about the migration or on DLS in general, please ask in the dls-tech channel in Slack.

Questions?

Connect with the DLS Team on Slack or by email.

Resources

Check out additional resources.