Registering SDK Components
Topic
Author:
Fluent Commerce
Changed on:
6 Sept 2024
Overview
Developers can add new components to OMX via the registries.There are three available:- Component Registry - for standard in-page components
- Field Registry - for interactive form field components
- Template Registry - for adding new template helpers
Registering SDK Components
Author:
Fluent Commerce
Changed on:
6 Sept 2024
Overview
Developers can add new components to OMX via the registries.There are three available:- Component Registry - for standard in-page components
- Field Registry - for interactive form field components
- Template Registry - for adding new template helpers
Key points
- Component Registry
- Field Registry
- Template Registry
Component Registry
Components are the building blocks of an OMX web app.SDK developers can build and register new components with the Component Registry, which allows them to be referenced in a web app manifest just like out-of-the-box components.Naming a component
Component names don't need to follow any strict rules, but in general should be as simple as possible, while leaving room to expand later on.The typical Fluent convention is a period-separated hierarchy of:- account namespace of the author (
`fc.`in our case, for "Fluent Commerce") - the type of component (e.g.
`card.`) - and finally the variant (e.g.
`map`)
`fc.card.map`.Sometimes you might have variants of variants, in which case it's fine to add levels as we have with `fc.button.print.download` and `fc.button.print.inline`.Registering a component
New components can be installed via the ComponentRegistry.After writing a custom component, rather than rendering it you simply give it a name in the ComponentRegistry...1const HelloComponent: FC<HelloComponentProps> = ({label}) => {
2 return (<h2>{label}</h2>);
3}
4ComponentRegistry.register(['ACME.HelloWorld'], HelloComponent);1routes: [
2 { path:'hello', component:'Page', decendants:[
3 { component:'ACME.HelloWorld', props:{ 'label':'Hello World!' } }
4 ]}
5]1const myProps = {
2 a: PropTypes.string(),
3 b: PropTypes.number().isRequired,
4 c: PropTypes.arrayOf.object(ColourPicker).isRequired,
5};
6const HelloProps: FC<InferProps<typeof myProps>> = ({b /* inferred as 'number' */, c /* inferred as custom type 'ColourPicker[]' */}) => {
7 return <div />;
8};
9BasicComponent.displayName = 'HelloProps';
10BasicComponent.propTypes = myProps;Retrieving a component from the registry
To use a component from the registry you can retrieve it using the provided`get` method.1const Comp = ComponentRegistry.get('acme.card.custom');
2return Comp ? (<Comp data={data} width={6} />) : null;`ComponentRegistry.get()` to attempt to load a series of fallbacks to represent the filter label. The order is most specific to least, allowing developers to override at the level they need to. If none are overridden, a basic `span` is returned.1const Comp = ComponentRegistry.get([
2 `fc.filter.${entityType}.${fieldName}.label`,
3 `fc.filter.${entityType}.${fieldType}.label`,
4 `fc.filter.${fieldName}.label`,
5 `fc.filter.${fieldType}.label`,
6], { noLog:true });
7
8return Comp ? (<Comp data={filter} />) : (<span>{filter.value.toString()}</span>);Field Registry
New form fields are installed via the Field Registry.This allows developers to add new field components to UX forms generated either from Rubix user actions (to match the data types expected by custom Rules) or GraphQL mutations (to improve the UX of previously purely auto-generated forms).1FieldRegistry.register(['string', 'text', 'input'], TextInput);Extending Filters
The standard`fc.list` component has a filter bar driven by the GraphQL schema.Using the Field Registry, you can implement custom UX for the configuration and display of these filters.Adding a new filter type
New filter types can be registered via the FieldRegistry. The field component should behave the same way as a normal form field (i.e. render a control and produce values via onChange), but it will be shown inside a modal when a matching filter is selected from the filters dropdown.Common use-cases include:- implementing a UX for a GraphQL type that doesn't currently exist
- tailoring the UX of an existing filter for a special case
- using the
`useSetting`hook inside a filter component to pre-fetch a list of valid type or status value from a retailer or account setting
`fc.filter.order.status``fc.filter.order.string``fc.filter.status``fc.filter.string`
Custom filter labels
When a filter produces a non-string result it might not look right in the filter chip that is produced on submit.For these cases, you can use the ComponentRegistry to provide a view component that will be embedded within the chip, following the same fallback logic:`fc.filter.order.status.label``fc.filter.order.string.label``fc.filter.status.label``fc.filter.string.label`
`onChange` event in the field) as the `data` prop, and should be registered with the ComponentRegistry:1ComponentRegistry.register(['fc.filter.order.status.label'], OrderStatusWithIcon, {category:'filter'});Extending Mutations
When a form is generated for a GraphQL mutation, Mystique chooses fields based on a similar specificity-based fallback strategy.`fc.mutation.order.attribute.value`(full path and field name)`fc.mutation.order.attribute.json`(full path and field type)`fc.mutation.attribute.value`(entity type and field name)`fc.mutation.attribute.json`(entity type and field type)`fc.mutation.value`(field name)`fc.mutation.json`(field type)
`string` fields) down to very specifically (e.g. the `value` field of `order attributes`) by registering a new field with the `FieldRegistry` at the desired level.Template Registry
Many OMX components use template strings to allow customisation of components via the manifest.1{ "value": "{{order.status}}" } // = "BOOKED"1{ "value": "{{dateRelative order.createdOn}}" } // = "5 days ago"1TemplateRegistry.register(['uppercase', 'toUpperCase'], function(str) {
2 return str.toUpperCase();
3});