@refinitiv-ui/efx-grid 6.0.55 → 6.0.57

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. package/lib/column-selection-dialog/lib/column-selection-dialog.d.ts +7 -2
  2. package/lib/column-selection-dialog/lib/column-selection-dialog.js +340 -44
  3. package/lib/column-selection-dialog/lib/locale/translation-de.js +1 -1
  4. package/lib/column-selection-dialog/lib/locale/translation-en.js +1 -1
  5. package/lib/column-selection-dialog/lib/locale/translation-ja.js +1 -1
  6. package/lib/column-selection-dialog/lib/locale/translation-zh-hant.js +1 -1
  7. package/lib/column-selection-dialog/lib/locale/translation-zh.js +1 -1
  8. package/lib/column-selection-dialog/themes/base.less +10 -0
  9. package/lib/column-selection-dialog/themes/elemental/dark/column-selection-dialog.js +1 -1
  10. package/lib/column-selection-dialog/themes/elemental/dark/es5/all-elements.js +1 -1
  11. package/lib/column-selection-dialog/themes/elemental/dark.js +3 -1
  12. package/lib/column-selection-dialog/themes/elemental/light/column-selection-dialog.js +1 -1
  13. package/lib/column-selection-dialog/themes/elemental/light/es5/all-elements.js +1 -1
  14. package/lib/column-selection-dialog/themes/elemental/light.js +3 -1
  15. package/lib/column-selection-dialog/themes/halo/dark/column-selection-dialog.js +1 -1
  16. package/lib/column-selection-dialog/themes/halo/dark/es5/all-elements.js +1 -1
  17. package/lib/column-selection-dialog/themes/halo/dark.js +3 -1
  18. package/lib/column-selection-dialog/themes/halo/light/column-selection-dialog.js +1 -1
  19. package/lib/column-selection-dialog/themes/halo/light/es5/all-elements.js +1 -1
  20. package/lib/column-selection-dialog/themes/halo/light.js +3 -1
  21. package/lib/column-selection-dialog/themes/solar/charcoal/column-selection-dialog.js +1 -1
  22. package/lib/column-selection-dialog/themes/solar/charcoal/es5/all-elements.js +1 -1
  23. package/lib/column-selection-dialog/themes/solar/charcoal.js +3 -1
  24. package/lib/column-selection-dialog/themes/solar/pearl/column-selection-dialog.js +1 -1
  25. package/lib/column-selection-dialog/themes/solar/pearl/es5/all-elements.js +1 -1
  26. package/lib/column-selection-dialog/themes/solar/pearl.js +3 -1
  27. package/lib/grid/index.js +1 -1
  28. package/lib/grid/themes/halo/dark/efx-grid.js +1 -1
  29. package/lib/grid/themes/halo/dark/es5/all-elements.js +1 -1
  30. package/lib/grid/themes/halo/light/efx-grid.js +1 -1
  31. package/lib/grid/themes/halo/light/es5/all-elements.js +1 -1
  32. package/lib/grid/themes/solar/charcoal/efx-grid.js +1 -1
  33. package/lib/grid/themes/solar/charcoal/es5/all-elements.js +1 -1
  34. package/lib/grid/themes/solar/pearl/efx-grid.js +1 -1
  35. package/lib/grid/themes/solar/pearl/es5/all-elements.js +1 -1
  36. package/lib/tr-grid-printer/es6/index.js +1 -1
  37. package/lib/versions.json +1 -1
  38. package/package.json +1 -1
@@ -5,10 +5,12 @@ import "@refinitiv-ui/elements/button";
5
5
  import { TreeRenderer as DefaultRenderer } from "@refinitiv-ui/elements/tree";
6
6
  import "@refinitiv-ui/elements/dialog";
7
7
  import "@refinitiv-ui/elements/search-field";
8
+ import "@refinitiv-ui/elements/pill";
9
+ import "@refinitiv-ui/elements/item";
8
10
  import translation from "./locale/translation.js";
9
11
  import ElementObserver from "../../tr-grid-util/es6/ElementObserver.js";
10
12
  import { ElfUtil } from "../../tr-grid-util/es6/ElfUtil.js";
11
- import { injectCss, prettifyCss } from "../../tr-grid-util/es6/Util.js";
13
+ import { injectCss, prettifyCss, isEmptyObject } from "../../tr-grid-util/es6/Util.js";
12
14
 
13
15
  declare namespace ColumnSelectionDialog {
14
16
 
@@ -26,7 +28,10 @@ declare namespace ColumnSelectionDialog {
26
28
  middleSeparator?: string|null,
27
29
  collapseAll?: boolean|null,
28
30
  width?: number|null,
29
- height?: number|null
31
+ height?: number|null,
32
+ tags?: (string)[]|null,
33
+ infoTooltip?: string|null,
34
+ searchPlaceholder?: string|null
30
35
  };
31
36
 
32
37
  }
@@ -4,10 +4,12 @@ import "@refinitiv-ui/elements/button";
4
4
  import { TreeRenderer as DefaultRenderer } from "@refinitiv-ui/elements/tree";
5
5
  import "@refinitiv-ui/elements/dialog";
6
6
  import "@refinitiv-ui/elements/search-field";
7
+ import "@refinitiv-ui/elements/pill";
8
+ import "@refinitiv-ui/elements/item";
7
9
  import translation from "./locale/translation.js";
8
10
  import ElementObserver from "../../tr-grid-util/es6/ElementObserver.js";
9
11
  import { ElfUtil } from "../../tr-grid-util/es6/ElfUtil.js";
10
- import { injectCss, prettifyCss } from "../../tr-grid-util/es6/Util.js";
12
+ import { injectCss, prettifyCss, isEmptyObject } from "../../tr-grid-util/es6/Util.js";
11
13
 
12
14
  /**
13
15
  * @typedef {Object} ColumnSelectionDialog~Config
@@ -25,6 +27,9 @@ import { injectCss, prettifyCss } from "../../tr-grid-util/es6/Util.js";
25
27
  * @property {boolean=} collapseAll=false Default collapse property applies to all groups
26
28
  * @property {number=} width Specify width of the dialog, with the minimum width of 490px
27
29
  * @property {number=} height Specify height of the dialog
30
+ * @property {Array.<string>=} tags=null All available tags for filtering
31
+ * @property {string=} infoTooltip="" If specified, an informational icon will appear on the top with the given text as its tooltip
32
+ * @property {string=} searchPlaceholder="Search" Placeholder text inside the search input.
28
33
  */
29
34
 
30
35
  /** Insert multiple items to the given array. This is an in-place modification.
@@ -88,37 +93,35 @@ const isEnabledItem = function (item) {
88
93
  return (item && !item.disabled) ? true : false;
89
94
  };
90
95
 
91
- /** search item label contain specific text
96
+
97
+ /** Recursively search through tree structures of items
92
98
  * @private
93
99
  * @function
94
- * @param {Array} items
95
- * @param {string} keyword keyword in lower case
96
- * @return {Array}
100
+ * @param {!Array} items
101
+ * @param {string|Array.<string>} input User input that has been validated
102
+ * @param {!Function} matchingLogic
103
+ * @return {!Array}
97
104
  */
98
- const filterSearch = function (items, keyword) {
99
- var c = items.length;
100
- if (c === 0 || !keyword) return items;
101
-
102
- var filtered = [];
103
- for (var i = 0; i < c; i++) {
105
+ const _recursivelySearch = function (items, input, matchingLogic) {
106
+ var results = [];
107
+ var itemCount = items ? items.length : 0;
108
+ for (var i = 0; i < itemCount; i++) {
104
109
  var item = items[i];
105
110
  if (item.items) {
106
- var result = filterSearch(item.items, keyword);
111
+ var result = _recursivelySearch(item.items, input, matchingLogic);
107
112
  if (result.length > 0) {
108
113
  item = Object.assign({}, item); // for header - clone new object to prevent mutate original
109
114
  item.items = result;
110
- filtered.push(item);
115
+ results.push(item);
111
116
  }
112
- } else if (item.label.toLowerCase().includes(keyword)) {
113
- filtered.push(item);
117
+ } else if (matchingLogic(item, input)) {
118
+ results.push(item);
114
119
  }
115
120
  }
116
121
 
117
- return filtered;
122
+ return results;
118
123
  };
119
124
 
120
-
121
-
122
125
  /** @private
123
126
  * @function
124
127
  * @param {Object} item
@@ -293,7 +296,9 @@ const _toCoralTreeItem = function (colObj, parent, defaultExpanded) {
293
296
  value: currentId,
294
297
  selected: false,
295
298
  disabled: colObj.disabled == true,
296
- stationary: colObj.stationary == true
299
+ stationary: colObj.stationary == true,
300
+ lowerCase: label.toLowerCase(),
301
+ tags: _toTagList(colObj.tags)
297
302
  };
298
303
  }
299
304
  };
@@ -301,7 +306,7 @@ const _toCoralTreeItem = function (colObj, parent, defaultExpanded) {
301
306
  /** Coral item requires label and value. So we need to convert column object to coral item
302
307
  * @private
303
308
  * @param {Object} item
304
- * @return {Object}
309
+ * @return {!Object}
305
310
  */
306
311
  const _toCoralItem = function(item) {
307
312
  return {
@@ -309,7 +314,9 @@ const _toCoralItem = function(item) {
309
314
  value: item.value,
310
315
  selected: false,
311
316
  disabled: item.disabled,
312
- stationary: item.stationary
317
+ stationary: item.stationary,
318
+ lowerCase: item.label.toLowerCase(),
319
+ tags: _toTagList(item.tags)
313
320
  };
314
321
  };
315
322
  /** Valid item must have an id or a field
@@ -450,7 +457,7 @@ const _countAutoGenerated = function (items) {
450
457
  * @private
451
458
  * @param {Array} items
452
459
  * @param {Array} visibleList
453
- * @return {Array}
460
+ * @return {!Array}
454
461
  */
455
462
  const _getVisibleItems = function (items, visibleList) {
456
463
  visibleList = visibleList || [];
@@ -470,6 +477,71 @@ const _getVisibleItems = function (items, visibleList) {
470
477
  return visibleList;
471
478
  };
472
479
 
480
+ /** Tag value will be used for searching and matching
481
+ * @private
482
+ * @param {string} tag
483
+ * @param {number} idx
484
+ * @return {!Object}
485
+ */
486
+ const _toTagDefinition = function(tag, idx) {
487
+ var tagKeyword = tag.toLowerCase(); // For searching and filtering
488
+
489
+ var tagPill = document.createElement("ef-pill");
490
+ tagPill._keyword = tagKeyword;
491
+ tagPill._tagIndex = idx;
492
+
493
+ tagPill.textContent = tag;
494
+ tagPill.setAttribute("clears", "");
495
+
496
+ return {
497
+ label: tag,
498
+ value: tagKeyword,
499
+ element: tagPill
500
+ };
501
+ };
502
+ /**
503
+ * @private
504
+ * @param {string} str
505
+ * @return {!Object}
506
+ */
507
+ const _toLowerCase = function(str) {
508
+ return str ? str.toLowerCase() : "";
509
+ };
510
+ /** Tag value will be used for searching and matching
511
+ * @private
512
+ * @param {string|Array} tag
513
+ * @return {Array.<string>}
514
+ */
515
+ const _toTagList = function(tag) {
516
+ if(tag) {
517
+ if(Array.isArray(tag)) {
518
+ return tag.map(_toLowerCase);
519
+ } else {
520
+ if(typeof tag !== "string") {
521
+ tag = tag + "";
522
+ }
523
+ return [tag.toLowerCase()];
524
+ }
525
+ }
526
+ return null;
527
+ };
528
+ /** @type {Object.<number, number>}
529
+ * @private
530
+ */
531
+ const NON_CHAR_KEYS = {
532
+ 9: 1, // TAB
533
+ 13: 1, // ENTER
534
+ 16: 1, // SHIFT
535
+ 17: 1, // CTRL
536
+ 18: 1, // ALT
537
+ 35: 1, // END
538
+ 36: 1, // HOME
539
+ 37: 1, // LEFT
540
+ 38: 1, // UP
541
+ 39: 1, // RIGHT
542
+ 40: 1 // DOWN
543
+ };
544
+
473
545
  /**
474
546
  * @class
475
547
  * @public
@@ -502,9 +574,13 @@ class ColumnSelectionDialog extends BasicElement {
502
574
  this._pendingTreeRefresh = false;
503
575
  this._pendingResetSearchInput = false;
504
576
  this._middleSeparator = "";
577
+ this._defaultExpanded = true;
505
578
  this._width = 0;
506
579
  this._height = 0;
507
- this._defaultExpanded = true;
580
+ this._tagDefs = null;
581
+ this._activeTags = null;
582
+ this._infoTooltip = "";
583
+ this._searchPlaceholder = "";
508
584
 
509
585
  this._allItemMapping = {};
510
586
  this._filterItemMapping = {};
@@ -521,7 +597,8 @@ class ColumnSelectionDialog extends BasicElement {
521
597
  this._treeValueChanged = this._treeValueChanged.bind(this);
522
598
  this._treeExpandedChanged = this._treeExpandedChanged.bind(this);
523
599
  this._removeBtnClicked = this._removeBtnClicked.bind(this);
524
- this._onSearchInputChanged = this._onSearchInputChanged.bind(this);
600
+ this._onSearchInputKeyDown = this._onSearchInputKeyDown.bind(this);
601
+ this._onSearchInputKeyUp = this._onSearchInputKeyUp.bind(this);
525
602
  this._restoreDefault = this._restoreDefault.bind(this);
526
603
  this._onConfirm = this._onConfirm.bind(this);
527
604
  this._onCancel = this._onCancel.bind(this);
@@ -538,6 +615,9 @@ class ColumnSelectionDialog extends BasicElement {
538
615
  this._handleClick = this._handleClick.bind(this);
539
616
  this._createTreeCustomRender = this._createTreeCustomRender.bind(this);
540
617
  this._selectAllCheckedChanged = this._selectAllCheckedChanged.bind(this);
618
+
619
+ this._advancedMatching = this._advancedMatching.bind(this);
620
+ this._onClearingTagPill = this._onClearingTagPill.bind(this);
541
621
  ElementObserver.addLanguageListener(this);
542
622
  }
543
623
 
@@ -600,6 +680,25 @@ class ColumnSelectionDialog extends BasicElement {
600
680
  } else {
601
681
  this._height = 0;
602
682
  }
683
+ var userTags = this.config.tags;
684
+ if (userTags != null) {
685
+ this._activeTags = null; // All existing active tags must be removed
686
+ if(Array.isArray(userTags) && userTags.length) {
687
+ this._tagDefs = userTags.map(_toTagDefinition);
688
+ var tagCount = this._tagDefs.length;
689
+ for(var i = 0; i < tagCount; ++i) {
690
+ this._tagDefs[i].element.addEventListener("clear", this._onClearingTagPill);
691
+ }
692
+ } else {
693
+ this._tagDefs = null;
694
+ }
695
+ }
696
+ if(this.config.infoTooltip != null) {
697
+ this._infoTooltip = this.config.infoTooltip ? this.config.infoTooltip : "";
698
+ }
699
+ if(this.config.searchPlaceholder != null) {
700
+ this._searchPlaceholder = this.config.searchPlaceholder ? this.config.searchPlaceholder : "";
701
+ }
603
702
 
604
703
  this._defaultItems = this.config.defaultItems;
605
704
  }
@@ -630,15 +729,14 @@ class ColumnSelectionDialog extends BasicElement {
630
729
  <div class="container">
631
730
  <div class="row">
632
731
  <div class="side">
633
- <label class="title">${t["Add / Remove Columns"]}</label>
634
- </div>
635
- <div class="side">
636
- </---to keep layout--->
732
+ <label class="title">${t["Add / Remove Columns"]}
733
+ <ef-icon icon="info" id="info_icon" title="${this._infoTooltip}"></ef-icon></label>
637
734
  </div>
735
+ <div class="side"></div>
638
736
  </div>
639
737
  <div class="row">
640
738
  <div class="side">
641
- <ef-search-field placeholder="${t["Search"]}" id="searchInput"></ef-search-field>
739
+ <ef-search-field placeholder="${this._searchPlaceholder ? this._searchPlaceholder : t["Search"]}" id="searchInput"></ef-search-field>
642
740
  </div>
643
741
  <div class="side">
644
742
  <label>${t["Show in this order"]}</label>
@@ -646,6 +744,7 @@ class ColumnSelectionDialog extends BasicElement {
646
744
  </div>
647
745
  <div class="row" id='listSection'>
648
746
  <div class="side" id="allColumnsSide">
747
+ <div id="tags_div"></div>
649
748
  <div id="allColumns">
650
749
  <ef-item id="treeNoResult" class="no-results" label="${t["No results found"]}"></ef-item>
651
750
  <ef-header level="1" id="selectAllHeader">
@@ -705,13 +804,16 @@ class ColumnSelectionDialog extends BasicElement {
705
804
  this._columnDialog = shadowRoot.getElementById('columnDialog');
706
805
  this._upItem = shadowRoot.getElementById('upItem');
707
806
  this._downItem = shadowRoot.getElementById('downItem');
708
- this._visibleColumnsContainer = this.shadowRoot.getElementById('visibleColumns');
709
- this._treeContainer = this.shadowRoot.getElementById('treeContainer');
710
- this._descriptionContainer = this.shadowRoot.getElementById('descriptionContainer');
807
+ this._visibleColumnsContainer = shadowRoot.getElementById('visibleColumns');
808
+ this._treeContainer = shadowRoot.getElementById('treeContainer');
809
+ this._descriptionContainer = shadowRoot.getElementById('descriptionContainer');
810
+ this._tagsDiv = shadowRoot.getElementById('tags_div');
811
+ this._infoIcon = shadowRoot.getElementById('info_icon');
711
812
 
712
813
  this._tree.addEventListener('value-changed', this._treeValueChanged);
713
814
  this._tree.addEventListener('expanded-changed', this._treeExpandedChanged);
714
- this._searchInput.addEventListener('keyup', this._onSearchInputChanged);
815
+ this._searchInput.addEventListener('keydown', this._onSearchInputKeyDown);
816
+ this._searchInput.addEventListener('keyup', this._onSearchInputKeyUp);
715
817
  this._columnDialog.addEventListener('cancel', this._onCancel);
716
818
  this._selectAllCheckbox.addEventListener('checked-changed', this._selectAllCheckedChanged);
717
819
  this._selectAllHeader.addEventListener('click', this._handleSelectAllHeaderClick);
@@ -791,7 +893,7 @@ class ColumnSelectionDialog extends BasicElement {
791
893
  if (this._pendingResetSearchInput) {
792
894
  this._pendingResetSearchInput = false;
793
895
  this._searchInput.value = '';
794
- this._updateSearchResult(this._searchInput.value);
896
+ this._updateSearchResult(this._searchInput.value); // TODO: Use empty string instead. This also trigger requestUpdate again
795
897
  }
796
898
 
797
899
  if(this._pendingScroll) {
@@ -816,6 +918,34 @@ class ColumnSelectionDialog extends BasicElement {
816
918
  this._columnDialog.style.width = this._width ? this._width + "px" : "";
817
919
 
818
920
  this._descriptionContainer.toggleAttribute('hide', !this._descriptionBox);
921
+
922
+ var activeTags = this._activeTags;
923
+ if(activeTags) {
924
+ var tagDefs = this._tagDefs;
925
+ var tagCount = tagDefs.length;
926
+ var tagDef;
927
+ for(var i = 0; i < tagCount; ++i) {
928
+ tagDef = tagDefs[i];
929
+ if(!activeTags[tagDef.value]) {
930
+ var pn = tagDef.element.parentNode;
931
+ if(pn){
932
+ pn.removeChild(tagDef.element);
933
+ }
934
+ }
935
+ }
936
+ for(var tagKeyword in activeTags) {
937
+ tagDef = tagDefs[activeTags[tagKeyword]];
938
+ if(tagDef) {
939
+ this._tagsDiv.appendChild(tagDef.element);
940
+ }
941
+ }
942
+ } else {
943
+ while(this._tagsDiv.lastChild) {
944
+ this._tagsDiv.removeChild(this._tagsDiv.lastChild);
945
+ }
946
+ }
947
+
948
+ this._infoIcon.style.display = this._infoTooltip ? "" : "none";
819
949
  }
820
950
 
821
951
  /**
@@ -836,6 +966,7 @@ class ColumnSelectionDialog extends BasicElement {
836
966
  var config = this.config || {};
837
967
  var visibleItems = this.visibleItems;
838
968
  var defaultItems = this._defaultItems;
969
+ this._activeTags = null; // Data has been changed, so all existing active tags must be removed
839
970
 
840
971
  if (this.data) {
841
972
  allItems = this.data;
@@ -1170,34 +1301,199 @@ class ColumnSelectionDialog extends BasicElement {
1170
1301
  this._moveVisibleColumnsElement(_getSelectedItemIndexes(this._visibleColumnList), 'Down');
1171
1302
  }
1172
1303
 
1173
- /**
1174
- * Set filtering result to "searchResult" element
1175
- * @private
1176
- * @param {object} e - event object
1177
- */
1178
- _onSearchInputChanged(e) {
1304
+ /** @private
1305
+ * @param {Event} e
1306
+ */
1307
+ _onSearchInputKeyDown(e) {
1308
+ var keyCode = e.keyCode;
1309
+ if(keyCode !== 9) { // Tab key
1310
+ return;
1311
+ }
1312
+ if(!this._tagDefs) {
1313
+ return;
1314
+ }
1315
+ // Advanced search mode
1316
+ e.stopPropagation();
1317
+ e.preventDefault();
1318
+ var str = e.currentTarget.value;
1319
+ str = str.trim().toLowerCase();
1320
+ var tagCount = this._tagDefs.length;
1321
+ for(var i = 0; i < tagCount; ++i) {
1322
+ var tagDef = this._tagDefs[i];
1323
+ var tagKeyword = tagDef.value;
1324
+ if(tagKeyword.indexOf(str) >= 0) {
1325
+ if(this._addTagPill(tagKeyword, i)) {
1326
+ this._searchInput.value = "";
1327
+ this._updateSearchResult("");
1328
+ break;
1329
+ }
1330
+ }
1331
+ }
1332
+ }
1333
+ /** @private
1334
+ * @param {Event} e
1335
+ */
1336
+ _onSearchInputKeyUp(e) {
1337
+ var keyCode = e.keyCode;
1338
+ if(NON_CHAR_KEYS[keyCode]) {
1339
+ // No search should be changed by any of these key codes (e.g., enter, esc, tab, shift, ctrl, arrow keys)
1340
+ return;
1341
+ }
1342
+
1179
1343
  var firstItem = this._searchInput.data && this._searchInput.data[0];
1180
1344
  if (firstItem) {
1181
- this._searchInput.scrollToItem(firstItem);
1345
+ this._searchInput.scrollToItem(firstItem); // Scroll to top
1182
1346
  }
1347
+
1183
1348
  this._updateSearchResult(e.target.value);
1184
1349
  }
1185
1350
 
1351
+ /** @private
1352
+ * @param {string} tagKeyword String for searching and filtering
1353
+ * @param {number|string} id For refering back to tag definitions
1354
+ * @return {boolean} Returns true if there is any change
1355
+ */
1356
+ _addTagPill(tagKeyword, id) {
1357
+ if(this._activeTags) {
1358
+ if(this._activeTags[tagKeyword]) {
1359
+ return false;
1360
+ }
1361
+ } else {
1362
+ this._activeTags = {};
1363
+ }
1364
+ this._activeTags[tagKeyword] = id != null ? id + "" : "-1";
1365
+ return true;
1366
+ }
1367
+ /** @private
1368
+ * @param {string} tagKeyword
1369
+ * @return {boolean} Returns true if there is any change
1370
+ */
1371
+ _removeTagPill(tagKeyword) {
1372
+ if(!this._activeTags) {
1373
+ return false;
1374
+ }
1375
+ if(!this._activeTags[tagKeyword]) {
1376
+ return false;
1377
+ }
1378
+
1379
+ delete this._activeTags[tagKeyword];
1380
+ if(isEmptyObject(this._activeTags)) {
1381
+ this._activeTags = null;
1382
+ }
1383
+ return true;
1384
+ }
1385
+ /** @private
1386
+ * @return {boolean} Returns true if there is any change
1387
+ */
1388
+ _removeAllTagPills() {
1389
+ if(!this._activeTags) {
1390
+ return false;
1391
+ }
1392
+ this._activeTags = null;
1393
+ return true;
1394
+ }
1395
+ /** @private
1396
+ * @param {Event} e
1397
+ */
1398
+ _onClearingTagPill(e) {
1399
+ var tagPill = e.currentTarget;
1400
+ if(this._removeTagPill(tagPill._keyword)) {
1401
+ this._updateSearchResult();
1402
+ }
1403
+ }
1404
+
1405
+ /** @private
1406
+ * @function
1407
+ * @param {Object} item
1408
+ * @param {string} keyword
1409
+ * @return {boolean}
1410
+ */
1411
+ _simpleMatching(item, keyword) {
1412
+ if(item.lowerCase) {
1413
+ return item.lowerCase.includes(keyword);
1414
+ } else {
1415
+ return false;
1416
+ }
1417
+ }
1418
+ /** @private
1419
+ * @function
1420
+ * @param {Object} item
1421
+ * @param {Array.<string>} keywords
1422
+ * @return {boolean}
1423
+ */
1424
+ _advancedMatching(item, keywords) {
1425
+ if(this._activeTags) {
1426
+ var tags = item.tags;
1427
+ var tagCount = tags ? tags.length : 0;
1428
+ var tagMatched = false;
1429
+ for(var i = 0; i < tagCount; ++i) {
1430
+ if(this._activeTags[tags[i]]) {
1431
+ tagMatched = true;
1432
+ break;
1433
+ }
1434
+ }
1435
+
1436
+ if(!tagMatched) {
1437
+ return false;
1438
+ }
1439
+ }
1440
+
1441
+ var lowerCase = item.lowerCase;
1442
+ if(!lowerCase) {
1443
+ return false;
1444
+ }
1445
+
1446
+ var wordCount = keywords.length;
1447
+ for(var j = 0; j < wordCount; ++j) {
1448
+ if(!lowerCase.includes(keywords[j])) {
1449
+ return false;
1450
+ }
1451
+ }
1452
+ return true;
1453
+ }
1454
+
1455
+ /** Search through tree structures of items
1456
+ * @private
1457
+ * @function
1458
+ * @param {Array} items
1459
+ * @param {string} keyword Keyword
1460
+ * @return {Array}
1461
+ */
1462
+ _filterSearch(items, keyword) {
1463
+ if(!keyword && !this._activeTags) {
1464
+ return items;
1465
+ }
1466
+ var itemCount = items.length;
1467
+ if(!itemCount) {
1468
+ return items;
1469
+ }
1470
+
1471
+ keyword = keyword.toLowerCase();
1472
+ if(this._tagDefs) {
1473
+ var keywords = keyword.split(/ +/);
1474
+ return _recursivelySearch(items, keywords, this._advancedMatching);
1475
+ }
1476
+
1477
+ return _recursivelySearch(items, keyword, this._simpleMatching);
1478
+ }
1479
+
1186
1480
  /**
1187
1481
  * @private
1188
1482
  * @param {string} value - search query
1189
1483
  */
1190
1484
  _updateSearchResult(value) {
1191
- if(!value) {
1485
+ var keyword = value ? value.trim() : "";
1486
+ if(!keyword && !this._activeTags) {
1192
1487
  this._filteredColumnList = this._allColumnList;
1193
1488
  this._filterItemMapping = this._allItemMapping;
1194
1489
  } else {
1195
- this._filteredColumnList = filterSearch(this._allColumnList, value.toLocaleLowerCase());
1490
+ // TODO: Avoid filter for the same active keyword
1491
+ this._filteredColumnList = this._filterSearch(this._allColumnList, keyword);
1196
1492
  this._filterItemMapping = _createMapping(this._filteredColumnList, 'value');
1197
1493
  }
1198
1494
 
1495
+ // TODO: Avoid unnecessary update
1199
1496
  this._pendingTreeRefresh = true;
1200
-
1201
1497
  this.requestUpdate();
1202
1498
  }
1203
1499
 
@@ -16,4 +16,4 @@ var translationDe = {
16
16
  "CANCEL": "ABBRECHEN"
17
17
  };
18
18
 
19
- export default translationDe;
19
+ export default translationDe;
@@ -16,4 +16,4 @@ var translationEn = {
16
16
  "CANCEL": "CANCEL"
17
17
  };
18
18
 
19
- export default translationEn;
19
+ export default translationEn;
@@ -16,4 +16,4 @@ var translationJa = {
16
16
  "CANCEL": "キャンセル"
17
17
  };
18
18
 
19
- export default translationJa;
19
+ export default translationJa;
@@ -16,4 +16,4 @@ var translationZhHant = {
16
16
  "CANCEL": "取消"
17
17
  };
18
18
 
19
- export default translationZhHant;
19
+ export default translationZhHant;
@@ -16,4 +16,4 @@ var translationZh = {
16
16
  "CANCEL": "取消"
17
17
  };
18
18
 
19
- export default translationZh;
19
+ export default translationZh;
@@ -105,6 +105,16 @@
105
105
  height: 100%;
106
106
  overflow: hidden;
107
107
  }
108
+
109
+ #info_icon {
110
+ vertical-align: top;
111
+ font-size: 14px;
112
+ }
113
+
114
+ #tags_div > * {
115
+ margin-right: 5px;
116
+ margin-bottom: 10px;
117
+ }
108
118
 
109
119
  #allColumns {
110
120
  overflow: hidden;
@@ -1,4 +1,4 @@
1
1
  import "./imports/native-elements.js";
2
2
 
3
3
 
4
- dispatchEvent(new CustomEvent('ef.customStyles.define', { detail: { name: 'column-selection-dialog', styles: ':host{background:#535de8;display:inline-block;height:0;width:0}:host *{margin:0}:host [hide]{display:none}:host div{box-sizing:border-box}:host ef-item.disabled{color:rgba(184,189,199,.5)}:host ef-item[focused] ef-checkbox{color:#b7bcc6}:host ef-item::part(center){white-space:normal}:host .title{line-height:14px}:host ef-dialog{width:700px;height:500px;min-width:490px}:host ef-tree{width:100%}:host ef-tree-item{min-width:100%}:host .container{height:100%;display:flex;flex-direction:column}:host .row{display:flex}:host .row+.row{margin-top:10px}:host .side{width:50%;max-width:50%;display:flex;flex-direction:column;vertical-align:top;overflow:hidden;align-self:center;padding-left:5px;padding-right:5px;justify-content:center}:host .side:first-child{padding-left:0}:host .side:last-child{padding-right:0}:host #listSection{height:100%;overflow:hidden}:host #allColumns{overflow:hidden;border:1px solid #3e444f;display:flex;flex-direction:column;flex-grow:1}:host #allColumnsSide,:host #visibleSide{height:100%}:host #visibleColumns{flex-grow:1;overflow-y:auto;border:1px solid #3e444f}:host #searchInput{width:100%}:host .no-results{pointer-events:none;text-align:center;margin-top:10px}:host #orderChangePanel{display:flex;text-align:center;margin-top:10px;justify-content:space-between}:host #orderChangePanel>*+*{margin-left:10px}:host #moveButtons>*+:not(:first-child){margin-left:10px}:host #descriptionContainer{margin-top:10px;min-height:60px;overflow-y:auto;border:1px solid #3e444f;font-size:12px;line-height:18px;box-sizing:border-box;padding:3px 10px}:host #selectAllHeader{min-height:28px;text-transform:none;cursor:pointer}:host #selectAllHeader #selectAllCheckbox{pointer-events:none}:host [slot=footer]{display:flex;justify-content:space-between}:host [slot=footer]>div{display:inline-flex;align-items:center;height:40px;padding-left:15px;padding-right:15px}:host [slot=footer]>div ef-button{text-transform:uppercase;margin-top:0;margin-bottom:0}:host [slot=footer]>div ef-button+ef-button{margin-left:15px}::-webkit-scrollbar{width:15px;height:15px}::-webkit-scrollbar-button{background:0 0/1px 2px no-repeat #21242a;height:15px;width:15px;display:block}::-webkit-scrollbar-thumb{background:#3e444f;border-radius:8px;border:2px solid #21242a}::-webkit-scrollbar-thumb:hover{background:#b7bcc6}::-webkit-scrollbar-thumb:active{background:#707a8e}::-webkit-scrollbar-track{background:#21242a}::-webkit-scrollbar-corner{background:#21242a}::-webkit-scrollbar-button:end:decrement,::-webkit-scrollbar-button:start:increment{display:none}::-webkit-scrollbar-button:horizontal{background-size:2px 1px}::-webkit-scrollbar-button:vertical:start:decrement{background-image:linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f);background-position:12px 8.5px,11px 7.5px,10px 6.5px,9px 5.5px,8px 4.5px,7px 3.5px,6px 4.5px,5px 5.5px,4px 6.5px,3px 7.5px,2px 8.5px}::-webkit-scrollbar-button:vertical:start:decrement:hover{background-image:linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6);background-position:12px 8.5px,11px 7.5px,10px 6.5px,9px 5.5px,8px 4.5px,7px 3.5px,6px 4.5px,5px 5.5px,4px 6.5px,3px 7.5px,2px 8.5px}::-webkit-scrollbar-button:vertical:start:decrement:active{background-image:linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e);background-position:12px 8.5px,11px 7.5px,10px 6.5px,9px 5.5px,8px 4.5px,7px 3.5px,6px 4.5px,5px 5.5px,4px 6.5px,3px 7.5px,2px 8.5px}::-webkit-scrollbar-button:vertical:end:increment{background-image:linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f);background-position:12px 4.5px,11px 5.5px,10px 6.5px,9px 7.5px,8px 8.5px,7px 9.5px,6px 8.5px,5px 7.5px,4px 6.5px,3px 5.5px,2px 4.5px}::-webkit-scrollbar-button:vertical:end:increment:hover{background-image:linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6);background-position:12px 4.5px,11px 5.5px,10px 6.5px,9px 7.5px,8px 8.5px,7px 9.5px,6px 8.5px,5px 7.5px,4px 6.5px,3px 5.5px,2px 4.5px}::-webkit-scrollbar-button:vertical:end:increment:active{background-image:linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e);background-position:12px 4.5px,11px 5.5px,10px 6.5px,9px 7.5px,8px 8.5px,7px 9.5px,6px 8.5px,5px 7.5px,4px 6.5px,3px 5.5px,2px 4.5px}::-webkit-scrollbar-button:horizontal:start:decrement{background-image:linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f);background-position:8.5px 12px,7.5px 11px,6.5px 10px,5.5px 9px,4.5px 8px,3.5px 7px,4.5px 6px,5.5px 5px,6.5px 4px,7.5px 3px,8.5px 2px}::-webkit-scrollbar-button:horizontal:start:decrement:hover{background-image:linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6);background-position:8.5px 12px,7.5px 11px,6.5px 10px,5.5px 9px,4.5px 8px,3.5px 7px,4.5px 6px,5.5px 5px,6.5px 4px,7.5px 3px,8.5px 2px}::-webkit-scrollbar-button:horizontal:start:decrement:active{background-image:linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e);background-position:8.5px 12px,7.5px 11px,6.5px 10px,5.5px 9px,4.5px 8px,3.5px 7px,4.5px 6px,5.5px 5px,6.5px 4px,7.5px 3px,8.5px 2px}::-webkit-scrollbar-button:horizontal:end:increment{background-image:linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f);background-position:4.5px 12px,5.5px 11px,6.5px 10px,7.5px 9px,8.5px 8px,9.5px 7px,8.5px 6px,7.5px 5px,6.5px 4px,5.5px 3px,4.5px 2px}::-webkit-scrollbar-button:horizontal:end:increment:hover{background-image:linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6);background-position:4.5px 12px,5.5px 11px,6.5px 10px,7.5px 9px,8.5px 8px,9.5px 7px,8.5px 6px,7.5px 5px,6.5px 4px,5.5px 3px,4.5px 2px}::-webkit-scrollbar-button:horizontal:end:increment:active{background-image:linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e);background-position:4.5px 12px,5.5px 11px,6.5px 10px,7.5px 9px,8.5px 8px,9.5px 7px,8.5px 6px,7.5px 5px,6.5px 4px,5.5px 3px,4.5px 2px}' }}))
4
+ dispatchEvent(new CustomEvent('ef.customStyles.define', { detail: { name: 'column-selection-dialog', styles: ':host{background:#535de8;display:inline-block;height:0;width:0}:host *{margin:0}:host [hide]{display:none}:host div{box-sizing:border-box}:host ef-item.disabled{color:rgba(184,189,199,.5)}:host ef-item[focused] ef-checkbox{color:#b7bcc6}:host ef-item::part(center){white-space:normal}:host .title{line-height:14px}:host ef-dialog{width:700px;height:500px;min-width:490px}:host ef-tree{width:100%}:host ef-tree-item{min-width:100%}:host .container{height:100%;display:flex;flex-direction:column}:host .row{display:flex}:host .row+.row{margin-top:10px}:host .side{width:50%;max-width:50%;display:flex;flex-direction:column;vertical-align:top;overflow:hidden;align-self:center;padding-left:5px;padding-right:5px;justify-content:center}:host .side:first-child{padding-left:0}:host .side:last-child{padding-right:0}:host #listSection{height:100%;overflow:hidden}:host #info_icon{vertical-align:top;font-size:14px}:host #tags_div>*{margin-right:5px;margin-bottom:10px}:host #allColumns{overflow:hidden;border:1px solid #3e444f;display:flex;flex-direction:column;flex-grow:1}:host #allColumnsSide,:host #visibleSide{height:100%}:host #visibleColumns{flex-grow:1;overflow-y:auto;border:1px solid #3e444f}:host #searchInput{width:100%}:host .no-results{pointer-events:none;text-align:center;margin-top:10px}:host #orderChangePanel{display:flex;text-align:center;margin-top:10px;justify-content:space-between}:host #orderChangePanel>*+*{margin-left:10px}:host #moveButtons>*+:not(:first-child){margin-left:10px}:host #descriptionContainer{margin-top:10px;min-height:60px;overflow-y:auto;border:1px solid #3e444f;font-size:12px;line-height:18px;box-sizing:border-box;padding:3px 10px}:host #selectAllHeader{min-height:28px;text-transform:none;cursor:pointer}:host #selectAllHeader #selectAllCheckbox{pointer-events:none}:host [slot=footer]{display:flex;justify-content:space-between}:host [slot=footer]>div{display:inline-flex;align-items:center;height:40px;padding-left:15px;padding-right:15px}:host [slot=footer]>div ef-button{text-transform:uppercase;margin-top:0;margin-bottom:0}:host [slot=footer]>div ef-button+ef-button{margin-left:15px}::-webkit-scrollbar{width:15px;height:15px}::-webkit-scrollbar-button{background:0 0/1px 2px no-repeat #21242a;height:15px;width:15px;display:block}::-webkit-scrollbar-thumb{background:#3e444f;border-radius:8px;border:2px solid #21242a}::-webkit-scrollbar-thumb:hover{background:#b7bcc6}::-webkit-scrollbar-thumb:active{background:#707a8e}::-webkit-scrollbar-track{background:#21242a}::-webkit-scrollbar-corner{background:#21242a}::-webkit-scrollbar-button:end:decrement,::-webkit-scrollbar-button:start:increment{display:none}::-webkit-scrollbar-button:horizontal{background-size:2px 1px}::-webkit-scrollbar-button:vertical:start:decrement{background-image:linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f);background-position:12px 8.5px,11px 7.5px,10px 6.5px,9px 5.5px,8px 4.5px,7px 3.5px,6px 4.5px,5px 5.5px,4px 6.5px,3px 7.5px,2px 8.5px}::-webkit-scrollbar-button:vertical:start:decrement:hover{background-image:linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6);background-position:12px 8.5px,11px 7.5px,10px 6.5px,9px 5.5px,8px 4.5px,7px 3.5px,6px 4.5px,5px 5.5px,4px 6.5px,3px 7.5px,2px 8.5px}::-webkit-scrollbar-button:vertical:start:decrement:active{background-image:linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e);background-position:12px 8.5px,11px 7.5px,10px 6.5px,9px 5.5px,8px 4.5px,7px 3.5px,6px 4.5px,5px 5.5px,4px 6.5px,3px 7.5px,2px 8.5px}::-webkit-scrollbar-button:vertical:end:increment{background-image:linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f);background-position:12px 4.5px,11px 5.5px,10px 6.5px,9px 7.5px,8px 8.5px,7px 9.5px,6px 8.5px,5px 7.5px,4px 6.5px,3px 5.5px,2px 4.5px}::-webkit-scrollbar-button:vertical:end:increment:hover{background-image:linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6);background-position:12px 4.5px,11px 5.5px,10px 6.5px,9px 7.5px,8px 8.5px,7px 9.5px,6px 8.5px,5px 7.5px,4px 6.5px,3px 5.5px,2px 4.5px}::-webkit-scrollbar-button:vertical:end:increment:active{background-image:linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e);background-position:12px 4.5px,11px 5.5px,10px 6.5px,9px 7.5px,8px 8.5px,7px 9.5px,6px 8.5px,5px 7.5px,4px 6.5px,3px 5.5px,2px 4.5px}::-webkit-scrollbar-button:horizontal:start:decrement{background-image:linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f);background-position:8.5px 12px,7.5px 11px,6.5px 10px,5.5px 9px,4.5px 8px,3.5px 7px,4.5px 6px,5.5px 5px,6.5px 4px,7.5px 3px,8.5px 2px}::-webkit-scrollbar-button:horizontal:start:decrement:hover{background-image:linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6);background-position:8.5px 12px,7.5px 11px,6.5px 10px,5.5px 9px,4.5px 8px,3.5px 7px,4.5px 6px,5.5px 5px,6.5px 4px,7.5px 3px,8.5px 2px}::-webkit-scrollbar-button:horizontal:start:decrement:active{background-image:linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e);background-position:8.5px 12px,7.5px 11px,6.5px 10px,5.5px 9px,4.5px 8px,3.5px 7px,4.5px 6px,5.5px 5px,6.5px 4px,7.5px 3px,8.5px 2px}::-webkit-scrollbar-button:horizontal:end:increment{background-image:linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f),linear-gradient(#3e444f,#3e444f);background-position:4.5px 12px,5.5px 11px,6.5px 10px,7.5px 9px,8.5px 8px,9.5px 7px,8.5px 6px,7.5px 5px,6.5px 4px,5.5px 3px,4.5px 2px}::-webkit-scrollbar-button:horizontal:end:increment:hover{background-image:linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6),linear-gradient(#b7bcc6,#b7bcc6);background-position:4.5px 12px,5.5px 11px,6.5px 10px,7.5px 9px,8.5px 8px,9.5px 7px,8.5px 6px,7.5px 5px,6.5px 4px,5.5px 3px,4.5px 2px}::-webkit-scrollbar-button:horizontal:end:increment:active{background-image:linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e),linear-gradient(#707a8e,#707a8e);background-position:4.5px 12px,5.5px 11px,6.5px 10px,7.5px 9px,8.5px 8px,9.5px 7px,8.5px 6px,7.5px 5px,6.5px 4px,5.5px 3px,4.5px 2px}' }}))