@@ -191,6 +191,227 @@ window.lumapps.customize(({ targets, components, render, placement, constants })
191
191
});
192
192
```
193
193
194
+ ## Add new button on the rich text editor toolbar (widget RTE, article or event)
195
+
196
+ ![ Use case wrex button] ( ./assets/use-case-wrex-toolbar-item.png " Use case wrex button ")
197
+
198
+ In this use case, you'll probably want to have a new button on the rich text editor toolbar allowing you to insert specific elements from an external provider.
199
+
200
+ ``` js
201
+ window .lumapps .customize (
202
+ ({ targets, components, render, placement, constants, state }) => {
203
+ const {
204
+ DropdownSection ,
205
+ DropdownItem ,
206
+ RawHTML ,
207
+ FlexBox ,
208
+ Button ,
209
+ List ,
210
+ ListItem ,
211
+ } = components;
212
+ const { Orientation , Size , Emphasis , Alignment } = constants;
213
+
214
+ /** Fetch the items from your external provider
215
+ * You can use our api wrapper(https://lumapps.github.io/customizations-api-doc/javascript/api.html#api-1)
216
+ */
217
+ const fetchItems = async () => {
218
+ const fetchedItems = new Promise ((resolve ) => {
219
+ setTimeout (() => {
220
+ resolve ([
221
+ { id: " 54" , title: " First item" , src: " https://lumapps.com" },
222
+ { id: " 57" , title: " Second item" , src: " https://picsum.photos/" },
223
+ ]);
224
+ }, 500 );
225
+ });
226
+ return fetchedItems;
227
+ };
228
+
229
+ /** Callback on search button click
230
+ * - Fetch external items
231
+ * - Render those items on a list
232
+ */
233
+ async function onItemsSearch () {
234
+ const context = state .get (" context" );
235
+ const input = document .querySelector (" input#items-search-input" );
236
+ const searchQuery = input .value ;
237
+
238
+ // Trigger the loading state of the dialog while we fetch items
239
+ context .openWrexConfigurationDialog ({
240
+ isLoading: true ,
241
+ });
242
+
243
+ const items = await fetchItems ();
244
+
245
+ const { componentToRender } = setupConfiguration ({ items, searchQuery });
246
+
247
+ await context .openWrexConfigurationDialog ({
248
+ componentToRender,
249
+ isLoading: false ,
250
+ });
251
+ }
252
+
253
+ /** Callback when the user select an item from the list
254
+ * - Update the attributes on the element we want to insert
255
+ * - Rerender the list to display the selected state on the item
256
+ */
257
+ const onItemPickChange = (item , configurationData ) => {
258
+ const context = state .get (" context" );
259
+
260
+ context .setWrexIframeAttributes ({
261
+ src: item .src ,
262
+ provider: " my-website" ,
263
+ });
264
+
265
+ const { componentToRender } = setupConfiguration ({
266
+ ... configurationData,
267
+ selectedItemId: item .id ,
268
+ });
269
+
270
+ context .openWrexConfigurationDialog ({
271
+ componentToRender,
272
+ });
273
+ };
274
+
275
+ /**
276
+ * Return the components to render on the configuration dialog
277
+ * - Display only an input + a search button without fetched items
278
+ * - Display the items in a list when available
279
+ */
280
+ function setupConfiguration (configurationData = {}) {
281
+ const { items , searchQuery , selectedItemId } = configurationData;
282
+ const componentsToDisplay = [
283
+ FlexBox ({
284
+ children: [
285
+ // Note: this allow to display an input the same way as other place of the product
286
+ RawHTML ({
287
+ html: `
288
+ <div class="lumx-text-field lumx-text-field--has-input lumx-text-field--has-label lumx-text-field--theme-light">
289
+ <div class="lumx-text-field__wrapper">
290
+ <div class="lumx-text-field__input-wrapper">
291
+ <input type="text" id="items-search-input" class="lumx-text-field__input-native lumx-text-field__input-native--text" value="${
292
+ searchQuery || " "
293
+ } " placeholder="Search an item">
294
+ </div>
295
+ </div>
296
+ </div>` ,
297
+ }),
298
+ Button ({
299
+ children: " Search" ,
300
+ emphasis: Emphasis .low ,
301
+ onClick: onItemsSearch,
302
+ }),
303
+ ],
304
+ orientation: Orientation .horizontal ,
305
+ gap: Size .regular ,
306
+ hAlign: Alignment .center ,
307
+ }),
308
+ ];
309
+
310
+ if (items && items .length > 0 ) {
311
+ const listItems = [];
312
+
313
+ for (const item of items) {
314
+ listItems .push (
315
+ ListItem ({
316
+ children: item .title ,
317
+ size: Size .tiny ,
318
+ onItemSelected : () => onItemPickChange (item, configurationData),
319
+ isSelected: selectedItemId === item .id ,
320
+ })
321
+ );
322
+ }
323
+
324
+ componentsToDisplay .push (
325
+ List ({
326
+ children: listItems,
327
+ })
328
+ );
329
+ }
330
+
331
+ const componentToRender = FlexBox ({
332
+ children: componentsToDisplay,
333
+ orientation: Orientation .vertical ,
334
+ gap: Size .huge ,
335
+ });
336
+
337
+ return { componentToRender };
338
+ }
339
+
340
+ /** Callback when the user click on our video custom button */
341
+ const onVideoButtonClick = async (context ) => {
342
+ state .set (" context" , context);
343
+ const { componentToRender } = setupConfiguration ();
344
+
345
+ context .openWrexConfigurationDialog ({
346
+ componentToRender,
347
+ });
348
+ };
349
+
350
+ render ({
351
+ placement: placement .UNDER ,
352
+ target: targets .WREX_TOOLBAR ,
353
+ toRenderWithContext : (context ) => {
354
+ return DropdownSection ({
355
+ children: [
356
+ DropdownItem ({
357
+ title: " My videos" ,
358
+ icon: " video-account" ,
359
+ onClick : () => onVideoButtonClick (context),
360
+ }),
361
+ ],
362
+ });
363
+ },
364
+ });
365
+ }
366
+ );
367
+ ```
368
+ ### Use case information
369
+
370
+ ** openWrexConfigurationDialog** Function
371
+
372
+ Open the configuration dialog and allows you to define his content.
373
+
374
+ | Parameter | Description | Is required? | Option type | Default Value |
375
+ | -----------| ------| ----------| ---------| -------------|
376
+ | ` configuration ` | Configuration options | Yes | object | ` {} ` |
377
+ | ` configuration.componentToRender ` | The component to render inside the dialog | Yes | Component | ` undefined ` |
378
+ | ` configuration.isLoading ` | Whether the dialog should be in a loading state | No | boolean | ` false ` |
379
+
380
+ ** setWrexIframeAttributes** Function
381
+
382
+ Allows you to define the data of the iframe to insert
383
+
384
+ * Note: calling this function will not insert an iframe, the insertion is done through the configuration dialog*
385
+
386
+ | Parameter | Description | Is required? | Option type | Default Value |
387
+ | -----------| ------| ----------| ---------| -------------|
388
+ | ` attributes ` | Configuration options | Yes | object | ` {} ` |
389
+ | ` attributes.src ` | The url of the page to embed | Yes | string | ` undefined ` |
390
+ | ` attributes.srcDoc ` | The html content of the iframe | No | string | ` undefined ` |
391
+ | ` attributes.title ` | The title of the iframe, used for accessibility | No | string | ` undefined ` |
392
+ | ` attributes.provider ` | The name of the provider of the iframe, used to identify an iframe | No | string | ` undefined ` |
393
+
394
+ ** setWrexImageAttributes** Function
395
+
396
+ Allows you to define the data of the image to insert
397
+
398
+ * Note: calling this function will not insert an image, the insertion is done through the configuration dialog*
399
+
400
+ | Parameter | Description | Is required? | Option type | Default Value |
401
+ | -----------| ------| ----------| ---------| -------------|
402
+ | ` attributes ` | Configuration options | Yes | object | ` {} ` |
403
+ | ` attributes.title ` | The caption of the image group | No | string | ` undefined ` |
404
+ | ` attributes.images ` | The image(s) to display | Yes | Image[ ] | ` [] ` |
405
+
406
+ ** Image** Object
407
+
408
+ | Parameter | Description | Is required? | Option type | Default Value |
409
+ | -----------| ------| ----------| ---------| -------------|
410
+ | ` src ` | The image url | Yes | string | ` '' ` |
411
+ | ` alt ` | The image alt text, should describe the image for accessibility purpose | No | string | ` '' ` |
412
+ | ` height ` | The image height (in px) | No | integer | ` undefined ` |
413
+ | ` width ` | The image width (in px) | No | integer | ` undefined ` |
414
+
194
415
## Disabling bookmarks
195
416
196
417
Bookmarks can be disabled in order to avoid them to be displayed by adding the following line of JavaScript to your site.
0 commit comments