This is the early access documentation preview for Custom Views. This documentation might not be in sync with our official documentation.

@/application-components

Generic components for building Merchant Center applications.

Installation

yarn add @commercetools-frontend/application-components
# or
npm --save install @commercetools-frontend/application-components

Additionally install the peer dependencies (if not present)

yarn add react react-dom react-intl
# or
npm --save install react react-dom react-intl

Page components

Custom Applications typically consist of a variety of pages with different hierarchical levels. For example, a page to show a list of products, followed by a detail page to see the product's details.

Moreover, pages with similar hierarchical levels might need to fulfill different requirements. For example a detail page with or without a form, or a page with tabs.

We provide several components that cover the most common use cases. We recommend using them wherever possible to ensure visual consistency and reduce development efforts.

We identified 3 groups of components:

  • Info
  • Form / CustomForm
  • Tabular

Additionally, we identified 4 hierarchical levels:

  • Main
  • Detail
  • Modal
  • Dialog

Components for main pages

The following page components should be used in the landing pages of the Custom Application that don't have a parent page in the hierarchy. For example, for a Custom Application for products, the main page can show a list of products.

InfoMainPage

Info Main pages are controlled components used to render a page to show more information about a particular feature. Similar to <InfoModalPage> but not rendered as a modal.

Usage

import { InfoMainPage } from '@commercetools-frontend/application-components';
import Text from '@commercetools-uikit/text';
const MainPage = () => {
return (
<InfoMainPage title="Main page">
<Text.Body>{'Lorem ipsum ...'}</Text.Body>
</InfoMainPage>
);
};

Properties

PropsTypeRequiredDefaultDescription
titlestring--The title of the page.
subtitlenode or string--The subtitle of the page, usually a React component. If a string is passed, it's rendered as a paragraph.
customTitleRownode--Pass a React.node to be used in place of the title and subtitle.
childrennode-Content rendered within the page. It's expected to have its style fully customized.

Static properties

  • Page Header title

    Pre-configured page header title component to use as part of a custom title row.

    InfoMainPage.PageHeaderTitle = PageHeaderTitle;

FormMainPage

Form Main pages are controlled components used to render a page with a form or something that requires user input. Similar to <FormModalPage> but not rendered as a modal. The header includes buttons to control the submission or cancellation of the form.

If you need to customize these buttons, you will need to use the <CustomFormMainPage> component instead.

Usage

import { useFormik } from 'formik';
import TextField from '@commercetools-uikit/text-field';
import TextInput from '@commercetools-uikit/text-input';
import { FormMainPage } from '@commercetools-frontend/application-components';
const MainPage = () => {
const formik = useFormik({
initialValues: {
email: '',
},
validate: (formikValues) => {
if (TextInput.isEmpty(formikValues.email)) {
return { email: { missing: true } };
}
return {};
},
onSubmit: async (formikValues) => {
alert(`email: ${formikValues.email}`);
// Do something async
},
});
return (
<FormMainPage
title="Manage your account"
isPrimaryButtonDisabled={formik.isSubmitting}
onSecondaryButtonClick={formik.handleReset}
onPrimaryButtonClick={formik.handleSubmit}
>
<TextField
name="email"
title="Email"
isRequired={true}
value={formik.values.email}
errors={formik.errors.email}
touched={formik.touched.email}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
/>
</FormMainPage>
);
};

Properties

PropsTypeRequiredDefaultDescription
titlestring--The title of the page.
subtitlenode or string--The subtitle of the page, usually a React component. If a string is passed, it's rendered as a paragraph.
customTitleRownode--Pass a React.node to be used in place of the title and subtitle.
childrennode-Content rendered within the page. It's expected to have its style fully customized.
labelSecondaryButtonstring or Intl messageCancelThe label for the secondary button as a string, or as an Intl message ({ id, defaultMessage }).
iconLeftSecondaryButtonnodeThe icon for the secondary button label.
labelPrimaryButtonstring or Intl messageSaveThe label for the primary button as a string, or as an Intl message ({ id, defaultMessage }).
onPrimaryButtonClickfunction-Called when the primary button is clicked.
onSecondaryButtonClickfunction-Called when the secondary button is clicked.
isPrimaryButtonDisabledboolean-falseIndicates whether the primary button is deactivated or not.
isSecondaryButtonDisabledboolean-falseIndicates whether the secondary button is deactivated or not.
dataAttributesSecondaryButtonobject--Use this prop to pass data- attributes to the secondary button.
dataAttributesPrimaryButtonobject--Use this prop to pass data- attributes to the primary button.
hideControlsboolean-falseHides the form controls.

Static properties

  • Page Header title

    Pre-configured page header title component to use as part of a custom title row.

    FormMainPage.PageHeaderTitle = PageHeaderTitle;
  • FormMainPage.Intl

    This is a convenience proxy export to expose pre-defined Intl messages defined in the @commercetools-frontend/i18n package. The Intl messages can, for instance, be used for button labels.

CustomFormMainPage

Custom Form Main page is a variation of the <FormMainPage> that allows passing custom control elements via formControls. This is useful in case the main page needs different control elements than the default ones (primary and secondary buttons).

Usage

import { useFormik } from 'formik';
import TextField from '@commercetools-uikit/text-field';
import TextInput from '@commercetools-uikit/text-input';
import { CustomFormMainPage } from '@commercetools-frontend/application-components';
const AccountPage = () => {
const formik = useFormik({
initialValues: {
email: '',
},
validate: (formikValues) => {
if (TextInput.isEmpty(formikValues.email)) {
return { email: { missing: true } };
}
return {};
},
onSubmit: async (formikValues) => {
alert(`email: ${formikValues.email}`);
// Do something async
},
});
return (
<CustomFormMainPage
title="Manage your account"
formControls={
<>
<CustomFormMainPage.FormSecondaryButton
onClick={formik.handleReset}
/>
<CustomFormMainPage.FormPrimaryButton onClick={formik.handleSubmit} />
<CustomFormMainPage.FormDeleteButton onClick={handleDelete} />
</>
}
>
<TextField
name="email"
title="Email"
isRequired={true}
value={formik.values.email}
errors={formik.errors.email}
touched={formik.touched.email}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
/>
</CustomFormMainPage>
);
};

Properties

PropsTypeRequiredDefaultDescription
titlestring--The title of the page.
subtitlenode or string--The subtitle of the page, usually a React component. If a string is passed, it's rendered as a paragraph.
customTitleRownode--Pass a React.node to be used in place of the title and subtitle.
childrennode-Content rendered within the page. It's expected to have its style fully customized.
formControlsnode--Pass a React.node with form controls. You can use the pre-made form buttons exposed by this component or you can use your own.
hideControlsboolean-falseHides the form controls.

Static properties

  • Form Control Buttons

    Pre-configured form control buttons to reuse in custom controls.

    CustomFormMainPage.FormPrimaryButton = FormPrimaryButton;
    CustomFormMainPage.FormSecondaryButton = FormSecondaryButton;
    CustomFormMainPage.FormDeleteButton = FormDeleteButton;
  • Page Header title

    Pre-configured page header title component to use as part of a custom title row.

    CustomFormMainPage.PageHeaderTitle = PageHeaderTitle;
  • CustomFormMainPage.Intl

    This is a convenience proxy export to expose pre-defined Intl messages defined in the @commercetools-frontend/i18n package. The Intl messages can for instance be used for button labels.

TabularMainPage

Tabular Main pages are controlled components used to render a page with navigational controls and route-driven content using Tabs. The layout is similar to TabularModalPage but is not rendered as a modal.

Tabs must be rendered using the <TabHeader> component via the tabControls prop. A <TabHeader> is rendered as a link and it assumes the "tab content" is controlled and rendered using <Route> components.

The <TabularMainPage> is supposed to be used in one of the main application landing pages, as the top-level component page. The page should have no parent pages in the hierarchy. The layout of this page can be recognized by the white background header and the gray content background.

Usage

import { Switch, Route, useRouteMatch } from 'react-router-dom';
import {
TabularMainPage,
TabHeader,
} from '@commercetools-frontend/application-components';
const MainPage = () => {
const match = useRouteMatch();
return (
<TabularMainPage
title="Main page"
tabControls={
<>
<TabHeader to={`${match.url}/tab-one`} label="Tab One" />
<TabHeader to={`${match.url}/tab-two`} label="Tab Two" />
</>
}
>
<Switch>
<Route path={`${match.path}/tab-one`}>
<Tab1 />
</Route>
<Route path={`${match.path}/tab-two`}>
<Tab2 />
</Route>
</Switch>
</TabularMainPage>
);
};

Properties

PropsTypeRequiredDefaultDescription
titlestring--The title of the page.
subtitlenode or string--The subtitle of the page, usually a React component. If a string is passed, it's rendered as a paragraph.
customTitleRownode--Pass a React.node to be used in place of the title and subtitle.
childrennode-Content rendered within the page. It's expected to have its style fully customized.
tabControlsnode-Pass a React.node to be used as the Tabs component for controlling the navigation between the Tab contents within the page.
formControlsnode--Pass a React.node with form controls. You can use the pre-made form buttons exposed by this component or you can use your own.
hideControlsbool-falseHides the form controls.

Static properties

  • Form Control Buttons

    Pre-configured form control buttons to easily re-use them in the custom controls.

    TabularMainPage.FormPrimaryButton = FormPrimaryButton;
    TabularMainPage.FormSecondaryButton = FormSecondaryButton;
    TabularMainPage.FormDeleteButton = FormDeleteButton;
  • Page Header title

    Pre-configured page header title component to use as part of a custom title row.

    TabularMainPage.PageHeaderTitle = PageHeaderTitle;
  • TabularMainPage.Intl

    This is a convenience proxy export to expose pre-defined Intl messages defined in the @commercetools-frontend/i18n package. The Intl messages can, for instance, be used for button labels.

Components for detail pages

The following page components should be used in the pages of the Custom Application that show data of a specific resource. Hierarchically, the parent page should be the main page. For example, for a Custom Application for products, the detail page shows the product's data.

InfoDetailPage

Info Detail pages are controlled components used to render a page to show more information about a particular feature. Similar to <InfoModalPage> but not rendered as a modal.

The <InfoDetailPage> may be used as a direct child of one of the main pages. A back link in the header section is also required. The layout of this page can be recognized by the gray background header and the white content background.

Usage

import { useHistory } from 'react-router-dom';
import { InfoDetailPage } from '@commercetools-frontend/application-components';
import Text from '@commercetools-uikit/text';
const DetailPage = () => {
const history = useHistory();
return (
<InfoDetailPage
title="Detail page"
onPreviousPathClick={() => history.push('/starting-page')}
previousPathLabel="Go back"
>
<Text.Body>{'Lorem ipsum ...'}</Text.Body>
</InfoDetailPage>
);
};

Properties

PropsTypeRequiredDefaultDescription
titlestring--The title of the page.
subtitlenode or string--The subtitle of the page, usually a React component. If a string is passed, it's rendered as a paragraph.
customTitleRownode--Pass a React.node to be used in place of the title and subtitle.
childrennode-Content rendered within the page. It's expected to have its style fully customized.
previousPathLabelstring or Intl message-"Go back" (translated)Label to appear as the previous path of the top bar of the page.
onPreviousPathClickfunction-Called when the back button is clicked.

Static properties

  • Page Header title

    Pre-configured page header title component to use as part of a custom title row.

    InfoDetailPage.PageHeaderTitle = PageHeaderTitle;

FormDetailPage

Form Detail pages are controlled components used to render a page with a form or something that requires user input. Similar to <FormModalPage> but not rendered as a modal. The header includes buttons to control the submission or cancellation of the form. These buttons can be overwritten with custom controls by using the <CustomFormDetailPage> component.

The <FormDetailPage> may be used as a direct child of one of the main pages. A back link in the header section is also required. The layout of this page can be recognized by the gray background header and the white content background.

Usage

import { useHistory } from 'react-router-dom';
import { useFormik } from 'formik';
import TextField from '@commercetools-uikit/text-field';
import TextInput from '@commercetools-uikit/text-input';
import { FormDetailPage } from '@commercetools-frontend/application-components';
const AccountPage = () => {
const history = useHistory();
const formik = useFormik({
initialValues: {
email: '',
},
validate: (formikValues) => {
if (TextInput.isEmpty(formikValues.email)) {
return { email: { missing: true } };
}
return {};
},
onSubmit: async (formikValues) => {
alert(`email: ${formikValues.email}`);
// Do something async
},
});
return (
<FormDetailPage
title="Manage your account"
onPreviousPathClick={() => history.push('/starting-page')}
isPrimaryButtonDisabled={formik.isSubmitting}
onSecondaryButtonClick={formik.handleReset}
onPrimaryButtonClick={formik.handleSubmit}
>
<TextField
name="email"
title="Email"
isRequired={true}
value={formik.values.email}
errors={formik.errors.email}
touched={formik.touched.email}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
/>
</FormDetailPage>
);
};

Properties

PropsTypeRequiredDefaultDescription
titlestring--The title of the page.
subtitlenode or string--The subtitle of the page, usually a React component. If a string is passed, it's rendered as a paragraph.
customTitleRownode--Pass a React.node to be used in place of the title and subtitle.
childrennode-Content rendered within the page. It's expected to have its style fully customized.
previousPathLabelstring or Intl message-"Go back" (translated)Label to appear as the previous path of the top bar of the page.
onPreviousPathClickfunction-Called when the back button is clicked.
labelSecondaryButtonstring or Intl messageCancelThe label for the secondary button as a string, or as an Intl message ({ id, defaultMessage }).
labelPrimaryButtonstring or Intl messageSaveThe label for the primary button as a string, or as an Intl message ({ id, defaultMessage }).
onPrimaryButtonClickfunction-Called when the primary button is clicked.
onSecondaryButtonClickfunction-Called when the secondary button is clicked.
iconLeftSecondaryButtonnode--The icon for the secondary button label.
isPrimaryButtonDisabledboolean-falseIndicates whether the primary button is deactivated or not.
isSecondaryButtonDisabledboolean-falseIndicates whether the secondary button is deactivated or not.
dataAttributesSecondaryButtonobject--Use this prop to pass data- attributes to the secondary button.
dataAttributesPrimaryButtonobject--Use this prop to pass data- attributes to the primary button.
hideControlsboolean-falseHides the form controls.

Static properties

  • Page Header title

    Pre-configured page header title component to use as part of a custom title row.

    FormDetailPage.PageHeaderTitle = PageHeaderTitle;
  • FormDetailPage.Intl

    This is a convenience proxy export to expose pre-defined Intl messages defined in the @commercetools-frontend/i18n package. The Intl messages can be used for button labels.

    <FormDetailPage
    // other props...
    labelSecondaryButton={FormDetailPage.Intl.revert}
    />

CustomFormDetailPage

Custom Form Detail pages are a variation of the <FormDetailPage> that allow passing custom control elements via formControls. This is useful in case the detail page needs different control elements than the default ones (primary and secondary button).

The <CustomFormDetailPage> may be used as a direct child of one of the main pages. A back link in the header section is also required. The layout of this page can be recognized by the gray background header and the white content background.

Usage

import { useHistory } from 'react-router-dom';
import { useFormik } from 'formik';
import TextField from '@commercetools-uikit/text-field';
import TextInput from '@commercetools-uikit/text-input';
import { CustomFormDetailPage } from '@commercetools-frontend/application-components';
const AccountPage = () => {
const history = useHistory();
const formik = useFormik({
initialValues: {
email: '',
},
validate: (formikValues) => {
if (TextInput.isEmpty(formikValues.email)) {
return { email: { missing: true } };
}
return {};
},
onSubmit: async (formikValues) => {
alert(`email: ${formikValues.email}`);
// Do something async
},
});
return (
<CustomFormDetailPage
title="Manage your account"
onPreviousPathClick={() => history.push('/starting-page')}
formControls={
<>
<CustomFormDetailPage.FormSecondaryButton
onClick={formik.handleReset}
/>
<CustomFormDetailPage.FormPrimaryButton
onClick={formik.handleSubmit}
/>
<CustomFormDetailPage.FormDeleteButton onClick={handleDelete} />
</>
}
>
<TextField
name="email"
title="Email"
isRequired={true}
value={formik.values.email}
errors={formik.errors.email}
touched={formik.touched.email}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
/>
</CustomFormDetailPage>
);
};

Properties

PropsTypeRequiredDefaultDescription
titlestring--The title of the page.
subtitlenode or string--The subtitle of the page, usually a React component. If a string is passed, it's rendered as a paragraph.
customTitleRownode--Pass a React.node to be used in place of the title and subtitle.
childrennode-Content rendered within the page. It's expected to have its style fully customized.
previousPathLabelstring or Intl message-"Go back" (translated)Label to appear as the previous path of the top bar of the page.
onPreviousPathClickfunction-Called when the back button is clicked.
formControlsnode--Pass a React.node with form controls. You can use the pre-made form buttons exposed by this component or you can use your own.
hideControlsboolean-falseHides the form controls.

Static properties

  • Form Control Buttons

    Pre-configured form control buttons to easily re-use them in the custom controls.

    CustomFormDetailPage.FormPrimaryButton = FormPrimaryButton;
    CustomFormDetailPage.FormSecondaryButton = FormSecondaryButton;
    CustomFormDetailPage.FormDeleteButton = FormDeleteButton;
  • Page Header title

    Pre-configured page header title component to use as part of a custom title row.

    CustomFormDetailPage.PageHeaderTitle = PageHeaderTitle;
  • CustomFormModalPage.Intl

    This is a convenience proxy export to expose pre-defined Intl messages defined in the @commercetools-frontend/i18n package. The Intl messages can be used for button labels.

    <CustomFormDetailPage
    // other props...
    formControls={
    <CustomFormDetailPage.FormSecondaryButton
    // other props...
    label={CustomFormDetailPage.Intl.revert}
    />
    }
    />

TabularDetailPage

Tabular Detail pages are controlled components used to render a page with navigational controls and route-driven content using Tabs. The layout is similar to TabularModalPage but is not rendered as a modal.

Tabs must be rendered using the <TabHeader> component via the tabControls prop. A <TabHeader> is rendered as a link and it assumes the "tab content" is controlled and rendered using <Route> components.

The <TabularDetailPage> should be used as a direct child of one of the main pages. Typically it's used as a detail page with multiple sub-pages (tabs). The layout of this page can be recognized by the gray background header and the white content background. A backlink in the header section is also required.

Usage

import { Switch, Route, useRouteMatch, useHistory } from 'react-router-dom';
import {
TabularDetailPage,
TabHeader,
} from '@commercetools-frontend/application-components';
const DetailPage = () => {
const match = useRouteMatch();
const history = useHistory();
return (
<TabularDetailPage
title="Detail page"
onPreviousPathClick={() => history.push('/starting-page')}
previousPathLabel="Go back"
tabControls={
<>
<TabHeader to={`${match.url}/tab-one`} label="Tab One" />
<TabHeader to={`${match.url}/tab-two`} label="Tab Two" />
</>
}
>
<Switch>
<Route path={`${match.path}/tab-one`}>
<Tab1 />
</Route>
<Route path={`${match.path}/tab-two`}>
<Tab2 />
</Route>
</Switch>
</TabularDetailPage>
);
};

Properties

PropsTypeRequiredDefaultDescription
titlestring--The title of the page.
subtitlenode or string--The subtitle of the page, usually a React component. If a string is passed, it's rendered as a paragraph.
customTitleRownode--Pass a React.node to be used in place of the title and subtitle.
childrennode-Content rendered within the page. It's expected to have its style fully customized.
tabControlsnode-Pass a React.node to be used as the Tabs component for controlling the navigation between the Tab contents within the page.
formControlsnode--Pass a React.node with form controls. You can use the pre-made form buttons exposed by this component or you can use your own.
hideControlsbool-falseHides the form controls.
previousPathLabelstring or Intl message-"Go back" (translated)Label to appear as the previous path of the top bar of the page.
onPreviousPathClickfunction-Called when the back button is clicked.

Static properties

  • Form Control Buttons

    Pre-configured form control buttons to easily re-use them in the custom controls.

    TabularDetailPage.FormPrimaryButton = FormPrimaryButton;
    TabularDetailPage.FormSecondaryButton = FormSecondaryButton;
    TabularDetailPage.FormDeleteButton = FormDeleteButton;
  • Page Header title

    Pre-configured page header title component to use as part of a custom title row.

    TabularDetailPage.PageHeaderTitle = PageHeaderTitle;
  • TabularDetailPage.Intl

    This is a convenience proxy export to expose pre-defined Intl messages defined in the @commercetools-frontend/i18n package. The Intl messages can for instance be used for button labels.

Components for modal pages

The following page components should be used in nested pages of the Custom Application. Hierarchically, the parent page should be the detail page. For example, for a Custom Application for products, the modal page shows the product's variants data.

InfoModalPage

Info Modal pages are controlled components used to render a page using a modal container, which makes it appear on top of the normal page. This is useful to render detailed data that typically requires some space.

Usage

import {
InfoModalPage,
useModalState,
} from '@commercetools-frontend/application-components';
const Example = () => {
const pageModalState = useModalState();
return (
<InfoModalPage
title="Lorem ipsum"
isOpen={pageModalState.isModalOpen}
onClose={pageModalState.closeModal}
subtitle={<Text.Body>{'Lorem ipsum ...'}</Text.Body>}
topBarCurrentPathLabel="Lorem ipsum"
topBarPreviousPathLabel="Back"
>
<Text.Body>{'Lorem ipsum ...'}</Text.Body>
</InfoModalPage>
);
};

Properties

PropsTypeRequiredDefaultDescription
isOpenboolean-Indicates whether the page is open or closed. The parent component needs to manage this state.
titlestring-The title of the page.
subtitlenode or string--The subtitle of the page, usually a React component. If a string is passed, it's rendered as a paragraph.
onClosefunction--Called when the page closes: click in overlay, click in close button, press ESC. If the function is not provided, the page cannot be closed by any of the listed options.
zIndexnumber---The z-index value to be applied to the overlay container. By default, all the modal containers are automatically assigned a correct z-index value. If this prop is defined, it will overwrite the assigned value.
topBarCurrentPathLabelstringThe title propLabel to appear as the current path of the top bar of the modal.
topBarPreviousPathLabelstring"Go Back" (translated)Label to appear as the previous path of the top bar of the modal.
childrennode-Content rendered within the page. If the content is long in height (depending on the screen size) a scrollbar will appear.
getParentSelectorfunction--The function should return an HTML element that will be used as the parent container to hold the modal DOM tree. If no function is provided, it's expected that an HTML element with the id="parent-container" is present in the DOM. In the NODE_ENV=test environment, the default HTML element is body.
shouldDelayOnClosebool-trueSets whether the ModalPage should delay calling its onClose function to allow the closing animation time to finish. This can be turned off if the developer is controlling the ModalPage only through the isOpen prop, and not abruptly mounting/unmounting it or one of its parent elements. You might also want to turn this off if you need to display a prompt (for example to save changes) on the ModalPage before navigating out of it, as this option makes the Modal close itself before onClose is called.
afterOpenStylesstring or object--Overwrite the default styles of afterOpen. You can pass a "class name" or a CSS-in-JS style object. This should be used only in cases the default styles are causing some layout issues.

FormModalPage

Form Modal pages are controlled components used to render a page with a form or something that requires user input. It is similar to InfoModalPage but has a semantically different role. The header includes buttons to control the submission or cancellation of the form. These buttons can be overwritten with custom controls by using the <CustomFormModalPage> component.

Usage

import { useFormik } from 'formik';
import TextField from '@commercetools-uikit/text-field';
import TextInput from '@commercetools-uikit/text-input';
import {
FormModalPage,
useModalState,
} from '@commercetools-frontend/application-components';
const AccountPage = () => {
const formModalState = useModalState();
const formik = useFormik({
initialValues: {
email: '',
},
validate: (formikValues) => {
if (TextInput.isEmpty(formikValues.email)) {
return { email: { missing: true } };
}
return {};
},
onSubmit: async (formikValues) => {
alert(`email: ${formikValues.email}`);
// Do something async
},
});
return (
<FormModalPage
title="Manage your account"
isOpen={formModalState.isModalOpen}
onClose={formModalState.closeModal}
isPrimaryButtonDisabled={formik.isSubmitting}
onSecondaryButtonClick={formik.handleReset}
onPrimaryButtonClick={formik.handleSubmit}
>
<TextField
name="email"
title="Email"
isRequired={true}
value={formik.values.email}
errors={formik.errors.email}
touched={formik.touched.email}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
/>
</FormModalPage>
);
};

Properties

PropsTypeRequiredDefaultDescription
isOpenboolean-Indicates whether the page is open or closed. The parent component needs to manage this state.
titlestring-The title of the page.
subtitlenode or string--The subtitle of the page, usually a React component. If a string is passed, it's rendered as a paragraph.
onClosefunction--Called when the page closes click in overlay, click in close button, press ESC. If the function is not provided, the page cannot be closed by any of the listed options.
zIndexnumber---The z-index value to be applied to the overlay container. By default, all the modal containers are automatically assigned a correct z-index value. If this prop is defined, it will overwrite the assigned value.
topBarCurrentPathLabelstringThe title propLabel to appear as the current path of the top bar of the modal.
topBarPreviousPathLabelstring"Go Back" (translated)Label to appear as the previous path of the top bar of the modal.
childrennode-Content rendered within the page. If the content is long in height (depending on the screen size) a scrollbar will appear.
hideControlsboolean-falseHides the form controls.
labelSecondaryButtonstring | Intl message-CancelThe label for the secondary button as a string, or as an Intl message ({ id, defaultMessage }). See Static properties.
labelPrimaryButtonstring | Intl message-SaveThe label for the primary button as a string, or as an Intl message ({ id, defaultMessage }). See Static properties.
onSecondaryButtonClickfunction-Called when the secondary button is clicked.
onPrimaryButtonClickfunction-Called when the primary button is clicked.
iconLeftSecondaryButtonnode--The icon for the secondary button label.
isPrimaryButtonDisabledboolean-falseIndicates whether the primary button is deactivated or not.
isSecondaryButtonDisabledboolean-falseIndicates whether the secondary button is deactivated or not.
dataAttributesSecondaryButtonobject--Use this prop to pass data- attributes to the secondary button.
dataAttributesPrimaryButtonobject--Use this prop to pass data- attributes to the primary button.
getParentSelectorfunction--The function should return an HTML element that will be used as the parent container to hold the modal DOM tree. If no function is provided, it's expected that an HTML element with the id="parent-container" is present in the DOM. In the NODE_ENV=test environment, the default HTML element is body.
shouldDelayOnClosebool-trueSets whether the ModalPage should delay calling its onClose function to allow the closing animation time to finish. This can be turned off if the developer is controlling the ModalPage only through the isOpen prop, and not abruptly mounting/unmounting it or one of its parent elements. You might also want to turn this off if you need to display a Prompt (for example to save changes) on the ModalPage before navigating out of it, as this option makes the Modal close itself before onClose is called.
afterOpenStylesstring or object--Overwrite the default styles of afterOpen. You can pass a "class name" or a CSS-in-JS style object. This should be used only in cases the default styles are causing some layout issues.

Static properties

  • FormModalPage.Intl

    This is a convenience proxy export to expose pre-defined Intl messages defined in the @commercetools-frontend/i18n package. The Intl messages can be used for button labels.

    <FormModalPage
    // other props...
    labelSecondaryButton={FormModalPage.Intl.revert}
    />

CustomFormModalPage

Custom Form Modal pages are a variation of the <FormModalPage> that allow passing custom control elements via formControls. This is useful in case the modal page needs different control elements than the default ones (primary and secondary buttons).

Usage

import { useFormik } from 'formik';
import TextField from '@commercetools-uikit/text-field';
import TextInput from '@commercetools-uikit/text-input';
import {
CustomFormModalPage,
useModalState,
} from '@commercetools-frontend/application-components';
const AccountPage = () => {
const formModalState = useModalState();
const formik = useFormik({
initialValues: {
email: '',
},
validate: (formikValues) => {
if (TextInput.isEmpty(formikValues.email)) {
return { email: { missing: true } };
}
return {};
},
onSubmit: async (formikValues) => {
alert(`email: ${formikValues.email}`);
// Do something async
},
});
return (
<CustomFormModalPage
title="Manage your account"
isOpen={formModalState.isModalOpen}
onClose={formModalState.closeModal}
formControls={
<>
<CustomFormModalPage.FormSecondaryButton
onClick={formik.handleReset}
/>
<CustomFormModalPage.FormPrimaryButton
onClick={formik.handleSubmit}
/>
<CustomFormModalPage.FormDeleteButton onClick={handleDelete} />
</>
}
>
<TextField
name="email"
title="Email"
isRequired={true}
value={formik.values.email}
errors={formik.errors.email}
touched={formik.touched.email}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
/>
</CustomFormModalPage>
);
};

Properties

PropsTypeRequiredDefaultDescription
isOpenboolean-Indicates whether the page is open or closed. The parent component needs to manage this state.
titlestring-The title of the page.
subtitlenode or string--The subtitle of the page, usually a React component. If a string is passed, it's rendered as a paragraph.
onClosefunction--Called when the page closes: click in overlay, click in close button, press ESC. If the function is not provided, the page cannot be closed by any of the listed options.
zIndexnumber---The z-index value to be applied to the overlay container. By default, all the modal containers are automatically assigned a correct z-index value. If this prop is defined, it will overwrite the assigned value.
topBarCurrentPathLabelstringThe title propLabel to appear as the current path of the top bar of the modal
topBarPreviousPathLabelstring"Go Back" (translated)Label to appear as the previous path of the top bar of the modal
childrennode-Content rendered within the page. If the content is long in height (depending on the screen size) a scrollbar will appear.
formControlsnode--Pass a React.node with form controls. You can use the pre-made form buttons exposed by this component or you can use your own.
getParentSelectorfunction--The function should return an HTML element that will be used as the parent container to hold the modal DOM tree. If no function is provided, it's expected that an HTML element with the id="parent-container" is present in the DOM. In the NODE_ENV=test environment, the default HTML element is body.
hideControlsbool-falseHides the form controls.
shouldDelayOnClosebool-trueSets whether the ModalPage should delay calling its onClose function to allow the closing animation time to finish. This can be turned off if the developer is controlling the ModalPage only through the isOpen prop, and not abruptly mounting/unmounting it or one of its parent elements. You might also want to turn this off if you need to display a Prompt (for example to save changes) on the ModalPage before navigating out of it, as this option makes the Modal close itself before onClose is called.
afterOpenStylesstring or object--Overwrite the default styles of afterOpen. You can pass a "class name" or a CSS-in-JS style object. This should be used only in cases the default styles are causing some layout issues.

Static properties

  • Form Control Buttons

    Pre-configured form control buttons to easily re-use them in the custom controls.

    CustomFormModalPage.FormPrimaryButton = FormPrimaryButton;
    CustomFormModalPage.FormSecondaryButton = FormSecondaryButton;
    CustomFormModalPage.FormDeleteButton = FormDeleteButton;
  • CustomFormModalPage.Intl

    This is a convenience proxy export to expose pre-defined Intl messages defined in the @commercetools-frontend/i18n package. The Intl messages can be used for button labels.

    <CustomFormModalPage
    // other props...
    formControls={
    <CustomFormModalPage.FormSecondaryButton
    // other props...
    label={CustomFormModalPage.Intl.revert}
    />
    }
    />

TabularModalPage

Tabular Modal pages are controlled components used to render a page with navigational controls and route-driven content using Tabs.

Tabs must be rendered using the <TabHeader> component via the tabControls prop. A <TabHeader> is rendered as a link and it assumes the "tab content" is controlled and rendered using <Route> components.

Usage

import {
BrowserRouter as Router,
Switch,
Route,
useRouteMatch,
} from 'react-router-dom';
import {
TabularModalPage,
useModalState,
TabHeader,
} from '@commercetools-frontend/application-components';
const AccountPage = () => {
const match = useRouteMatch();
const tabsModalState = useModalState();
return (
<Router>
<TabularModalPage
title="Manage your account"
isOpen={tabsModalState.isModalOpen}
onClose={tabsModalState.closeModal}
tabControls={
<>
<TabHeader to={`${match.url}/tab-one`} label="Tab One" />
<TabHeader to={`${match.url}/tab-two`} label="Tab Two" />
</>
}
>
<Switch>
<Route path={`${match.path}/tab-one`}>
<Tab1 />
</Route>
<Route path={`${match.path}/tab-two`}>
<Tab2 />
</Route>
</Switch>
</TabularModalPage>
</Router>
);
};

Properties

PropsTypeRequiredDefaultDescription
isOpenboolean-Indicates whether the page is open or closed. The parent component needs to manage this state.
titlestring-The title of the page.
subtitlenode or string--The subtitle of the page, usually a React component. If a string is passed, it's rendered as a paragraph.
onClosefunction--Called when the page closes: click in overlay, click in close button, press ESC. If the function is not provided, the page cannot be closed by any of the listed options.
zIndexnumber---The z-index value to be applied to the overlay container. By default, all the modal containers are automatically assigned a correct z-index value. If this prop is defined, it will overwrite the assigned value.
topBarCurrentPathLabelstringThe title propLabel to appear as the current path of the top bar of the modal.
topBarPreviousPathLabelstring"Go Back" (translated)Label to appear as the previous path of the top bar of the modal.
childrennode-Content rendered within the page. It isn't wrapped by anything except the Modal Container itself, so it's expected to have its style fully customized.
formControlsnode--Pass a React.node with form controls. You can use the pre-made form buttons exposed by this component or you can use your own.
customTitleRownode--Pass a React.node to be used in place of the title and subtitle.
tabControlsnode-Pass a React.node to be used as the Tabs component for controlling the navigation between the Tab contents within the modal.
getParentSelectorfunction--The function should return an HTML element that will be used as the parent container to hold the modal DOM tree. If no function is provided, it's expected that an HTML element with the id="parent-container" is present in the DOM. In the NODE_ENV=test environment, the default HTML element is body.
shouldDelayOnClosebool-trueSets whether the ModalPage should delay calling its onClose function to allow the closing animation time to finish. This can be turned off if the developer is controlling the ModalPage only through the isOpen prop, and not abruptly mounting/unmounting it or one of its parent elements. You might also want to turn this off if you need to display a Prompt (for example to save changes) on the ModalPage before navigating out of it, as this option makes the Modal close itself before onClose is called.
afterOpenStylesstring or object--Overwrite the default styles of afterOpen. You can pass a "class name" or a CSS-in-JS style object. This should be used only in cases the default styles are causing some layout issues.

Static properties

  • Form Control Buttons

    Pre-configured form control buttons to reuse in custom controls.

    TabularModalPage.FormPrimaryButton = FormPrimaryButton;
    TabularModalPage.FormSecondaryButton = FormSecondaryButton;
    TabularModalPage.FormDeleteButton = FormDeleteButton;
  • TabularModalPage.Intl

    This is a convenience proxy export to expose pre-defined Intl messages defined in the @commercetools-frontend/i18n package. The Intl messages can be used for button labels.

    <TabularModalPage
    // other props...
    formControls={
    <TabularModalPage.FormSecondaryButton
    // other props...
    label={TabularModalPage.Intl.revert}
    />
    }
    />

Components for dialogs

The following page components can be used on any page of the Custom Application. For example, showing a confirmation dialog before performing an important action, or showing additional information as an info box.

InfoDialog

Info dialogs are controlled components used to show more information about a particular feature, UI element, etc. They are mainly composed of text paragraphs.

Usage

import {
InfoDialog,
useModalState,
} from '@commercetools-frontend/application-components';
const ChannelsInfo = () => {
const infoModalState = useModalState();
return (
<InfoDialog
title="About channels"
isOpen={infoModalState.isModalOpen}
onClose={infoModalState.closeModal}
>
<Spacings.Stack scale="m">
<Text.Body>{'Channels are ...'}</Text.Body>
</Spacings.Stack>
</InfoDialog>
);
};

Properties

PropsTypeRequiredValuesDefaultDescription
titlestring--The title of the Info Dialog.
isOpenboolean--Indicates whether the dialog is open or closed. The parent component needs to manage this state.
onClosefunction--Called when the dialog closes: click in overlay, click in close button, press ESC.
childrennode--Content rendered within the dialog. If the content is long in height (depending on the screen size) a scrollbar will appear.
sizestring-m, l, scalelHorizontal width of the dialog card. If scale is used, the dialog size expands to the viewport size, with some margin.
zIndexnumber---The z-index value to be applied to the overlay container. By default, all the modal containers are automatically assigned a correct z-index value. If this prop is defined, it will overwrite the assigned value.
getParentSelectorfunction---The function should return an HTML element that will be used as the parent container to hold the modal DOM tree. If no function is provided, it's expected that an HTML element with the id="parent-container" is present in the DOM. In the NODE_ENV=test environment, the default HTML element is body.

ConfirmationDialog

Confirmation dialogs are controlled components used to prompt the user to confirm an important or destructive action. They are similar to Info dialogs but they have a primary and secondary button in the footer area.

Usage

import {
ConfirmationDialog,
useModalState,
} from '@commercetools-frontend/application-components';
const ChannelDeletion = () => {
const confirmationModalState = useModalState();
const handleConfirm = useCallback(() => {
// Do something async
}, []);
return (
<ConfirmationDialog
title="Confirm channel deletion"
isOpen={confirmationModalState.isModalOpen}
onClose={confirmationModalState.closeModal}
onCancel={confirmationModalState.closeModal}
onConfirm={handleConfirm}
>
<Spacings.Stack scale="m">
<Text.Body>{'Are you sure you want to delete this channel?'}</Text.Body>
</Spacings.Stack>
</ConfirmationDialog>
);
};

Properties

PropsTypeRequiredValuesDefaultDescription
titlestring--The title of the Confirmation Dialog.
isOpenboolean--Indicates whether the dialog is open or closed. The parent component needs to manage this state.
onClosefunction---Called when the dialog closes: click in overlay, click in close button, press ESC. If the function is not provided, the modal cannot be closed by any of the listed options.
childrennode--Content rendered within the dialog. If the content is long in height (depending on the screen size) a scrollbar will appear.
sizestringm, l, scalelHorizontal width limit of the dialog card. If scale is used, the dialog size expands to the viewport size, with some margin.
zIndexnumber---The z-index value to be applied to the overlay container. By default, all the modal containers are automatically assigned a correct z-index value. If this prop is defined, it will overwrite the assigned value.
labelSecondarystring | Intl message-CancelThe label for the secondary button as a string, or as an Intl message ({ id, defaultMessage }). See Static properties.
labelPrimarystring | Intl message-ConfirmThe label for the primary button as a string, or as an Intl message ({ id, defaultMessage }). See Static properties.
onCancelfunction--Called when the secondary button is clicked.
onConfirmfunction--Called when the primary button is clicked.
isPrimaryButtonDisabledboolean--falseIndicates whether the primary button is deactivated or not.
dataAttributesSecondaryButtonobject---Use this prop to pass data- attributes to the secondary button.
dataAttributesPrimaryButtonobject---Use this prop to pass data- attributes to the primary button.
getParentSelectorfunction---The function should return an HTML element that will be used as the parent container to hold the modal DOM tree. If no function is provided, it's expected that an HTML element with the id="parent-container" is present in the DOM. In the NODE_ENV=test environment, the default HTML element is body.

Static properties

  • ConfirmationDialog.Intl

    This is a convenience proxy export to expose pre-defined Intl messages defined in the @commercetools-frontend/i18n package. The Intl messages can be used for button labels.

    <ConfirmationDialog
    // other props...
    labelSecondary={ConfirmationDialog.Intl.revert}
    />

FormDialog

Form dialogs are controlled components used to render a form or something that requires user input. They are similar to Confirmation dialogs but fulfill a different role semantically.

Usage

import { useFormik } from 'formik';
import TextField from '@commercetools-uikit/text-field';
import TextInput from '@commercetools-uikit/text-input';
import {
FormDialog,
useModalState,
} from '@commercetools-frontend/application-components';
const EmailForm = () => {
const formModalState = useModalState();
const formik = useFormik({
initialValues: {
email: '',
},
validate: (formikValues) => {
if (TextInput.isEmpty(formikValues.email)) {
return { email: { missing: true } };
}
return {};
},
onSubmit: async (formikValues) => {
alert(`email: ${formikValues.email}`);
// Do something async
},
});
return (
<FormDialog
title="Update email"
isOpen={formModalState.isModalOpen}
onClose={formModalState.closeModal}
isPrimaryButtonDisabled={formik.isSubmitting}
onSecondaryButtonClick={formik.handleReset}
onPrimaryButtonClick={formik.handleSubmit}
>
<TextField
name="email"
title="Email"
isRequired={true}
value={formik.values.email}
errors={formik.errors.email}
touched={formik.touched.email}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
/>
</FormDialog>
);
};

Properties

PropsTypeRequiredValuesDefaultDescription
titlestring--The title of the Form Dialog.
isOpenboolean--Indicates whether the dialog is open or closed. The parent component needs to manage this state.
onClosefunction---Called when the dialog closes: click in overlay, click in close button, press ESC. If the function is not provided, the modal cannot be closed by any of the listed options.
childrennode--Content rendered within the dialog. If the content is long in height (depending on the screen size) a scrollbar will appear.
sizestringm, l, scalelHorizontal width limit of the dialog card. If scale is used, the dialog size expands to the viewport size, with some margin.
zIndexnumber---The z-index value to be applied to the overlay container. By default, all the modal containers are automatically assigned a correct z-index value. If this prop is defined, it will overwrite the assigned value.
labelSecondarystring | Intl message-CancelThe label for the secondary button as a string, or as an Intl message ({ id, defaultMessage }). See Static properties.
labelPrimarystring | Intl message-SaveThe label for the primary button as a string, or as an Intl message ({ id, defaultMessage }). See Static properties.
onSecondaryButtonClickfunction--Called when the secondary button is clicked.
onPrimaryButtonClickfunction--Called when the primary button is clicked.
iconLeftSecondaryButtonnode---The icon for the secondary button label.
isPrimaryButtonDisabledboolean--falseIndicates whether the primary button is deactivated or not.
dataAttributesSecondaryButtonobject---Use this prop to pass data- attributes to the secondary button.
dataAttributesPrimaryButtonobject---Use this prop to pass data- attributes to the primary button.
getParentSelectorfunction---The function should return an HTML element that will be used as the parent container to hold the modal DOM tree. If no function is provided, it's expected that an HTML element with the id="parent-container" is present in the DOM. In the NODE_ENV=test environment, the default HTML element is body.

Static properties

  • FormDialog.Intl

    This is a convenience proxy export to expose pre-defined Intl messages defined in the @commercetools-frontend/i18n package. The Intl messages can be used for button labels.

    <FormDialog
    // other props...
    labelSecondary={FormDialog.Intl.revert}
    />

Other components

TabHeader

Tab Headers facilitate navigation within a tabular page.

In a tabular page, tabs must be rendered using the <TabHeader> component via the tabControls prop. A <TabHeader> is rendered as a link and it assumes the "tab content" is controlled and rendered using <Route> components. <TabHeader> tracks the route changes internally and a tab is active if the to prop matches the current route.

Properties

PropsTypeRequiredDefaultDescription
tostring or LocationDescriptor-A route path to redirect to when the tab is clicked.
labelstring--The label of the tab. Required if intlMessage is not provided.
intlMessageIntl message--The label of the tab, using an intl message object. Required if label is not provided.
isDisabledboolean-falseIndicates whether the tab is deactivated or not.
exactPathMatchboolean-falseIf true, marks the tab as active if the link matches exactly the route.

Page content components

When displaying the content of a page, it's important to structure it properly to establish a visual hierarchy and provide the users with a familiar user experience. To learn more about different layouts, see Page Content Layouts.

We provide the following components to help you create page content layouts:

PageContentNarrow

Renders the children in a narrow page content layout.

Usage

import { PageContentNarrow } from '@commercetools-frontend/application-components';
const ChannelsDetails = () => {
// ...
return (
<PageContentNarrow>
<Spacings.Stack>
<div>Title</div>
<ChannelsForm />
</Spacings.Stack>
</PageContentNarrow>
);
};

Properties

PropsTypeRequiredDescription
childrennodeContent rendered within this layout.

PageContentWide

Renders the children in a wide page content layout.

Usage

import { PageContentWide } from '@commercetools-frontend/application-components';
const ChannelsDetailsSingleColumn = () => {
// ...
return (
<PageContentWide>
<Spacings.Stack>
<div>Title</div>
<ChannelsForm />
</Spacings.Stack>
</PageContentWide>
);
};
const ChannelsDetailsTwoColumn1_1 = () => {
// ...
return (
<PageContentWide columns="1/1">
<div>Left side</div>
<div>Right side</div>
</PageContentWide>
);
};
const ChannelsDetailsTwoColumn2_1 = () => {
// ...
return (
<PageContentWide columns="2/1">
<Spacings.Stack>
<ChannelsForm />
</Spacings.Stack>
<Spacings.Stack>
<div>Meta info</div>
</Spacings.Stack>
</PageContentWide>
);
};

Properties

PropsTypeRequiredDefaultDescription
columnsenum

1, 1/1, 2/1
-1For a single-column layout, use the 1. For a two-column layout with equal widths, use 1/1. For a two-column layout with column widths in a 2:1 ratio, use 2/1.
gapSizeenum

10, 20
-20The space between the two columns.
childrennode-Content rendered within this layout.

In a two-column layout, the children are rendered from left to right in the order they're used.

PageContentFull

Renders the children in a full page content layout.

Usage

import { PageContentFull } from '@commercetools-frontend/application-components';
const ChannelsDetails = () => {
// ...
return (
<PageContentFull>
<ChannelsTable />
</PageContentFull>
);
};

Properties

PropsTypeRequiredDescription
childrennodeContent rendered within this layout.

Hooks

useModalState

Using the dialog or modal page components usually requires having some state to open/close these components.

Usage

import {
useModalState,
InfoDialog,
} from '@commercetools-frontend/application-components';
const MyComponent = () => {
const infoModalState = useModalState();
return (
<div>
<button onClick={infoModalState.openModal}>Click me</button>
<InfoDialog
isOpen={infoModalState.isModalOpen}
onClose={infoModalState.closeModal}
title="Welcome"
>
Hi there.
</InfoDialog>
</div>
);
};

Return type

The following is the definition of the state object returned by useModalState:

  • isModalOpen: Whether the state is open or closed.
  • openModal: Update the isModalOpen state to true.
  • closeModal: Update the isModalOpen state to false.

Usage outside of Custom Applications

If you happen to use some of the components outside of a Custom Application, you need to additionally render the <PortalsContainer>.

The <PortalsContainer> renders an empty HTML element with a specific identifier and is used to render all modal components (for example dialogs or modal pages). Make sure to render this component once in your application.

import { PortalsContainer } from '@commercetools-frontend/application-components';
const Application = () => (
<main>
<PortalsContainer />
{/* ... */}
</main>
);