Not sure if you are aware but we have a set of useful web components that can be used in add-ons. Customers/Partners asked many times to let them reuse common elements like buttons, inputs, typography. But it is also very useful to allow them to reuse more complex elements like content-selector or image picker.
It should be very simple to use them, without any kind of special setup or bootstrapping.
For now there are just a few components available but hopefully more will be added in the future:
- optimizely-button
- optimizely-input
- optimizely-checkbox
- optimizely-typography
- optimizely-content-tree - which is rendered as a button and opens a dialog with the content tree and saves the selected content link
It is possible to create
optimizely-xxx
both declaratively and imperatively.
so both
<optimizely-typography tag="h1" text="Hello world"></optimizely-typography>
and
const optiTypography = document.createElement("optimizely-typography"); optiTypography.tag= "h1"; optiTypography.text = "Hello world"; window.body.appendChild(optiTypography );
are acceptable.
So for example. This is a simple admin mode plugin which is used by testers to generate some content items.
It is a simple internal tool which was created very fast but it is quite difficult to use as you need to type content link manually. The controls look a bit ugly and it is not very user friendly.
It can be easily improved with the use of the web components and below you can find the updated code.
<div class="container"> <h1>Generate content</h1> <div> <div id="result"></div> <div class="formField"> <optimizely-typography type="caption" text="Root id"></optimizely-typography> <optimizely-content-tree id="content-tree"></optimizely-content-tree> </div> <div class="formField"> <optimizely-typography type="caption" text="Count"></optimizely-typography> <optimizely-input id="count-input" value="10"></optimizely-input> </div> <div class="formField"> <optimizely-typography type="caption" text="Truncate parent"></optimizely-typography> <optimizely-checkbox id="truncate-checkbox"></optimizely-checkbox> </div> <div class="formField"> <optimizely-typography type="caption" text="Generate images"></optimizely-typography> <optimizely-checkbox id="truncate-generate-images"></optimizely-checkbox> </div> <div class="formField"> <optimizely-typography type="caption" text="Also create notification"></optimizely-typography> <optimizely-checkbox id="truncate-create-notification"></optimizely-checkbox> </div> <optimizely-button id="generate" buttonStyle="highlight" text="Generate"></optimizely-button> </div> </div> <script type="text/javascript"> const data = { count: 10 }; document.getElementById("content-tree").addEventListener("onNodeSelected", (event) => { data.root = event.detail.contentLink; }); document.getElementById("count-input").addEventListener("onChange", (event) => { data.count = event.detail; }); document.getElementById("truncate-checkbox").addEventListener("onChange", (event) => { data.truncateParent = event.detail; }); document.getElementById("truncate-generate-images").addEventListener("onChange", (event) => { data.generateImages = event.detail; }); document.getElementById("truncate-create-notification").addEventListener("onChange", (event) => { data.createNotification = event.detail; }); document.getElementById("generate").addEventListener("onClick", () => { var result = document.getElementById("result"); result.innerHTML = "Command in progress..."; var formData = new FormData(); Object.keys(data).forEach(key => { formData.append(key, data[key]); }); var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { result.innerHTML = xhr.responseText; } } xhr.open("post", "/NewsGeneratorPlugin/Generate"); xhr.setRequestHeader("Accept", "application/json"); xhr.send(formData); }); </script>
And then it looks like this:
As you can see attaching events is pretty standard. There are no custom styles, everything is inherited from the default optimizely stylesheet.
In order to use the Web Components you need to either register them manually:
@Html.Raw(Html.RegisterOptimizelyWebComponents())
Or use the CommonLayout.cshtml where they are already registered (described in How to add an Admin Mode add-on in Optimizely CMS)