Custom element example
This commit is contained in:
parent
977fd80d0c
commit
d4aa8fb377
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"info": {
|
||||
"id": "custom-elements",
|
||||
"name": "Custom Elements Example",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jiiks",
|
||||
"discord_id": "81388395867156480",
|
||||
"github_username": "Jiiks",
|
||||
"twitter_username": "Jiiksi"
|
||||
}
|
||||
],
|
||||
"version": 1.0,
|
||||
"description": "Custom Elements Description"
|
||||
},
|
||||
"main": "index.js"
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/**
|
||||
* This is an example of how you should add custom elements instead of manipulating the DOM directly
|
||||
*/
|
||||
|
||||
module.exports = (Plugin, Api, Vendor) => {
|
||||
|
||||
// Destructure some apis
|
||||
const { Logger, ReactComponents, Patcher, monkeyPatch, Reflection, Utils, CssUtils } = Api;
|
||||
const { React } = Reflection.modules; // This should be in vendor
|
||||
|
||||
return class extends Plugin {
|
||||
|
||||
async onStart() {
|
||||
Logger.log('Custom Elements Example Started');
|
||||
this.injectStyle();
|
||||
this.patchGuildTextChannel();
|
||||
return true;
|
||||
}
|
||||
|
||||
async onStop() {
|
||||
Logger.log('Custom Elements Example Stopped');
|
||||
// The automatic unpatcher is not there yet
|
||||
Patcher.unpatchAll();
|
||||
CssUtils.deleteAllStyles();
|
||||
|
||||
// Force update elements to remove our changes
|
||||
const GuildTextChannel = await ReactComponents.getComponent('GuildTextChannel');
|
||||
GuildTextChannel.forceUpdateAll();
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Inject some style for our custom element */
|
||||
async injectStyle() {
|
||||
const css = `
|
||||
.exampleCustomElement {
|
||||
background: #7a7d82;
|
||||
color: #FFF;
|
||||
border-radius: 5px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
opacity: .5;
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}`;
|
||||
await CssUtils.injectSass(css);
|
||||
}
|
||||
|
||||
async patchGuildTextChannel() {
|
||||
// Get the GuildTextChannel component and patch it's render function
|
||||
const GuildTextChannel = await ReactComponents.getComponent('GuildTextChannel');
|
||||
monkeyPatch(GuildTextChannel.component.prototype).after('render', this.injectReact.bind(this));
|
||||
// Force update to see our changes immediatly
|
||||
GuildTextChannel.forceUpdateAll();
|
||||
}
|
||||
|
||||
/* Injecting a custom Vue element */
|
||||
injectVue() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
/*
|
||||
* Injecting a custom React element using React.createElement
|
||||
* https://reactjs.org/docs/react-api.html#createelement
|
||||
**/
|
||||
injectReact(that, args, returnValue) {
|
||||
// Get the child we want using a treewalker since we know the child we want has a channel property and children.
|
||||
const child = Utils.findInReactTree(returnValue, filter => filter.hasOwnProperty('channel') && filter.children);
|
||||
if (!child) return;
|
||||
// If children is not an array make it into one
|
||||
if (!child.children instanceof Array) child.children = [child.children];
|
||||
|
||||
// add our custom component to children
|
||||
child.children.push(React.createElement(
|
||||
'button',
|
||||
{ className: 'exampleCustomElement', onClick: e => this.handleReactClick(e, child.channel) },
|
||||
'i'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Will log the channel object
|
||||
*/
|
||||
handleReactClick(e, channel) {
|
||||
Logger.log('Clicked!', channel);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
Loading…
Reference in New Issue