@refinitiv-ui/efx-grid 6.0.55 → 6.0.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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}' }}))