@kodaris/krubble-components 1.0.55 → 1.0.56

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.
@@ -4065,6 +4065,7 @@
4065
4065
  this._filterPanelTab = 'filter';
4066
4066
  this._buckets = new Map();
4067
4067
  this._filterPanelPos = { top: 0, left: 0 };
4068
+ this._sorts = [];
4068
4069
  this._resizing = null;
4069
4070
  this._resizeObserver = null;
4070
4071
  this._searchPositionLocked = false;
@@ -4254,7 +4255,7 @@
4254
4255
  const request = {
4255
4256
  page: this._page - 1,
4256
4257
  size: this._pageSize,
4257
- sorts: [],
4258
+ sorts: this._sorts,
4258
4259
  filterFields: [],
4259
4260
  queryFields: [],
4260
4261
  facetFields: []
@@ -4294,7 +4295,7 @@
4294
4295
  const request = {
4295
4296
  page: this._page - 1,
4296
4297
  size: this._pageSize,
4297
- sorts: [],
4298
+ sorts: this._sorts,
4298
4299
  filterFields: [],
4299
4300
  queryFields: [],
4300
4301
  facetFields: []
@@ -4593,6 +4594,77 @@
4593
4594
  document.addEventListener('mouseup', this._handleResizeEnd);
4594
4595
  }
4595
4596
  // ----------------------------------------------------------------------------
4597
+ // Sorting
4598
+ // ----------------------------------------------------------------------------
4599
+ _handleSortClick(e, column) {
4600
+ if (e.shiftKey) {
4601
+ // Multi-sort: add or cycle existing
4602
+ const existingIndex = this._sorts.findIndex(s => s.sortBy === column.id);
4603
+ if (existingIndex === -1) {
4604
+ this._sorts.push({ sortBy: column.id, sortDirection: 'asc' });
4605
+ }
4606
+ else {
4607
+ const existing = this._sorts[existingIndex];
4608
+ if (existing.sortDirection === 'asc') {
4609
+ existing.sortDirection = 'desc';
4610
+ }
4611
+ else {
4612
+ // on third click, remove sorting for the column
4613
+ this._sorts.splice(existingIndex, 1);
4614
+ }
4615
+ }
4616
+ this.requestUpdate();
4617
+ }
4618
+ else {
4619
+ // Single sort: replace all
4620
+ let existing = null;
4621
+ if (this._sorts.length === 1) {
4622
+ existing = this._sorts.find(s => s.sortBy === column.id);
4623
+ }
4624
+ if (!existing) {
4625
+ this._sorts = [{ sortBy: column.id, sortDirection: 'asc' }];
4626
+ }
4627
+ else if (existing.sortDirection === 'asc') {
4628
+ this._sorts = [{ sortBy: column.id, sortDirection: 'desc' }];
4629
+ }
4630
+ else {
4631
+ this._sorts = [];
4632
+ }
4633
+ }
4634
+ this._page = 1;
4635
+ this._fetch();
4636
+ }
4637
+ _renderSortIndicator(column) {
4638
+ if (!column.sortable) {
4639
+ return A;
4640
+ }
4641
+ const sortIndex = this._sorts.findIndex(s => s.sortBy === column.id);
4642
+ if (sortIndex === -1) {
4643
+ // Ghost arrow: visible only on hover via CSS
4644
+ return b `
4645
+ <span class="header-cell__sort" @click=${(e) => this._handleSortClick(e, column)}>
4646
+ <svg class="header-cell__sort-arrow header-cell__sort-arrow--ghost" viewBox="0 0 24 24" fill="currentColor">
4647
+ <path d="M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z"/>
4648
+ </svg>
4649
+ </span>
4650
+ `;
4651
+ }
4652
+ let arrowStyle = {};
4653
+ if (this._sorts[sortIndex].sortDirection === 'desc') {
4654
+ arrowStyle = { transform: 'rotate(180deg)' };
4655
+ }
4656
+ return b `
4657
+ <span class="header-cell__sort" @click=${(e) => this._handleSortClick(e, column)}>
4658
+ <svg class="header-cell__sort-arrow" viewBox="0 0 24 24" fill="currentColor" style=${o$1(arrowStyle)}>
4659
+ <path d="M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z"/>
4660
+ </svg>
4661
+ ${this._sorts.length > 1 ? b `
4662
+ <span class="header-cell__sort-priority">${sortIndex + 1}</span>
4663
+ ` : A}
4664
+ </span>
4665
+ `;
4666
+ }
4667
+ // ----------------------------------------------------------------------------
4596
4668
  // Header
4597
4669
  // ----------------------------------------------------------------------------
4598
4670
  _handleAction(action) {
@@ -4786,6 +4858,7 @@
4786
4858
  _getHeaderCellClasses(column, index) {
4787
4859
  return {
4788
4860
  'header-cell': true,
4861
+ 'header-cell--sortable': !!column.sortable,
4789
4862
  'header-cell--align-center': column.align === 'center',
4790
4863
  'header-cell--align-right': column.align === 'right',
4791
4864
  'header-cell--sticky-left': column.sticky === 'left',
@@ -5273,10 +5346,14 @@
5273
5346
  class=${e$1(this._getHeaderCellClasses(col, i))}
5274
5347
  style=${o$1(this._getCellStyle(col, i))}
5275
5348
  data-column-id=${col.id}
5276
- >${col.label ?? col.id}${col.resizable !== false ? b `<div
5349
+ >
5350
+ <span class="header-cell__label">${col.label ?? col.id}</span>
5351
+ ${this._renderSortIndicator(col)}
5352
+ ${col.resizable !== false ? b `<div
5277
5353
  class="header-cell__resize"
5278
5354
  @mousedown=${(e) => this._handleResizeStart(e, col.id)}
5279
- ></div>` : A}</div>
5355
+ ></div>` : A}
5356
+ </div>
5280
5357
  `)}
5281
5358
  </div>
5282
5359
  ${this._renderFilterRow()}
@@ -5685,9 +5762,7 @@
5685
5762
  .header-cell {
5686
5763
  position: sticky;
5687
5764
  top: 0;
5688
- z-index: 2;
5689
5765
  height: 48px;
5690
- line-height: 48px;
5691
5766
  padding: 0 16px;
5692
5767
  white-space: nowrap;
5693
5768
  box-sizing: border-box;
@@ -5697,8 +5772,8 @@
5697
5772
  border-right: 1px solid #e5e7ebba;
5698
5773
  font-weight: 600;
5699
5774
  color: #374151;
5700
- overflow: hidden;
5701
- text-overflow: ellipsis;
5775
+ display: flex;
5776
+ align-items: center;
5702
5777
  }
5703
5778
 
5704
5779
  .header-cell__resize {
@@ -5708,21 +5783,52 @@
5708
5783
  bottom: 0;
5709
5784
  width: 14px;
5710
5785
  cursor: col-resize;
5786
+ z-index: 10;
5787
+ }
5788
+
5789
+ .header-cell--sortable {
5790
+ user-select: none;
5791
+ }
5792
+
5793
+ .header-cell__label {
5794
+ overflow: hidden;
5795
+ text-overflow: ellipsis;
5796
+ min-width: 0;
5797
+ line-height: 48px;
5798
+ }
5799
+
5800
+ .header-cell__sort {
5801
+ flex-grow: 1;
5711
5802
  display: flex;
5712
5803
  align-items: center;
5713
- justify-content: center;
5714
- z-index: 10;
5804
+ height: 100%;
5805
+ margin-left: 6px;
5806
+ cursor: pointer;
5715
5807
  }
5716
5808
 
5717
- .header-cell__resize::after {
5718
- content: '';
5719
- width: 2px;
5720
- height: 20px;
5721
- background: #c6c6cd;
5809
+ .header-cell__sort-arrow {
5810
+ width: 16px;
5811
+ height: 16px;
5812
+ color: #374151;
5813
+ stroke: currentColor;
5814
+ stroke-width: 1px;
5722
5815
  }
5723
5816
 
5724
- .header-cell:last-child .header-cell__resize::after {
5725
- display: none;
5817
+ .header-cell__sort-arrow--ghost {
5818
+ opacity: 0;
5819
+ color: #374151;
5820
+ transition: opacity 0.15s;
5821
+ }
5822
+
5823
+ .header-cell--sortable:hover .header-cell__sort-arrow--ghost {
5824
+ opacity: 0.4;
5825
+ }
5826
+
5827
+ .header-cell__sort-priority {
5828
+ font-size: 10px;
5829
+ font-weight: 600;
5830
+ color: #374151;
5831
+ line-height: 1;
5726
5832
  }
5727
5833
 
5728
5834
  .cell {
@@ -6188,6 +6294,9 @@
6188
6294
  __decorate$9([
6189
6295
  r$1()
6190
6296
  ], exports.KRTable.prototype, "_buckets", void 0);
6297
+ __decorate$9([
6298
+ r$1()
6299
+ ], exports.KRTable.prototype, "_sorts", void 0);
6191
6300
  __decorate$9([
6192
6301
  n$1({ type: Object })
6193
6302
  ], exports.KRTable.prototype, "def", void 0);