@revolist/revogrid 4.27.1 → 4.27.2

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 (44) hide show
  1. package/dist/cjs/{filter.button-F2Bw3UAd.js → filter.button-C6ixuMmr.js} +3 -2
  2. package/dist/cjs/index.cjs.js +3 -2
  3. package/dist/cjs/loader.cjs.js +1 -1
  4. package/dist/cjs/revo-grid.cjs.entry.js +3 -3
  5. package/dist/cjs/revo-grid.cjs.js +1 -1
  6. package/dist/cjs/revogr-data_4.cjs.entry.js +9 -8
  7. package/dist/cjs/revogr-filter-panel.cjs.entry.js +139 -33
  8. package/dist/cjs/{row-resize.plugin-sK9_rcUN.js → row-resize.plugin-C4YOF1lN.js} +54 -5
  9. package/dist/collection/components/header/header-renderer.js +7 -6
  10. package/dist/collection/components/header/revogr-header-style.css +8 -3
  11. package/dist/collection/components/revoGrid/revo-grid-style.css +12 -2
  12. package/dist/collection/plugins/filter/filter.button.js +3 -2
  13. package/dist/collection/plugins/filter/filter.indexed.js +5 -0
  14. package/dist/collection/plugins/filter/filter.panel.js +138 -31
  15. package/dist/collection/plugins/filter/filter.plugin.js +48 -5
  16. package/dist/collection/plugins/filter/filter.style.css +25 -3
  17. package/dist/{revo-grid/filter.button-DMhpuAiw.js → esm/filter.button-CEPUxLUo.js} +3 -2
  18. package/dist/esm/index.js +3 -3
  19. package/dist/esm/loader.js +1 -1
  20. package/dist/esm/revo-grid.entry.js +3 -3
  21. package/dist/esm/revo-grid.js +1 -1
  22. package/dist/esm/revogr-data_4.entry.js +9 -8
  23. package/dist/esm/revogr-filter-panel.entry.js +139 -33
  24. package/dist/{revo-grid/row-resize.plugin-DBOgjLdE.js → esm/row-resize.plugin-Beu0pMds.js} +54 -6
  25. package/dist/{esm/filter.button-DMhpuAiw.js → revo-grid/filter.button-CEPUxLUo.js} +3 -2
  26. package/dist/revo-grid/index.esm.js +3 -3
  27. package/dist/revo-grid/revo-grid.entry.js +3 -3
  28. package/dist/revo-grid/revo-grid.esm.js +1 -1
  29. package/dist/revo-grid/revogr-data_4.entry.js +9 -8
  30. package/dist/revo-grid/revogr-filter-panel.entry.js +139 -33
  31. package/dist/{esm/row-resize.plugin-DBOgjLdE.js → revo-grid/row-resize.plugin-Beu0pMds.js} +54 -6
  32. package/dist/types/plugins/filter/filter.indexed.d.ts +2 -0
  33. package/dist/types/plugins/filter/filter.panel.d.ts +9 -2
  34. package/dist/types/plugins/filter/filter.plugin.d.ts +8 -1
  35. package/dist/types/plugins/filter/filter.types.d.ts +8 -0
  36. package/dist/types/types/interfaces.d.ts +13 -1
  37. package/hydrate/index.js +203 -46
  38. package/hydrate/index.mjs +203 -46
  39. package/package.json +1 -1
  40. package/standalone/filter.button.js +1 -1
  41. package/standalone/index.js +1 -1
  42. package/standalone/revo-grid.js +1 -1
  43. package/standalone/revogr-filter-panel.js +1 -1
  44. package/standalone/revogr-header2.js +1 -1
@@ -5,7 +5,7 @@
5
5
 
6
6
  var index = require('./index-DRvxCueo.js');
7
7
  var debounce = require('./debounce-CcpHiH2p.js');
8
- var filter_button = require('./filter.button-F2Bw3UAd.js');
8
+ var filter_button = require('./filter.button-C6ixuMmr.js');
9
9
 
10
10
  (function closest() {
11
11
  if (!Element.prototype.matches) {
@@ -68,7 +68,7 @@ function moveFilterItem(items, sourceId, targetId) {
68
68
  return true;
69
69
  }
70
70
 
71
- const filterStyleCss = () => `.revo-button{position:relative;overflow:hidden;color:var(--rg-theme-button-text);background-color:var(--rg-theme-button-bg);height:32px;line-height:32px;padding:0 15px;outline:0;border:0;border-radius:7px;box-sizing:border-box;cursor:pointer}.revo-button.green{background-color:var(--rg-theme-button-success-bg)}.revo-button.red{background-color:var(--rg-theme-button-danger-bg)}.revo-button:disabled,.revo-button[disabled]{cursor:not-allowed !important;filter:opacity(0.35) !important}.revo-button.outline{border:1px solid var(--rg-theme-button-outline-border);line-height:30px;background:none;color:var(--rg-theme-button-outline-text);box-shadow:none}revogr-filter-panel{display:block}revogr-filter-panel .filter-panel-dialog{position:fixed;top:0;left:0;z-index:100;max-height:calc(100vh - 16px);overflow:auto;opacity:1;transform:none;color:var(--rg-theme-filter-panel-text);background-color:var(--rg-theme-filter-panel-bg);border:1px solid var(--rg-theme-filter-panel-border);transform-origin:62px 0px;box-shadow:0 5px 18px -2px var(--rg-theme-filter-panel-shadow);box-sizing:border-box;padding:10px;border-radius:8px;margin:0;min-width:220px;text-align:left;animation:revogr-filter-panel-open 140ms cubic-bezier(0.2, 0, 0, 1)}revogr-filter-panel .filter-panel-dialog .filter-holder>div{display:flex;flex-direction:column}revogr-filter-panel .filter-panel-dialog label{font-size:13px;display:block;padding:8px 0}revogr-filter-panel .filter-panel-dialog select{width:100%}revogr-filter-panel .filter-panel-dialog input[type=text]{border:0;min-height:34px;margin:5px 0;color:var(--rg-theme-filter-panel-text);background:var(--rg-theme-filter-panel-input-bg);border-radius:5px;padding:0 10px;box-sizing:border-box;width:100%}revogr-filter-panel .filter-panel-dialog .filter-actions{position:sticky;right:0;bottom:-10px;left:0;z-index:1;text-align:right;margin:10px -10px -10px;padding:0 5px 10px 10px;background:var(--rg-theme-filter-panel-bg);border-top:1px solid var(--rg-theme-filter-panel-divider)}revogr-filter-panel .filter-panel-dialog .filter-actions button{margin-top:10px;margin-right:5px}@keyframes revogr-filter-panel-open{from{opacity:0;transform:translateY(-4px) scale(0.98)}to{opacity:1;transform:none}}@media (prefers-reduced-motion: reduce){revogr-filter-panel .filter-panel-dialog{animation:none}}.rgHeaderCell:hover .rv-filter{transition:opacity 267ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, transform 178ms cubic-bezier(0.4, 0, 0.2, 1) 0ms}.rgHeaderCell:hover .rv-filter,.rgHeaderCell .rv-filter.active{opacity:1}.rgHeaderCell .rv-filter{height:24px;width:24px;background:none;border:0;opacity:0;visibility:visible;cursor:pointer;border-radius:4px;position:relative;z-index:1}.rgHeaderCell .rv-filter.active{color:var(--rg-theme-filter-panel-icon-active)}.rgHeaderCell .rv-filter .filter-img{color:var(--rg-theme-filter-panel-icon);width:11px}.select-css{display:block;font-family:sans-serif;line-height:1.3;padding:0.6em 1.4em 0.5em 0.8em;width:100%;max-width:100%;box-sizing:border-box;margin:0;color:var(--rg-theme-filter-panel-text);border:1px solid var(--rg-theme-filter-panel-select-border);box-shadow:transparent;border-radius:0.5em;appearance:none;background-color:var(--rg-theme-filter-panel-input-bg);background-image:var(--revo-grid-filter-panel-select-arrow, url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23007CB2%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E"));background-repeat:no-repeat, repeat;background-position:right 0.7em top 50%, 0 0;background-size:0.65em auto, 100%;}.select-css::-ms-expand{display:none}.select-css{}.select-css:hover{border-color:var(--rg-theme-filter-panel-select-border)}.select-css{}.select-css:focus{border-color:var(--rg-theme-filter-panel-select-border-hover);box-shadow:var(--rg-theme-filter-panel-focus-ring);outline:none}.select-css{}.select-css option{font-weight:normal}.select-css{}.select-css:disabled,.select-css[aria-disabled=true]{color:var(--rg-theme-filter-panel-muted-text);background-image:var(--revo-grid-filter-panel-select-arrow-disabled, url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22graytext%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E"))}.select-css:disabled:hover,.select-css[aria-disabled=true]{border-color:var(--rg-theme-filter-panel-select-border)}.multi-filter-list{margin-top:5px;margin-bottom:5px}.multi-filter-list div{white-space:nowrap}.multi-filter-list .multi-filter-list-row{display:flex;align-items:center;gap:6px;position:relative}.multi-filter-list .multi-filter-list-row.filter-row-dragging{opacity:0.65}.multi-filter-list .multi-filter-list-row.filter-row-drag-over::before{content:"";position:absolute;top:-4px;right:0;left:0;z-index:2;height:2px;background:var(--rg-theme-filter-panel-reorder-accent);border-radius:999px;box-shadow:0 0 0 2px var(--rg-theme-filter-panel-bg)}.multi-filter-list .multi-filter-list-row.filter-row-drop-active .filter-row-drop-target{pointer-events:auto}.multi-filter-list .filter-row-drop-target{position:absolute;inset:0;z-index:1;padding:0;pointer-events:none;background:transparent;border:0}.multi-filter-list .multi-filter-list-action{display:flex;align-self:stretch;flex:0 0 auto;justify-content:flex-end;align-items:center}.multi-filter-list .and-or-button{margin:0 0 0 10px;min-width:58px;cursor:pointer}.multi-filter-list .trash-button{margin:0 0 -2px 6px;padding:0;border:0;background:transparent;color:inherit;cursor:pointer;width:22px;height:100%;font-size:16px}.multi-filter-list .trash-button .trash-img{width:1em}.multi-filter-list .reorder-button{border:0;background:transparent;color:var(--rg-theme-filter-panel-reorder-color);cursor:grab;font-family:monospace;font-size:12px;letter-spacing:0;line-height:1;padding:6px 2px;transform:scaleX(0.8);width:16px}.multi-filter-list .reorder-button.filter-row-drag-over{color:var(--rg-theme-filter-panel-reorder-accent)}.multi-filter-list .reorder-button:active{cursor:grabbing}.multi-filter-list-container{padding:0;margin:0;list-style:none}.add-filter-divider{display:block;margin:0 -10px 10px -10px;border-bottom:1px solid var(--rg-theme-filter-panel-divider);height:10px}.select-input{display:flex;align-items:center;flex:1 1 auto;gap:6px;min-width:0}.select-input .select-filter,.select-input .filter-extra{flex:1 1 0;min-width:0}.select-input .select-filter{width:auto}.select-input .filter-extra{display:flex}.select-input .filter-extra>*{width:100%}.select-input input[type=text],.select-input input[type=date]{margin:0}`;
71
+ const filterStyleCss = () => `.revo-button{position:relative;overflow:hidden;color:var(--rg-theme-button-text);background-color:var(--rg-theme-button-bg);height:32px;line-height:32px;padding:0 15px;outline:0;border:0;border-radius:7px;box-sizing:border-box;cursor:pointer}.revo-button.green{background-color:var(--rg-theme-button-success-bg)}.revo-button.red{background-color:var(--rg-theme-button-danger-bg)}.revo-button:disabled,.revo-button[disabled]{cursor:not-allowed !important;filter:opacity(0.35) !important}.revo-button.outline{border:1px solid var(--rg-theme-button-outline-border);line-height:30px;background:none;color:var(--rg-theme-button-outline-text);box-shadow:none}revogr-filter-panel{display:block}revogr-filter-panel .filter-panel-dialog{position:fixed;top:0;left:0;z-index:100;max-height:calc(100vh - 16px);overflow:auto;opacity:1;transform:none;color:var(--rg-theme-filter-panel-text);background-color:var(--rg-theme-filter-panel-bg);border:1px solid var(--rg-theme-filter-panel-border);transform-origin:62px 0px;box-shadow:0 5px 18px -2px var(--rg-theme-filter-panel-shadow);box-sizing:border-box;padding:10px;border-radius:8px;margin:0;min-width:220px;text-align:left;animation:revogr-filter-panel-open 140ms cubic-bezier(0.2, 0, 0, 1)}revogr-filter-panel .filter-panel-dialog .filter-holder>div{display:flex;flex-direction:column}revogr-filter-panel .filter-panel-dialog label{font-size:13px;display:block;padding:8px 0}revogr-filter-panel .filter-panel-dialog select{width:100%}revogr-filter-panel .filter-panel-dialog input[type=text]{border:0;min-height:34px;margin:5px 0;color:var(--rg-theme-filter-panel-text);background:var(--rg-theme-filter-panel-input-bg);border-radius:5px;padding:0 10px;box-sizing:border-box;width:100%}revogr-filter-panel .filter-panel-dialog .filter-actions{position:sticky;right:0;bottom:-10px;left:0;z-index:1;text-align:right;margin:10px -10px -10px;padding:0 5px 10px 10px;background:var(--rg-theme-filter-panel-bg);border-top:1px solid var(--rg-theme-filter-panel-divider)}revogr-filter-panel .filter-panel-dialog .filter-actions button{margin-top:10px;margin-right:5px}@keyframes revogr-filter-panel-open{from{opacity:0;transform:translateY(-4px) scale(0.98)}to{opacity:1;transform:none}}@media (prefers-reduced-motion: reduce){revogr-filter-panel .filter-panel-dialog{animation:none}}.rgHeaderCell:hover .rv-filter{transition:opacity 267ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, width 267ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, transform 178ms cubic-bezier(0.4, 0, 0.2, 1) 0ms}.rgHeaderCell:hover:has(.rv-filter) .header-content,.rgHeaderCell:focus-within:has(.rv-filter) .header-content,.rgHeaderCell:has(.rv-filter.active) .header-content{margin-right:24px}.rgHeaderCell:hover:has(.rv-filter):has(.desc) .header-content,.rgHeaderCell:hover:has(.rv-filter):has(.asc) .header-content,.rgHeaderCell:focus-within:has(.rv-filter):has(.desc) .header-content,.rgHeaderCell:focus-within:has(.rv-filter):has(.asc) .header-content,.rgHeaderCell:has(.rv-filter.active):has(.desc) .header-content,.rgHeaderCell:has(.rv-filter.active):has(.asc) .header-content{margin-right:8px;padding-right:24px}.rgHeaderCell:hover .rv-filter,.rgHeaderCell:focus-within .rv-filter,.rgHeaderCell .rv-filter.active{opacity:1;width:24px}@media (hover: none), (pointer: coarse){.rgHeaderCell:has(.rv-filter) .header-content{margin-right:24px}.rgHeaderCell:has(.rv-filter):has(.desc) .header-content,.rgHeaderCell:has(.rv-filter):has(.asc) .header-content{margin-right:8px;padding-right:24px}.rgHeaderCell .rv-filter{opacity:1;width:24px}}.rgHeaderCell .rv-filter{height:24px;width:0;background:none;border:0;opacity:0;visibility:visible;cursor:pointer;border-radius:4px;position:relative;z-index:1;padding:0}.rgHeaderCell .rv-filter.active{color:var(--rg-theme-filter-panel-icon-active)}.rgHeaderCell .rv-filter .filter-img{color:var(--rg-theme-filter-panel-icon);width:11px}.select-css{display:block;font-family:sans-serif;line-height:1.3;padding:0.6em 1.4em 0.5em 0.8em;width:100%;max-width:100%;box-sizing:border-box;margin:0;color:var(--rg-theme-filter-panel-text);border:1px solid var(--rg-theme-filter-panel-select-border);box-shadow:transparent;border-radius:0.5em;appearance:none;background-color:var(--rg-theme-filter-panel-input-bg);background-image:var(--revo-grid-filter-panel-select-arrow, url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23007CB2%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E"));background-repeat:no-repeat, repeat;background-position:right 0.7em top 50%, 0 0;background-size:0.65em auto, 100%;}.select-css::-ms-expand{display:none}.select-css{}.select-css:hover{border-color:var(--rg-theme-filter-panel-select-border)}.select-css{}.select-css:focus{border-color:var(--rg-theme-filter-panel-select-border-hover);box-shadow:var(--rg-theme-filter-panel-focus-ring);outline:none}.select-css{}.select-css option{font-weight:normal}.select-css{}.select-css:disabled,.select-css[aria-disabled=true]{color:var(--rg-theme-filter-panel-muted-text);background-image:var(--revo-grid-filter-panel-select-arrow-disabled, url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22graytext%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E"))}.select-css:disabled:hover,.select-css[aria-disabled=true]{border-color:var(--rg-theme-filter-panel-select-border)}.multi-filter-list{margin-top:5px;margin-bottom:5px}.multi-filter-list div{white-space:nowrap}.multi-filter-list .multi-filter-list-row{display:flex;align-items:center;gap:6px;position:relative}.multi-filter-list .multi-filter-list-row.filter-row-dragging{opacity:0.65}.multi-filter-list .multi-filter-list-row.filter-row-drag-over::before{content:"";position:absolute;top:-4px;right:0;left:0;z-index:2;height:2px;background:var(--rg-theme-filter-panel-reorder-accent);border-radius:999px;box-shadow:0 0 0 2px var(--rg-theme-filter-panel-bg)}.multi-filter-list .multi-filter-list-row.filter-row-drop-active .filter-row-drop-target{pointer-events:auto}.multi-filter-list .filter-row-drop-target{position:absolute;inset:0;z-index:1;padding:0;pointer-events:none;background:transparent;border:0}.multi-filter-list .multi-filter-list-action{display:flex;align-self:stretch;flex:0 0 auto;justify-content:flex-end;align-items:center}.multi-filter-list .and-or-button{margin:0 0 0 10px;min-width:58px;cursor:pointer}.multi-filter-list .trash-button{margin:0 0 -2px 6px;padding:0;border:0;background:transparent;color:inherit;cursor:pointer;width:22px;height:100%;font-size:16px}.multi-filter-list .trash-button .trash-img{width:1em}.multi-filter-list .reorder-button{border:0;background:transparent;color:var(--rg-theme-filter-panel-reorder-color);cursor:grab;font-family:monospace;font-size:12px;letter-spacing:0;line-height:1;padding:6px 2px;transform:scaleX(0.8);width:16px}.multi-filter-list .reorder-button.filter-row-drag-over{color:var(--rg-theme-filter-panel-reorder-accent)}.multi-filter-list .reorder-button:active{cursor:grabbing}.multi-filter-list-container{padding:0;margin:0;list-style:none}.add-filter-divider{display:block;margin:0 -10px 10px -10px;border-bottom:1px solid var(--rg-theme-filter-panel-divider);height:10px}.select-input{display:flex;align-items:center;flex:1 1 auto;gap:6px;min-width:0}.select-input .select-filter,.select-input .filter-extra{flex:1 1 0;min-width:0}.select-input .select-filter{width:auto}.select-input .filter-extra{display:flex}.select-input .filter-extra>*{width:100%}.select-input input[type=text],.select-input input[type=date]{margin:0}`;
72
72
 
73
73
  const defaultType = 'none';
74
74
  const FILTER_LIST_CLASS = 'multi-filter-list';
@@ -80,6 +80,7 @@ const FilterPanel = class {
80
80
  index.registerInstance(this, hostRef);
81
81
  this.filterChange = index.createEvent(this, "filterChange", 7);
82
82
  this.resetChange = index.createEvent(this, "resetChange", 7);
83
+ this.hasChanges = false;
83
84
  this.filterCaptionsInternal = {
84
85
  title: 'Filter by',
85
86
  ok: 'Close',
@@ -115,7 +116,7 @@ const FilterPanel = class {
115
116
  */
116
117
  this.allowDuplicateOperators = true;
117
118
  this.debouncedApplyFilter = debounce.debounce(() => {
118
- this.filterChange.emit(this.filterItems);
119
+ this.emitFilterChange();
119
120
  }, 400);
120
121
  }
121
122
  onMouseDown(e) {
@@ -145,10 +146,25 @@ const FilterPanel = class {
145
146
  }
146
147
  }
147
148
  async show(newEntity) {
149
+ this.hasChanges = false;
148
150
  this.changes = newEntity;
149
- this.filterItems = (newEntity === null || newEntity === void 0 ? void 0 : newEntity.filterItems) || {};
151
+ this.filterItems = this.cloneFilterItems((newEntity === null || newEntity === void 0 ? void 0 : newEntity.filterItems) || {});
152
+ this.draftFilter = undefined;
150
153
  if (this.changes) {
151
154
  this.changes.type = this.changes.type || defaultType;
155
+ const prop = this.changes.prop;
156
+ const propFilters = prop === undefined ? undefined : this.filterItems[prop];
157
+ if (!(propFilters === null || propFilters === void 0 ? void 0 : propFilters.length) && this.changes.showDefaultFilter !== false) {
158
+ const type = this.resolveDraftFilterType(this.changes.defaultFilterType);
159
+ if (type) {
160
+ this.draftFilter = {
161
+ id: ++this.filterId,
162
+ type,
163
+ value: '',
164
+ relation: 'and',
165
+ };
166
+ }
167
+ }
152
168
  }
153
169
  }
154
170
  async getChanges() {
@@ -169,29 +185,42 @@ const FilterPanel = class {
169
185
  const prop = (_a = this.changes) === null || _a === void 0 ? void 0 : _a.prop;
170
186
  if (prop === undefined)
171
187
  return '';
172
- const propFilters = (_b = this.filterItems[prop]) !== null && _b !== void 0 ? _b : [];
173
- const visibleFilterCount = propFilters.filter(filter => !filter.hidden).length;
188
+ const propFilters = ((_b = this.filterItems[prop]) !== null && _b !== void 0 ? _b : []).map((filter, index) => ({
189
+ filter,
190
+ index,
191
+ isDraft: false,
192
+ }));
193
+ if (this.draftFilter) {
194
+ propFilters.push({
195
+ filter: this.draftFilter,
196
+ index: propFilters.length,
197
+ isDraft: true,
198
+ });
199
+ }
200
+ const visibleFilters = propFilters.filter(({ filter }) => !filter.hidden);
201
+ const visibleFilterCount = visibleFilters.length;
174
202
  const capts = Object.assign(Object.assign({}, this.filterCaptionsInternal), this.filterCaptions);
175
- return (index.h("div", { key: this.filterId }, index.h("ul", { class: "multi-filter-list-container" }, propFilters.map((filter, index$1) => {
203
+ return (index.h("div", { key: this.filterId }, index.h("ul", { class: "multi-filter-list-container" }, propFilters.map(({ filter, index: index$1, isDraft }) => {
204
+ var _a;
176
205
  let andOrButton;
177
206
  if (filter.hidden) {
178
207
  return;
179
208
  }
180
209
  // hide toggle button if there is only one filter and the last one
181
- if (index$1 !== this.filterItems[prop].length - 1) {
210
+ if (((_a = visibleFilters[visibleFilterCount - 1]) === null || _a === void 0 ? void 0 : _a.filter.id) !== filter.id) {
182
211
  andOrButton = (index.h(filter_button.AndOrButton, { text: filter.relation === 'and' ? capts.and : capts.or, onClick: () => this.toggleFilterAndOr(filter.id) }));
183
212
  }
184
- const extra = this.renderExtra(prop, index$1);
213
+ const extra = this.renderExtra(prop, index$1, isDraft);
185
214
  const isDragging = this.draggedFilterId === filter.id;
186
215
  const isDragOver = this.dragOverFilterId === filter.id && !isDragging;
187
- const canReorder = visibleFilterCount > 1;
216
+ const canReorder = visibleFilterCount > 1 && !isDraft;
188
217
  return (index.h("li", { key: filter.id, class: FILTER_LIST_CLASS, "aria-label": `${capts.filterCondition} ${index$1 + 1}` }, index.h("div", { class: {
189
218
  'multi-filter-list-row': true,
190
219
  'filter-row-drop-active': this.draggedFilterId !== undefined && !isDragging,
191
220
  'filter-row-dragging': isDragging,
192
221
  'filter-row-drag-over': isDragOver,
193
- } }, canReorder ? (index.h("button", { type: "button", class: "filter-row-drop-target", tabIndex: -1, "aria-label": `${capts.filterCondition} ${index$1 + 1}`, onDragOver: e => this.onFilterDragOver(e, filter.id), onDragLeave: () => this.onFilterDragLeave(filter.id), onDrop: e => this.onFilterDrop(e, prop, filter.id) })) : '', canReorder ? (index.h(filter_button.ReorderButton, { ariaLabel: capts.reorderFilter, dragging: isDragging, dragOver: isDragOver, onDragStart: e => this.onFilterDragStart(e, filter.id), onDragEnd: () => this.onFilterDragEnd(), onKeyDown: e => this.onFilterReorderKeyDown(e, prop, filter.id) })) : '', index.h("div", { class: { 'select-input': true } }, index.h("select", { class: "select-css select-filter", onChange: e => this.onFilterTypeChange(e, prop, index$1) }, this.renderSelectOptions(this.filterItems[prop][index$1].type, true)), extra ? index.h("div", { class: "filter-extra" }, extra) : ''), index.h("div", { class: FILTER_LIST_CLASS_ACTION }, andOrButton, index.h(filter_button.TrashButton, { ariaLabel: capts.removeFilter, onClick: () => this.onRemoveFilter(filter.id) })))));
194
- })), propFilters.some(f => !f.hidden) ? index.h("div", { class: "add-filter-divider" }) : ''));
222
+ } }, canReorder ? (index.h("button", { type: "button", class: "filter-row-drop-target", tabIndex: -1, "aria-label": `${capts.filterCondition} ${index$1 + 1}`, onDragOver: e => this.onFilterDragOver(e, filter.id), onDragLeave: () => this.onFilterDragLeave(filter.id), onDrop: e => this.onFilterDrop(e, prop, filter.id) })) : '', canReorder ? (index.h(filter_button.ReorderButton, { ariaLabel: capts.reorderFilter, dragging: isDragging, dragOver: isDragOver, onDragStart: e => this.onFilterDragStart(e, filter.id), onDragEnd: () => this.onFilterDragEnd(), onKeyDown: e => this.onFilterReorderKeyDown(e, prop, filter.id) })) : '', index.h("div", { class: { 'select-input': true } }, index.h("select", { class: "select-css select-filter", onChange: e => this.onFilterTypeChange(e, prop, index$1, isDraft) }, this.renderSelectOptions(filter.type, true)), extra ? index.h("div", { class: "filter-extra" }, extra) : ''), index.h("div", { class: FILTER_LIST_CLASS_ACTION }, andOrButton, index.h(filter_button.TrashButton, { ariaLabel: capts.removeFilter, onClick: () => this.onRemoveFilter(filter.id) })))));
223
+ })), visibleFilterCount ? index.h("div", { class: "add-filter-divider" }) : ''));
195
224
  }
196
225
  componentDidRender() {
197
226
  this.syncDialog();
@@ -240,16 +269,24 @@ const FilterPanel = class {
240
269
  el.style.left = `${left}px`;
241
270
  el.style.top = `${top}px`;
242
271
  }
243
- onFilterTypeChange(e, prop, index) {
272
+ onFilterTypeChange(e, prop, index, isDraft = false) {
244
273
  if (!(e.target instanceof HTMLSelectElement)) {
245
274
  return;
246
275
  }
247
- this.filterItems[prop][index].type = e.target.value;
276
+ const type = e.target.value;
277
+ const filter = isDraft
278
+ ? this.promoteDraft(prop, type)
279
+ : this.filterItems[prop][index];
280
+ if (!filter) {
281
+ return;
282
+ }
283
+ filter.type = type;
284
+ this.hasChanges = true;
248
285
  // this re-renders the input to know if we need extra input
249
286
  this.filterId++;
250
287
  // adding setTimeout will wait for the next tick DOM update then focus on input
251
288
  setTimeout(() => {
252
- const input = document.getElementById('filter-input-' + this.filterItems[prop][index].id);
289
+ const input = document.getElementById('filter-input-' + filter.id);
253
290
  if (input instanceof HTMLInputElement) {
254
291
  input.focus();
255
292
  }
@@ -284,12 +321,20 @@ const FilterPanel = class {
284
321
  return;
285
322
  this.filterId++;
286
323
  this.currentFilterId = this.filterId;
287
- this.filterItems[prop].push({
288
- id: this.currentFilterId,
289
- type: this.currentFilterType,
290
- value: '',
291
- relation: 'and',
292
- });
324
+ if (this.draftFilter) {
325
+ this.draftFilter.id = this.currentFilterId;
326
+ this.draftFilter.type = this.currentFilterType;
327
+ this.promoteDraft(prop);
328
+ }
329
+ else {
330
+ this.filterItems[prop].push({
331
+ id: this.currentFilterId,
332
+ type: this.currentFilterType,
333
+ value: '',
334
+ relation: 'and',
335
+ });
336
+ this.hasChanges = true;
337
+ }
293
338
  // adding setTimeout will wait for the next tick DOM update then focus on input
294
339
  setTimeout(() => {
295
340
  const input = document.getElementById('filter-input-' + this.currentFilterId);
@@ -298,7 +343,9 @@ const FilterPanel = class {
298
343
  }, 0);
299
344
  }
300
345
  onSave() {
301
- this.filterChange.emit(this.filterItems);
346
+ if (this.hasChanges) {
347
+ this.emitFilterChange();
348
+ }
302
349
  }
303
350
  onCancel() {
304
351
  this.changes = undefined;
@@ -306,16 +353,25 @@ const FilterPanel = class {
306
353
  onReset() {
307
354
  var _a;
308
355
  this.assertChanges();
309
- this.resetChange.emit((_a = this.changes) === null || _a === void 0 ? void 0 : _a.prop);
356
+ this.draftFilter = undefined;
357
+ const prop = (_a = this.changes) === null || _a === void 0 ? void 0 : _a.prop;
358
+ if (prop !== undefined) {
359
+ delete this.filterItems[prop];
360
+ }
361
+ this.resetChange.emit(prop);
310
362
  // this updates the DOM which is used by getFilterItemsList() key
311
363
  this.filterId++;
312
364
  }
313
365
  onRemoveFilter(id) {
314
- var _a;
366
+ var _a, _b;
315
367
  this.assertChanges();
316
368
  // this is for reactivity issues for getFilterItemsList()
317
369
  this.filterId++;
318
370
  const prop = (_a = this.changes) === null || _a === void 0 ? void 0 : _a.prop;
371
+ if (((_b = this.draftFilter) === null || _b === void 0 ? void 0 : _b.id) === id) {
372
+ this.draftFilter = undefined;
373
+ return;
374
+ }
319
375
  const items = this.filterItems[prop !== null && prop !== void 0 ? prop : ''];
320
376
  if (!items)
321
377
  return;
@@ -323,6 +379,7 @@ const FilterPanel = class {
323
379
  if (index === -1)
324
380
  return;
325
381
  items.splice(index, 1);
382
+ this.hasChanges = true;
326
383
  // let's remove the prop if no more filters so the filter icon will be removed
327
384
  if (items.length === 0)
328
385
  delete this.filterItems[prop !== null && prop !== void 0 ? prop : ''];
@@ -364,6 +421,7 @@ const FilterPanel = class {
364
421
  if (!moveFilterItem(items, sourceId, targetId)) {
365
422
  return;
366
423
  }
424
+ this.hasChanges = true;
367
425
  this.filterId++;
368
426
  if (!this.disableDynamicFiltering) {
369
427
  this.debouncedApplyFilter();
@@ -399,6 +457,7 @@ const FilterPanel = class {
399
457
  if (!target || !moveFilterItem(items, sourceId, target.id)) {
400
458
  return;
401
459
  }
460
+ this.hasChanges = true;
402
461
  this.filterId++;
403
462
  if (!this.disableDynamicFiltering) {
404
463
  this.debouncedApplyFilter();
@@ -417,6 +476,7 @@ const FilterPanel = class {
417
476
  if (index === -1)
418
477
  return;
419
478
  items[index].relation = items[index].relation === 'and' ? 'or' : 'and';
479
+ this.hasChanges = true;
420
480
  if (!this.disableDynamicFiltering) {
421
481
  this.debouncedApplyFilter();
422
482
  }
@@ -465,12 +525,22 @@ const FilterPanel = class {
465
525
  }
466
526
  return options;
467
527
  }
468
- renderExtra(prop, index$1) {
469
- const currentFilter = this.filterItems[prop];
528
+ renderExtra(prop, index$1, isDraft = false) {
529
+ var _a, _b;
530
+ const currentFilter = isDraft
531
+ ? this.draftFilter
532
+ : (_a = this.filterItems[prop]) === null || _a === void 0 ? void 0 : _a[index$1];
470
533
  if (!currentFilter)
471
534
  return '';
472
535
  const applyFilter = (value) => {
473
- this.filterItems[prop][index$1].value = value;
536
+ currentFilter.value = value;
537
+ if (isDraft && !this.isMeaningfulDraftValue(value)) {
538
+ return;
539
+ }
540
+ if (isDraft && !this.promoteDraft(prop)) {
541
+ return;
542
+ }
543
+ this.hasChanges = true;
474
544
  if (!this.disableDynamicFiltering) {
475
545
  this.debouncedApplyFilter();
476
546
  }
@@ -485,11 +555,11 @@ const FilterPanel = class {
485
555
  }
486
556
  };
487
557
  const capts = Object.assign(Object.assign({}, this.filterCaptionsInternal), this.filterCaptions);
488
- const extra = this.filterEntities[currentFilter[index$1].type].extra;
558
+ const extra = (_b = this.filterEntities[currentFilter.type]) === null || _b === void 0 ? void 0 : _b.extra;
489
559
  if (typeof extra === 'function') {
490
560
  return extra(index.h, {
491
- value: currentFilter[index$1].value,
492
- filter: currentFilter[index$1],
561
+ value: currentFilter.value,
562
+ filter: currentFilter,
493
563
  prop,
494
564
  index: index$1,
495
565
  placeholder: capts.placeholder,
@@ -504,7 +574,7 @@ const FilterPanel = class {
504
574
  if (extra !== 'input' && extra !== 'datepicker') {
505
575
  return '';
506
576
  }
507
- return (index.h("input", { id: `filter-input-${currentFilter[index$1].id}`, placeholder: capts.placeholder, type: extra === 'datepicker' ? 'date' : 'text', value: currentFilter[index$1].value, onInput: (e) => {
577
+ return (index.h("input", { id: `filter-input-${currentFilter.id}`, placeholder: capts.placeholder, type: extra === 'datepicker' ? 'date' : 'text', value: currentFilter.value, onInput: (e) => {
508
578
  if (e.target instanceof HTMLInputElement) {
509
579
  applyFilter(e.target.value);
510
580
  }
@@ -520,6 +590,42 @@ const FilterPanel = class {
520
590
  e.stopPropagation();
521
591
  } }));
522
592
  }
593
+ resolveDraftFilterType(preferred) {
594
+ var _a, _b;
595
+ const available = Object.values((_b = (_a = this.changes) === null || _a === void 0 ? void 0 : _a.filterTypes) !== null && _b !== void 0 ? _b : {}).flat();
596
+ const type = preferred && available.includes(preferred)
597
+ ? preferred
598
+ : available[0];
599
+ return type;
600
+ }
601
+ promoteDraft(prop, type) {
602
+ if (!this.draftFilter) {
603
+ return;
604
+ }
605
+ if (!this.filterItems[prop]) {
606
+ this.filterItems[prop] = [];
607
+ }
608
+ if (type) {
609
+ this.draftFilter.type = type;
610
+ }
611
+ const filter = this.draftFilter;
612
+ this.filterItems[prop].push(filter);
613
+ this.draftFilter = undefined;
614
+ this.hasChanges = true;
615
+ return filter;
616
+ }
617
+ isMeaningfulDraftValue(value) {
618
+ return value !== '' && value !== undefined && value !== null;
619
+ }
620
+ emitFilterChange() {
621
+ this.filterChange.emit(this.cloneFilterItems(this.filterItems));
622
+ }
623
+ cloneFilterItems(filterItems) {
624
+ return Object.fromEntries(Object.entries(filterItems).map(([prop, filters]) => [
625
+ prop,
626
+ filters.map(filter => (Object.assign({}, filter))),
627
+ ]));
628
+ }
523
629
  getAddFilterSelect() {
524
630
  return this.element.querySelector(`#${FILTER_ID}`);
525
631
  }
@@ -552,7 +658,7 @@ const FilterPanel = class {
552
658
  top: `${(_d = (_c = this.changes) === null || _c === void 0 ? void 0 : _c.y) !== null && _d !== void 0 ? _d : 0}px`,
553
659
  };
554
660
  const capts = Object.assign(Object.assign({}, this.filterCaptionsInternal), this.filterCaptions);
555
- return (index.h(index.Host, { key: 'd0e4ebb408750b11b3965da6a25e581733c968e3' }, index.h("dialog", { key: '3df36777c931ec1063e8574169ca880a99dbfe41', class: "filter-panel-dialog", style: style, ref: el => (this.dialog = el), onCancel: e => {
661
+ return (index.h(index.Host, { key: '0bb6ac39407141e989b6a2f54063ee5ed789e40e' }, index.h("dialog", { key: '28a919ca4184018e8f00bbd31d373e153306d163', class: "filter-panel-dialog", style: style, ref: el => (this.dialog = el), onCancel: e => {
556
662
  e.preventDefault();
557
663
  this.onCancel();
558
664
  } }, this.changes && [
@@ -561,7 +667,7 @@ const FilterPanel = class {
561
667
  ((_g = this.changes) === null || _g === void 0 ? void 0 : _g.hideDefaultFilters) !== true && [
562
668
  index.h("label", { key: "filter-title" }, capts.title),
563
669
  index.h("div", { key: "filter-holder", class: "filter-holder" }, this.getFilterItemsList()),
564
- index.h("div", { key: "add-filter", class: "add-filter" }, index.h("select", { key: 'e2a8bd29f2090d3e6c933795427b71ca190b82aa', id: FILTER_ID, class: "select-css", onChange: e => this.onAddNewFilter(e) }, this.renderSelectOptions(this.currentFilterType))),
670
+ index.h("div", { key: "add-filter", class: "add-filter" }, index.h("select", { key: 'c5816b6699d8608bd8ec2621bbbd4c70daf52a1e', id: FILTER_ID, class: "select-css", onChange: e => this.onAddNewFilter(e) }, this.renderSelectOptions(this.currentFilterType))),
565
671
  ],
566
672
  index.h("slot", { key: "default-slot" }),
567
673
  ((_j = (_h = this.changes).extraBottomContent) === null || _j === void 0 ? void 0 : _j.call(_h, this.changes)) || '',
@@ -8,7 +8,7 @@ var dimension_helpers = require('./dimension.helpers-CptesQOZ.js');
8
8
  var viewport_store = require('./viewport.store-mhsdi61t.js');
9
9
  var index$1 = require('./index-BVESmpqW.js');
10
10
  var index = require('./index-DRvxCueo.js');
11
- var filter_button = require('./filter.button-F2Bw3UAd.js');
11
+ var filter_button = require('./filter.button-C6ixuMmr.js');
12
12
  var debounce = require('./debounce-CcpHiH2p.js');
13
13
  var headerCellRenderer = require('./header-cell-renderer-B5Y4fdZC.js');
14
14
 
@@ -1363,6 +1363,11 @@ const filterTypes = {
1363
1363
  boolean: ['notEmpty', 'empty'],
1364
1364
  array: ['notEmpty', 'empty'],
1365
1365
  };
1366
+ /** Preferred initial operator for built-in filter families. */
1367
+ const filterTypeDefaults = {
1368
+ string: 'contains',
1369
+ number: 'eqN',
1370
+ };
1366
1371
  const filterNames = {
1367
1372
  none: 'None',
1368
1373
  empty: 'Is blank',
@@ -1405,6 +1410,8 @@ const FILTE_PANEL = 'revogr-filter-panel';
1405
1410
  *
1406
1411
  * @property {FilterLocalization|undefined} localization - translation for filter popup captions.
1407
1412
  *
1413
+ * @property {boolean|undefined} defaultFilter - creates a draft condition when an empty filter panel opens. Defaults to true.
1414
+ *
1408
1415
  * @property {boolean|undefined} disableDynamicFiltering - disables dynamic filtering. A way to apply filters on Save only.
1409
1416
  */
1410
1417
  /**
@@ -1426,7 +1433,7 @@ class FilterPlugin extends BasePlugin {
1426
1433
  * number: ['eqN', 'neqN', 'gt']
1427
1434
  * }
1428
1435
  */
1429
- this.filterByType = Object.assign({}, filterTypes);
1436
+ this.filterByType = Object.fromEntries(Object.entries(filterTypes).map(([type, filters]) => [type, [...filters]]));
1430
1437
  this.filterNameIndexByType = Object.assign({}, filterNames);
1431
1438
  this.filterFunctionsIndexedByType = Object.assign({}, filterCoreFunctionsIndexedByType);
1432
1439
  this.filterProp = filter_button.FILTER_PROP;
@@ -1510,11 +1517,16 @@ class FilterPlugin extends BasePlugin {
1510
1517
  return null;
1511
1518
  }
1512
1519
  initConfig(config) {
1513
- var _a;
1520
+ var _a, _b, _c, _d;
1514
1521
  this.config = config;
1515
1522
  this.allowDuplicateOperators = (_a = config.allowDuplicateOperators) !== null && _a !== void 0 ? _a : true;
1516
1523
  if (this.pop) {
1517
1524
  this.pop.allowDuplicateOperators = this.allowDuplicateOperators;
1525
+ this.pop.disableDynamicFiltering =
1526
+ (_b = config.disableDynamicFiltering) !== null && _b !== void 0 ? _b : false;
1527
+ this.pop.closeOnOutsideClick =
1528
+ (_c = config.closeFilterPanelOnOutsideClick) !== null && _c !== void 0 ? _c : true;
1529
+ this.pop.filterCaptions = (_d = config.localization) === null || _d === void 0 ? void 0 : _d.captions;
1518
1530
  }
1519
1531
  if (config.multiFilterItems) {
1520
1532
  this.multiFilterItems = Object.assign({}, config.multiFilterItems);
@@ -1603,11 +1615,12 @@ class FilterPlugin extends BasePlugin {
1603
1615
  }
1604
1616
  // filter button clicked, open filter dialog
1605
1617
  const buttonPos = (filterButton instanceof HTMLElement ? filterButton : el).getBoundingClientRect();
1606
- const data = Object.assign(Object.assign(Object.assign({}, e.detail), this.filterCollection[prop]), { x: buttonPos.x, y: buttonPos.y + buttonPos.height, anchorY: buttonPos.y, autoCorrect: true, filterTypes: this.getColumnFilter(e.detail.filter), filterItems: this.multiFilterItems, extraContent: this.extraHyperContent, extraBottomContent: this.extraBottomHyperContent });
1618
+ const data = Object.assign(Object.assign(Object.assign({}, e.detail), this.filterCollection[prop]), { x: buttonPos.x, y: buttonPos.y + buttonPos.height, anchorY: buttonPos.y, autoCorrect: true, filterTypes: this.getColumnFilter(e.detail.filter), defaultFilterType: this.getDefaultFilter(e.detail.filter), showDefaultFilter: this.shouldShowDefaultFilter(e.detail.filter), filterItems: this.multiFilterItems, extraContent: this.extraHyperContent, extraBottomContent: this.extraBottomHyperContent });
1607
1619
  (_b = this.beforeshow) === null || _b === void 0 ? void 0 : _b.call(this, data);
1608
1620
  this.pop.show(data);
1609
1621
  }
1610
- getColumnFilter(type) {
1622
+ getColumnFilter(config) {
1623
+ const type = this.isColumnFilterOption(config) ? config.type : config;
1611
1624
  let filterType = 'string';
1612
1625
  if (!type) {
1613
1626
  return { [filterType]: this.filterByType[filterType] };
@@ -1627,6 +1640,41 @@ class FilterPlugin extends BasePlugin {
1627
1640
  }
1628
1641
  return { [filterType]: this.filterByType[filterType] };
1629
1642
  }
1643
+ /** Resolve the preferred operator against the column's available filters. */
1644
+ getDefaultFilter(config) {
1645
+ var _a;
1646
+ const filters = this.getColumnFilter(config);
1647
+ const availableFilters = Object.values(filters).flat();
1648
+ const columnDefault = this.isColumnFilterOption(config)
1649
+ ? config.default
1650
+ : undefined;
1651
+ if (typeof columnDefault === 'string' &&
1652
+ availableFilters.includes(columnDefault)) {
1653
+ return columnDefault;
1654
+ }
1655
+ const firstFamily = Object.keys(filters)[0];
1656
+ const familyDefault = filterTypeDefaults[firstFamily];
1657
+ if (familyDefault && ((_a = filters[firstFamily]) === null || _a === void 0 ? void 0 : _a.includes(familyDefault))) {
1658
+ return familyDefault;
1659
+ }
1660
+ return availableFilters[0];
1661
+ }
1662
+ /** Resolve grid and column-level draft opt-outs. */
1663
+ shouldShowDefaultFilter(config) {
1664
+ var _a;
1665
+ if (this.isColumnFilterOption(config)) {
1666
+ if (config.default === false) {
1667
+ return false;
1668
+ }
1669
+ if (typeof config.default === 'string') {
1670
+ return true;
1671
+ }
1672
+ }
1673
+ return ((_a = this.config) === null || _a === void 0 ? void 0 : _a.defaultFilter) !== false;
1674
+ }
1675
+ isColumnFilterOption(value) {
1676
+ return !!value && typeof value === 'object' && !Array.isArray(value);
1677
+ }
1630
1678
  isValidType(type) {
1631
1679
  return !!(typeof type === 'string' && this.filterByType[type]);
1632
1680
  }
@@ -3746,6 +3794,7 @@ exports.doCollapse = doCollapse;
3746
3794
  exports.doExpand = doExpand;
3747
3795
  exports.filterCoreFunctionsIndexedByType = filterCoreFunctionsIndexedByType;
3748
3796
  exports.filterNames = filterNames;
3797
+ exports.filterTypeDefaults = filterTypeDefaults;
3749
3798
  exports.filterTypes = filterTypes;
3750
3799
  exports.getColumnDragPosition = getColumnDragPosition;
3751
3800
  exports.getComparer = getComparer;
@@ -11,19 +11,20 @@ const HeaderRenderer = (p) => {
11
11
  const hasSortingSign = !!(((_a = p.data) === null || _a === void 0 ? void 0 : _a.sortable) ||
12
12
  ((_b = p.data) === null || _b === void 0 ? void 0 : _b.order) ||
13
13
  ((_c = p.data) === null || _c === void 0 ? void 0 : _c.sortIndex));
14
+ const hasFilterButton = !!(p.canFilter && ((_d = p.data) === null || _d === void 0 ? void 0 : _d.filter) !== false);
14
15
  const cellClass = {
15
16
  [HEADER_CLASS]: true,
16
- [HEADER_SORTABLE_CLASS]: !!((_d = p.data) === null || _d === void 0 ? void 0 : _d.sortable),
17
+ [HEADER_SORTABLE_CLASS]: !!((_e = p.data) === null || _e === void 0 ? void 0 : _e.sortable),
17
18
  };
18
- if ((_e = p.data) === null || _e === void 0 ? void 0 : _e.order) {
19
+ if ((_f = p.data) === null || _f === void 0 ? void 0 : _f.order) {
19
20
  cellClass[p.data.order] = true;
20
21
  }
21
22
  const dataProps = {
22
- key: String((_g = (_f = p.data) === null || _f === void 0 ? void 0 : _f.prop) !== null && _g !== void 0 ? _g : p.column.itemIndex),
23
+ key: String((_h = (_g = p.data) === null || _g === void 0 ? void 0 : _g.prop) !== null && _h !== void 0 ? _h : p.column.itemIndex),
23
24
  [DATA_COL]: p.column.itemIndex,
24
25
  canResize: p.canResize,
25
- minWidth: ((_h = p.data) === null || _h === void 0 ? void 0 : _h.minSize) || MIN_COL_SIZE,
26
- maxWidth: (_j = p.data) === null || _j === void 0 ? void 0 : _j.maxSize,
26
+ minWidth: ((_j = p.data) === null || _j === void 0 ? void 0 : _j.minSize) || MIN_COL_SIZE,
27
+ maxWidth: (_k = p.data) === null || _k === void 0 ? void 0 : _k.maxSize,
27
28
  active: p.active || ['r'],
28
29
  class: cellClass,
29
30
  style: {
@@ -59,6 +60,6 @@ const HeaderRenderer = (p) => {
59
60
  }
60
61
  }
61
62
  }
62
- return (h(HeaderCellRenderer, { data: p.data, props: dataProps, additionalData: p.additionalData }, hasSortingSign ? h(SortingSign, { column: p.data }) : null, p.canFilter && ((_k = p.data) === null || _k === void 0 ? void 0 : _k.filter) !== false ? (h(FilterButton, { column: p.data })) : ('')));
63
+ return (h(HeaderCellRenderer, { data: p.data, props: dataProps, additionalData: p.additionalData }, hasSortingSign || hasFilterButton ? (h("span", { class: "header-controls" }, hasSortingSign ? h(SortingSign, { column: p.data }) : null, hasFilterButton ? h(FilterButton, { column: p.data }) : null)) : null));
63
64
  };
64
65
  export default HeaderRenderer;
@@ -71,10 +71,15 @@ revogr-header .rgHeaderCell .header-content {
71
71
  white-space: nowrap;
72
72
  flex-grow: 1;
73
73
  }
74
- revogr-header .rgHeaderCell > span:first-of-type {
75
- position: relative;
74
+ revogr-header .rgHeaderCell .header-controls {
75
+ position: absolute;
76
+ top: 0;
77
+ right: 1px;
78
+ bottom: 1px;
79
+ min-width: 15px;
76
80
  z-index: 1;
77
- margin-left: auto;
81
+ display: flex;
82
+ align-items: center;
78
83
  }
79
84
  revogr-header .rgHeaderCell .resizable {
80
85
  display: block;
@@ -175,9 +175,16 @@ revo-grid[theme]:not([theme=default],
175
175
  [theme=dark],
176
176
  [theme=compact],
177
177
  [theme=darkCompact]) revogr-header .rgHeaderCell {
178
- padding: var(--rg-theme-header-padding);
178
+ padding: 0;
179
179
  text-overflow: ellipsis;
180
180
  }
181
+ revo-grid:is([theme=material], [theme=darkMaterial]) revogr-header .rgHeaderCell .header-content,
182
+ revo-grid[theme]:not([theme=default],
183
+ [theme=dark],
184
+ [theme=compact],
185
+ [theme=darkCompact]) revogr-header .rgHeaderCell .header-content {
186
+ padding: var(--rg-theme-header-padding);
187
+ }
181
188
  revo-grid:is([theme=material], [theme=darkMaterial]) revogr-header .header-rgRow,
182
189
  revo-grid[theme]:not([theme=default],
183
190
  [theme=dark],
@@ -264,9 +271,12 @@ revo-grid:is([theme=compact], [theme=darkCompact]) revogr-header {
264
271
  text-align: var(--rg-theme-header-text-align);
265
272
  }
266
273
  revo-grid:is([theme=compact], [theme=darkCompact]) revogr-header .rgHeaderCell {
267
- padding: var(--rg-theme-header-padding);
274
+ padding: 0;
268
275
  text-overflow: ellipsis;
269
276
  }
277
+ revo-grid:is([theme=compact], [theme=darkCompact]) revogr-header .rgHeaderCell .header-content {
278
+ padding: var(--rg-theme-header-padding);
279
+ }
270
280
  revo-grid:is([theme=compact], [theme=darkCompact]) revogr-header .header-rgRow {
271
281
  height: var(--rg-theme-header-height);
272
282
  }
@@ -9,9 +9,10 @@ export const AND_OR_BUTTON = 'and-or-button';
9
9
  export const TRASH_BUTTON = 'trash-button';
10
10
  export const REORDER_BUTTON = 'reorder-button';
11
11
  export const FilterButton = ({ column }) => {
12
- return (h("span", null, h("button", { class: {
12
+ const active = !!(column === null || column === void 0 ? void 0 : column[FILTER_PROP]);
13
+ return (h("span", { class: "filter-button-wrapper" }, h("button", { class: {
13
14
  [FILTER_BUTTON_CLASS]: true,
14
- [FILTER_BUTTON_ACTIVE]: column && !!column[FILTER_PROP],
15
+ [FILTER_BUTTON_ACTIVE]: active,
15
16
  } }, h("svg", { class: "filter-img", viewBox: "0 0 64 64" }, h("g", { stroke: "none", "stroke-width": "1", fill: "none", "fill-rule": "evenodd" }, h("path", { d: "M43,48 L43,56 L21,56 L21,48 L43,48 Z M53,28 L53,36 L12,36 L12,28 L53,28 Z M64,8 L64,16 L0,16 L0,8 L64,8 Z", fill: "currentColor" }))))));
16
17
  };
17
18
  export const TrashButton = ({ ariaLabel, onClick }) => {
@@ -32,6 +32,11 @@ export const filterTypes = {
32
32
  boolean: ['notEmpty', 'empty'],
33
33
  array: ['notEmpty', 'empty'],
34
34
  };
35
+ /** Preferred initial operator for built-in filter families. */
36
+ export const filterTypeDefaults = {
37
+ string: 'contains',
38
+ number: 'eqN',
39
+ };
35
40
  export const filterNames = {
36
41
  none: 'None',
37
42
  empty: 'Is blank',