JSFiddle - React, Tailwind, and code Playground

by mcsf

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.0.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.0.0/umd/react-dom.development.js"></script>
The following showcases a component enhancement built on top of WithAPIData that intercepts reads from and writes to a block's attributes, providing or locally setting site options depending on the attribute.

<div id="app">
</div>

Babel + JSX

const main = () => {
  ReactDOM.render( <EnhancedBlockEdit />,
  document.getElementById( 'app' ) );
};

// Fixture
const WithAPIData = () => ( WrappedComponent ) =>
	( props ) => <WrappedComponent
    { ...props }
    settings={ {
    	data: { description: "I'm a description" },
      save: () => {},
    } } />;
    
const blockType1 = {
	attributes: {
  	description: {
    	type: 'string',
      option: 'description',
    },
    isAwesome: {
    	type: 'boolean',
      default: true,
    },
  },
};
    
const blockType2 = {
	attributes: {
    isRegular: {
    	type: 'boolean',
      default: true,
    },
  },
};
    
const BlockEdit = ( { attributes, setAttributes } ) => {
	const { description } = attributes;
  return [
    <p key="prop">Prop: { description }</p>,
    <input key="input"
      value={ description }
      onChange={
        ( event ) => setAttributes( { description: event.target.value } )
      } />
  ];
};

const WithFakeSettings = ( blockType ) => ( WrappedComponent ) =>
	class extends React.Component {
  	constructor() {
			super( ...arguments );
      this.setAttributes = this.setAttributes.bind( this );
      this.state = { settings: {} };
      // TODO: map between attr name and option name
      this.SETTINGS_KEYS = _.reduce( blockType.attributes,
      	( acc, value, key ) => 'option' in value ? [ ...acc, key ] : acc,
				[] );
    }
    
  	setAttributes( attributes ) {
    	const intercepted = {};
      const passedThrough = {};
    	Object.keys( attributes ).forEach( ( key ) => {
      	if ( _.includes( this.SETTINGS_KEYS, key ) ) {
        	console.log( 'setting', key );
          intercepted[ key ] = attributes[ key ];
        } else {
					passedThrough[ key ] = attributes[ key ];
        }
			} );
      if ( ! _.isEmpty( intercepted ) ) {
        console.log( 'setter: setState' );
        this.setState( { settings: intercepted } );
      }
      if ( ! _.isEmpty( passedThrough ) ) {
        console.log( 'setter: passthrough' );
   ...