Manifest to Maniless
a review and proposal to alter how Widgets are mutated
History
- Widgets accessed data using Fluxible
- Widgets had simple, static schema definitions
- Widgets exposed "fields" in manifest, defaults in Widget.
- Editor used Widget meta to provide editing experience using "mutators"
fieldSets: [{
name: 'business-name',
header: 'Business name',
description: 'Enter the name of your business',
icon: 'sm-business',
fields: [{
label: 'Business Name',
property: 'businessName',
type: editorTypes.TEXT
}]
}]export default connectPropsToStores(Header1, {
businessName: [NestedProp.property]
});Manifest
Widget
Problems
- Doesn't support dynamic properties (cards/gallery)
- Doesn't enable advanced validations
- Tightly couples Widget to Render Stores
- Missing i18n support
Current
- Widgets access data using Extensions
- Widgets have complex schema definitions
- Widgets expose fields, defaults, i18n, and mutator arguments in manifest.
- Editor uses manifest tools and extensions to provide editing experience using "mutators"
{
types: {
businessNameBinding: {
kind: 'extensionBinding',
type: 'TEXT',
extensionName: 'BusinessInfo',
field: 'businessName',
defaultOnly: true,
defaultValue: {
kind: 'translatedValue',
value: 'fallbackForHeaderBusinessName'
},
arguments: {
maxCount: 50
}
}
},
props: {
businessName: {
kind: 'typeReferenceWithDisplayInfo',
type: 'businessNameBinding',
editingDisplay: {
titleId: {
kind: 'translatedValue',
value: 'titleForHeaderBusinessName'
},
descriptionId: {
kind: 'translatedValue',
value: 'descriptionForHeaderSiteName'
}
}
}
}
}Manifest
Problems
- Overly complex
- It's own language
- Requires updates in multiple locations
- Mixes concerns of props vs mutators
- Data driven, doesn't support widget specified logic
Proposal
- Widgets access data using Selectors
- Widgets use native React based definitions
- Widgets expose a Mutator Component.
- Editor renders Widget's Mutator to provide editing experience.
- Editor and Widgets can override SDK's default Mutator experience
const Widget = connect(class extends SDK.Widget {
static propTypes = {
businessName: SDK.PropTypes.string.maxCount(50)
};
static defaultProps = {
businessName: [
SDK.Selectors.Website.businessName,
SDK.Intl("fallbackForHeaderBusinessName")
]
};
});Widget
const Mutator = createMutator(class extends SDK.Mutator {
static mutatorFields = ["businessName"];
static defaultProps = {
businessNameTitle: SDK.Intl("titleForHeaderBusinessName"),
businessNameDesc: SDK.Intl("descriptionForHeaderSiteName")
};
render() {
const { route } = this.state;
return (
<Route path="/">
<SDK.Mutators.Text
name="businessName"
title={ this.props.businessNameTitle }
description={ this.props.businessNameDesc }
/>
</Route>
);
}
}, Widget);Mutator
Problems?
- Widgets own editing experience for app(s)
- Changes still required across multiple libs
- Mutators are still their own framework
In Review: Today
- Customers edit their website using "Editor"
- Editor is responsible for editing "Widgets"
- Widgets render based on "Props"
- Widget expresses props using a "Manifest"
- Manifest is parsed using "Manifest Tools"
- Manifest tools use "Extensions" to get store data
- Editor reads the manifest to render "Mutators"
- Mutators are hard
In Review: Tomorrow
- Customers edit their website using "Editor"
-
Editor isWidgets are responsible for editing "Widgets" - Widgets render based on "Props"
- Widget expresses props using
a "Manifest"React Manifest is parsed using "Manifest Tools"-
Manifest tools use "Extensions" toWidgets get store data - Editor
reads the manifestuses Widget to render "Mutators" - Mutators are not so hard
Features
- Shared mutator lib (core)
- Mutators are overwritable and extendable like themes
- Widgets can own their own mutators/validations
- Native defaultProps/propTypes work
- Before write/After read hooks/validation
Topics still to be discussed
- Build artifacts
- Ownership of services/integrations
- Editor still a first class integration
- Final mutator interface (manifest vs react vs ?)
Maniless
By gingur
Maniless
- 100