Overriding UI components
Mercury offers a lot of components out of the box. Sometimes they do not offer what you need and you write your own. However, sometimes you just want to change a part of an existing component. Mercury uses React.js under the hood and components are made out of other components.
Bundles
The Mercury components are grouped in logical bundles. So first you need to determine in which bundle to replace the component. For example, if you would like to replace a product related component, you would need to replace it in the MercuryCatalog bundle.
Inversion of control
Internally Mercury uses a principle which is called Inversion of control. In the case of Mercury this means that all components and dependencies are resolved through an IOC container. This also makes it possible for projects using Mercury to replace the components in the container.
All the bundles expose functionality to access the container using a container property. For example: MercuryCatalog.container. The most important functions exposed by this property are get and replace. The get method can be used to access the inner components of Mercury and the replace method is used to swap the original Mercury component with your own.
The container uses the original components as the key, for example:
container.replace('./components/example.jsx', require('mycomponent.jsx'))
The key is the internal path of the mercury component. To find out the path of the component you would like to replace its probably easiest to open the unminified version of the bundle and search for '.jsx'. You will then find a list of paths of all the components in the bundle and it should be fairly easy to find the component you are looking for.
var map = {
"./actions/filteractions.js": 38,
"./actions/filtersettingsactions.js": 45,
"./actions/imageactions.js": 52,
"./actions/productdetailsactions.js": 29,
"./actions/productselectionactions.js": 26,
"./actions/recentlyviewedproductsactions.js": 90,
"./componentcontainerbuilder.js": 3,
"./components/connecttoproductstore.jsx": 4,
"./components/filter/clearfilter.jsx": 42,
.. etc.
Example
Lets say we would like to replace the product part of the product lister that is used on the filter page:

In this case the root Mercury component is products.jsx, which uses a product.jsx component to display the individual products. In order to replace the product.jsx component we first need to look up the internal Mercury path of the product.jsx component. If we open the unminified bundle and search for product.jsx, we find ./components/product.jsx.
In our custom script we can then replace the component:
MercuryCatalog.container.replace('./components/product.jsx', require('./customproduct.jsx'));
Make sure that the replacing component supports the same properties as the original Mercury component. Using the React chrome tools is a great way of exploring the Mercury component tree and to see what properties are passed to the underlying components!
New React configuration mechanism
The above described way of overriding React components is being replaced. This section describes the new configuration mechanism which is applied to new features, and will be gradually rolled out for existing components.
Configure to use React component
Mercury Sitecore renderings have a "React component" settings available. This fields specifies what React component to use. In order to use their own React component, client projects can copy the Sitecore rendering item into their project structure and change the "React component" setting. Note that for old-style components, filling this settings overrides the hard-coded React component in the Razor view.
Use different child component in Mercury React component
Mercury React components use render props, i.e. function properties that render React components, for child components.
For example:
import { Lister } from 'mercury-sharing';
import MyCustomRenderItem from './my-custom-render-item';
const MyLister = <Lister renderItem={myCustomRenderItem} />
Replace React component in Mercury bundle
Mercury bundles expose replace functions for each replaceable React component. This function can be used in a client project to change the default Mercury React component. This is useful for replacing all occurences of a certain React component.
For example:
import Sharing from 'mercury-sharing';
import MyCustomComponent from './my-custom-component';
Sharing.replaceLister(MyCustomComponent)