Last active
June 30, 2019 20:01
-
-
Save braco/5c48ad162dcd27f072debc3967aee0b0 to your computer and use it in GitHub Desktop.
Repeating components in Wordpress Gutenberg
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
``` | |
edit: repeater({ | |
editing: true, | |
renderComponent: ({ attributes: { name }, setAttributes }) => | |
<MyComponent | |
name={ | |
<PlainText | |
value={ name } | |
placeholder={'Name'} | |
onChange={ value => setAttributes( { name: value } ) } | |
/> | |
} | |
/> | |
}), | |
save: repeater({ | |
renderComponent: ({ attributes: { name } }) => <MyComponent name={name} /> | |
}) | |
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const repeater = ({ | |
attribute: key = 'data', | |
renderComponent, | |
renderContainer = (props) => <div {...props} />, | |
editing = false, | |
}) => ({ attributes, setAttributes }) => { | |
// WP doesn't support array of objects :) | |
let thisAttribute; | |
try { | |
const parsed = JSON.parse(attributes[key]); | |
thisAttribute = Array.isArray(parsed) ? parsed : [{}]; | |
} catch (e) { | |
thisAttribute = [{}]; | |
} | |
return renderContainer({ | |
children: <React.Fragment> | |
{ | |
thisAttribute.map((item, i) => { | |
const thisIndex = i; | |
const setIndexedAttribute = (obj) => { | |
Object.keys(obj).map(k => thisAttribute[thisIndex][k] = obj[k]); | |
setAttributes({ | |
[key]: JSON.stringify(thisAttribute) | |
});; | |
} | |
return renderComponent({ | |
index: i, | |
attributes: thisAttribute[thisIndex], | |
setAttributes: setIndexedAttribute | |
}) | |
}) | |
} | |
{ | |
editing && | |
<div> | |
<button onClick={() => { | |
thisAttribute.length && thisAttribute.pop(); | |
setAttributes({ | |
[key]: JSON.stringify(thisAttribute) | |
}); | |
}}>One less</button> | |
<button onClick={() => { | |
thisAttribute.push({}); | |
setAttributes({ | |
[key]: JSON.stringify(thisAttribute) | |
}); | |
}}>One more</button> | |
</div> | |
} | |
</React.Fragment> | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment