Changes for page Icon Picker

Last modified by Jan Bürger on 2025/05/06 12:29

From version 5.1
edited by Jan Bürger
on 2025/05/06 12:29
Change comment: Install extension [org.xwiki.platform:xwiki-platform-icon-ui/17.3.0]
To version 1.1
edited by admin
on 2024/02/20 17:47
Change comment: Install extension [org.xwiki.platform:xwiki-platform-icon-ui/16.0.0]

Summary

Details

Page properties
Author
... ... @@ -1,1 +1,1 @@
1 -XWiki.JanBurger
1 +XWiki.admin
Content
... ... @@ -1,28 +1,28 @@
1 1  {{velocity}}
2 2  ###########################
3 +## GLOBALS
4 +###########################
5 +#set($xwikiIcons = ['home', 'wiki', 'space', 'page', 'check', 'add', 'anchor', 'terminal', 'list', 'branch', 'down', 'up', 'left', 'right', 'arrows', 'repeat', 'undo', 'refresh', 'rotate-left', 'rotate-right', 'switch', 'random', 'attach', 'shopping-cart', 'bell', 'trash', 'bomb', 'book', 'cube', 'cubes', 'briefcase', 'bug', 'building', 'caret-down', 'caret-up', 'caret-right', 'calculator', 'calendar', 'camera', 'remove', 'cross', 'car', 'truck', 'chart-bar', 'chart-organisation', 'cloud', 'clock', 'cog', 'comment', 'comments', 'desktop', 'contrast', 'eject', 'step-forward', 'step-backward', 'fast-forward', 'backward', 'play', 'pause', 'stop', 'gamepad', 'credit-card', 'coffee', 'cut', 'database', 'delete', 'floppy-disk', 'glass', 'drive', 'envelope', 'warning', 'error', 'info', 'eye', 'rss', 'female', 'male', 'film', 'flag', 'search', 'search-plus', 'search-minus', 'folder', 'user', 'group', 'heart', 'question', 'image', 'key', 'keyboard', 'lightbulb', 'link', 'unlink', 'lock', 'unlock', 'money', 'dollar', 'euro', 'gbp', 'yen', 'music', 'file', 'file-white', 'file-pdf', 'file-code', 'file-archive', 'file-word', 'file-excel', 'file-powerpoint', 'file-text', 'paste', 'pencil', 'print', 'shield', 'certificate', 'volume-up', 'volume-down', 'volume-off', 'soccer', 'star', 'table', 'phone', 'font', 'bold', 'italic', 'strikethrough', 'subscript', 'superscript', 'underline', 'align-center', 'align-justify', 'align-left', 'align-right', 'columns', 'indent-left', 'indent-right', 'list-bullets', 'list-numbers', 'sun', 'world', 'wrench'])
6 +###########################
3 3  ## DATA: ICON THEMES
4 4  ###########################
5 -#if ($request.action == 'data_iconthemes')
6 - #set ($map = {})
7 - #set ($discard = $map.put('iconThemes', $services.icon.iconSetNames))
8 - #set ($discard = $map.put('currentIconTheme', $services.icon.currentIconSetName))
9 +#if($request.action == 'data_iconthemes')
10 + #set($map = {})
11 + #set($discard = $map.put('iconThemes', $services.icon.iconSetNames))
12 + #set($discard = $map.put('currentIconTheme', $services.icon.currentIconSetName))
9 9   #jsonResponse($map)
10 10  ###########################
11 11  ## DATA: ICONS
12 12  ###########################
13 -#elseif ($request.action == 'data_icons')
14 - #set ($icons = [])
15 - #set ($iconTheme = $request.iconTheme)
16 - #set ($xwikiIcons = $collectiontool.sort($services.icon.getIconNames($iconTheme)))
17 - #set ($iconNamePrefix = $request.query.toLowerCase())
18 - #foreach ($xwikiIcon in $xwikiIcons)
19 - #if ("$!iconNamePrefix" == '' || $xwikiIcon.startsWith($iconNamePrefix))
20 - #set ($discard = $icons.add({
21 - 'name': $xwikiIcon,
22 - 'render': $services.icon.renderHTML($xwikiIcon, $iconTheme),
23 - 'metadata': $services.icon.getMetaData($xwikiIcon, $iconTheme)
24 - }))
25 - #end
17 +#elseif($request.action == 'data_icons')
18 + #set($icons = [])
19 + #set($iconTheme = $request.iconTheme)
20 + #foreach($xwikiIcon in $xwikiIcons)
21 + #set($icon = {})
22 + #set($discard = $icon.put('name', $xwikiIcon))
23 + #set($discard = $icon.put('render', $services.icon.renderHTML($xwikiIcon, $iconTheme)))
24 + #set($discard = $icon.put('metadata', $services.icon.getMetaData($xwikiIcon, $iconTheme)))
25 + #set($discard = $icons.add($icon))
26 26   #end
27 27   #jsonResponse($icons)
28 28  #else
XWiki.JavaScriptExtension[0]
Code
... ... @@ -55,37 +55,23 @@
55 55   * Display the list of icons
56 56   */
57 57   var displayList = function(iconTheme) {
58 - // Filter the icons we display based on the value of the input field.
59 - let selectedIconName = '';
60 - if (currentInput.data('xwikiIconPickerSettings') !== '') {
61 - selectedIconName = currentInput[0].value.replace(currentInput.data('xwikiIconPickerSettings').prefix, '');
62 - }
63 63   // For each icon
64 64   for (var i=0; i < iconTheme.length; ++i) {
65 65   // Display the icon
66 - if (selectedIconName === '' || iconTheme[i].name.includes(selectedIconName)) {
67 - var displayer = $(document.createElement('button'));
68 - displayer.addClass('btn');
69 - iconListSection.append(displayer);
70 - displayer.addClass('xwikiIconPickerIcon');
71 - var imageDiv = $(document.createElement('p'));
72 - imageDiv.addClass('xwikiIconPickerIconImage').html(iconTheme[i].render);
73 - displayer.append(imageDiv);
74 - var iconNameSpan = $(document.createElement('p'));
75 - // Usually, the icon name is just one "word" in snakecase. e.g. arrow_refresh_small
76 - // We add Line Break Opportunity elements in the middle of this word so that it's cut into nice to read
77 - // substrings.
78 - let iconNameWithLineBreakOpportunities = iconTheme[i].name
79 - .replaceAll("-","<wbr/>-")
80 - .replaceAll("_","<wbr/>_");
81 - iconNameSpan.addClass('xwikiIconPickerIconName').html(iconNameWithLineBreakOpportunities);
82 - displayer.append(iconNameSpan);
83 - // Change the input value when the icon is clicked
84 - displayer.on('click', function(event) {
85 - currentInput.val(currentInput.data('xwikiIconPickerSettings').prefix + $(event.currentTarget).children('.xwikiIconPickerIconName').text());
86 - closePicker();
87 - });
88 - }
61 + var displayer = $(document.createElement('div'));
62 + iconListSection.append(displayer);
63 + displayer.addClass('xwikiIconPickerIcon');
64 + var imageDiv = $(document.createElement('div'));
65 + imageDiv.addClass('xwikiIconPickerIconImage').html(iconTheme[i].render);
66 + displayer.append(imageDiv);
67 + var iconNameDiv = $(document.createElement('div'));
68 + iconNameDiv.addClass('xwikiIconPickerIconName').text(iconTheme[i].name);
69 + displayer.append(iconNameDiv);
70 + // Change the input value when the icon is clicked
71 + displayer.on('click', function(event) {
72 + currentInput.val(currentInput.data('xwikiIconPickerSettings').prefix + $(event.currentTarget).children('.xwikiIconPickerIconName').text() );
73 + closePicker();
74 + });
89 89   }
90 90   }
91 91  
... ... @@ -93,7 +93,7 @@
93 93   * Load the icon list (get the JSON from the server) and display it afterwards
94 94   */
95 95   var loadIconList = function(iconTheme) {
96 - $.getJSON(getResourceURL('data_icons', 'iconTheme=' + iconTheme), function(dataIcons) {
82 + $.getJSON(getResourceURL('data_icons', 'iconTheme='+iconTheme), function(dataIcons) {
97 97   // Put the result in the icons map
98 98   icons[iconTheme] = dataIcons;
99 99   // Display the list
... ... @@ -201,7 +201,7 @@
201 201   }
202 202  
203 203   /**
204 - * Create the picker
190 + * Create the piccker
205 205   */
206 206   var createPicker = function (input) {
207 207   // If the picker already exists
... ... @@ -220,7 +220,7 @@
220 220   xwikiCurrentIconsPicker = $(document.createElement('div'));
221 221   xwikiCurrentIconsPicker.addClass('xwikiIconPickerContainer');
222 222   // Insert the picker in the DOM
223 - xwikiCurrentIconsPicker.insertAfter(currentInput);
209 + $(body).append(xwikiCurrentIconsPicker);
224 224   // Set the position
225 225   setPickerPosition();
226 226   // Add the icon list section
... ... @@ -256,32 +256,13 @@
256 256   loadIconList(currentIconTheme);
257 257   }
258 258   }
259 - var lastTimeout = 0;
260 - var reloadIconList = function () {
261 - // Remove all the displayed icons
262 - $('.xwikiIconPickerIcon').remove();
263 - // Display the new ones. We always reload because the filter results are unrelated.
264 - displayList(icons[currentIconTheme]);
265 - };
245 + // Close the picker when the user press 'escape'.
266 266   currentInput.on('keyup', function(event) {
267 - // Close the picker when the user press 'escape'.
268 268   // See: http://stackoverflow.com/questions/1160008/which-keycode-for-escape-key-with-jquery
269 269   if (event.which == 27) {
270 270   closePicker();
271 - } else {
272 - if (lastTimeout!==0) {
273 - clearTimeout(lastTimeout);
274 - }
275 - lastTimeout = setTimeout(reloadIconList, 500);
276 276   }
277 277   });
278 - iconThemeSelector.on('keyup', function(event) {
279 - // Close the picker when the user press 'escape'.
280 - // See: http://stackoverflow.com/questions/1160008/which-keycode-for-escape-key-with-jquery
281 - if (event.which == 27) {
282 - closePicker();
283 - }
284 - });
285 285   }
286 286  
287 287   /**
XWiki.StyleSheetExtension[0]
Code
... ... @@ -10,37 +10,22 @@
10 10  }
11 11  
12 12  .xwikiIconPickerList {
13 - display: grid;
14 - max-width: 100%;
15 - height: 240px;
16 16   overflow-y: scroll;
17 - gap: .3em;
18 - padding: .3em;
19 - /* 4 columns, each a fraction of the whole width */
20 - grid-template-columns: repeat(4, 1fr);
14 + height: 240px;
21 21  }
22 22  
23 -/* Avoid stretching on the Loader element. */
24 -.xwikiIconPickerList > img {
25 - object-fit: contain;
26 -}
27 -
28 28  .xwikiIconPickerIcon {
29 - display: flex;
30 - flex-direction: column;
31 - margin: 0;
32 - padding: 0;
18 + float: left;
19 + height: 80px;
20 + width: 100px;
33 33   text-align: center;
34 34   border-radius: 7px;
35 35   vertical-align: middle;
24 + overflow: hidden;
25 + padding: 10px;
36 36   cursor: pointer;
37 - background-color: transparent;
38 38  }
39 39  
40 -.xwikiIconPickerIcon * {
41 - padding: 0;
42 -}
43 -
44 44  .xwikiIconPickerIcon:hover {
45 45   background-color: $theme.highlightColor;
46 46  }
... ... @@ -47,7 +47,6 @@
47 47  
48 48  .xwikiIconPickerIconImage {
49 49   font-size: 24px;
50 - line-height: 1;
51 51   margin: 0;
52 52  }
53 53  
... ... @@ -55,12 +55,6 @@
55 55   width: 24px;
56 56  }
57 57  
58 -.xwikiIconPickerIcon .xwikiIconPickerIconName {
59 - /* Make sure the name wraps onto multiple lines instead of overflowing. */
60 - white-space: pre-wrap;
61 - word-break: break-word;
62 -}
63 -
64 64  .xwikiIconPickerIconThemeSelector {
65 65   width: 100%;
66 66   background-color: $theme.menuBackgroundColor;