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 is Widgets 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" to Widgets get store data
  • Editor reads the manifest uses 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 ?)
Made with Slides.com