vue2-excel-grid 2.8.8 → 2.9.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vue2-excel-grid",
3
- "version": "2.8.8",
3
+ "version": "2.9.0",
4
4
  "description": "Excel-style grid component for Vue 2.6.14 with virtual scrolling",
5
5
  "license": "MIT",
6
6
  "author": "Fozilbek Raimberdiyev",
@@ -244,8 +244,8 @@
244
244
  class="eg-header-cell"
245
245
  :class="[
246
246
  { 'eg-header-group': cell.isGroup, 'eg-header-cell--drag-source': colDrag.active && cell._firstLeafFlatIndex >= colDrag.sourceFirstLeaf && cell._firstLeafFlatIndex < colDrag.sourceFirstLeaf + colDrag.sourceLeafCount },
247
- cell.column && cell.column.overflowTitle === 'truncate' ? 'eg-header-cell--truncate' : '',
248
- cell.column && cell.column.overflowTitle === 'wrap' ? 'eg-header-cell--wrap' : ''
247
+ cell.column && (cell.column.overflowTitle || overflowTitle) === 'truncate' ? 'eg-header-cell--truncate' : '',
248
+ cell.column && (cell.column.overflowTitle || overflowTitle) === 'wrap' ? 'eg-header-cell--wrap' : ''
249
249
  ]"
250
250
  :data-fi="!cell.isGroup ? cell.column._flatIndex : undefined"
251
251
  :data-start="cell.isGroup ? cell._firstLeafFlatIndex : undefined"
@@ -254,6 +254,8 @@
254
254
  @mousedown="onColHeaderMouseDown($event, cell)"
255
255
  @dblclick="onColHeaderDblClick($event, cell)"
256
256
  @contextmenu.prevent="onColHeaderContextMenu($event, cell)"
257
+ @mouseenter="cell.column && (cell.column.overflowTitle || overflowTitle) === 'truncate' ? _showTooltip(cell.column.title, $event.currentTarget) : null"
258
+ @mouseleave="_hideTooltip"
257
259
  >
258
260
  <span class="eg-header-title">
259
261
  <slot v-if="!cell.isGroup" :name="'header-' + cell.column.key" :column="cell.column">
@@ -340,8 +342,8 @@
340
342
  class="eg-header-cell"
341
343
  :class="[
342
344
  { 'eg-header-group': cell.isGroup, 'eg-header-cell--drag-source': colDrag.active && cell._firstLeafFlatIndex >= colDrag.sourceFirstLeaf && cell._firstLeafFlatIndex < colDrag.sourceFirstLeaf + colDrag.sourceLeafCount },
343
- cell.column && cell.column.overflowTitle === 'truncate' ? 'eg-header-cell--truncate' : '',
344
- cell.column && cell.column.overflowTitle === 'wrap' ? 'eg-header-cell--wrap' : ''
345
+ cell.column && (cell.column.overflowTitle || overflowTitle) === 'truncate' ? 'eg-header-cell--truncate' : '',
346
+ cell.column && (cell.column.overflowTitle || overflowTitle) === 'wrap' ? 'eg-header-cell--wrap' : ''
345
347
  ]"
346
348
  :data-fi="!cell.isGroup ? cell.column._flatIndex : undefined"
347
349
  :data-start="cell.isGroup ? cell._firstLeafFlatIndex : undefined"
@@ -350,6 +352,8 @@
350
352
  @mousedown="onColHeaderMouseDown($event, cell)"
351
353
  @dblclick="onColHeaderDblClick($event, cell)"
352
354
  @contextmenu.prevent="onColHeaderContextMenu($event, cell)"
355
+ @mouseenter="cell.column && (cell.column.overflowTitle || overflowTitle) === 'truncate' ? _showTooltip(cell.column.title, $event.currentTarget) : null"
356
+ @mouseleave="_hideTooltip"
353
357
  >
354
358
  <span class="eg-header-title">
355
359
  <slot v-if="!cell.isGroup" :name="'header-' + cell.column.key" :column="cell.column">
@@ -433,8 +437,8 @@
433
437
  class="eg-header-cell"
434
438
  :class="[
435
439
  { 'eg-header-group': cell.isGroup, 'eg-header-cell--drag-source': colDrag.active && cell._firstLeafFlatIndex >= colDrag.sourceFirstLeaf && cell._firstLeafFlatIndex < colDrag.sourceFirstLeaf + colDrag.sourceLeafCount },
436
- cell.column && cell.column.overflowTitle === 'truncate' ? 'eg-header-cell--truncate' : '',
437
- cell.column && cell.column.overflowTitle === 'wrap' ? 'eg-header-cell--wrap' : ''
440
+ cell.column && (cell.column.overflowTitle || overflowTitle) === 'truncate' ? 'eg-header-cell--truncate' : '',
441
+ cell.column && (cell.column.overflowTitle || overflowTitle) === 'wrap' ? 'eg-header-cell--wrap' : ''
438
442
  ]"
439
443
  :data-fi="!cell.isGroup ? cell.column._flatIndex : undefined"
440
444
  :data-start="cell.isGroup ? cell._firstLeafFlatIndex : undefined"
@@ -443,6 +447,8 @@
443
447
  @mousedown="onColHeaderMouseDown($event, cell)"
444
448
  @dblclick="onColHeaderDblClick($event, cell)"
445
449
  @contextmenu.prevent="onColHeaderContextMenu($event, cell)"
450
+ @mouseenter="cell.column && (cell.column.overflowTitle || overflowTitle) === 'truncate' ? _showTooltip(cell.column.title, $event.currentTarget) : null"
451
+ @mouseleave="_hideTooltip"
446
452
  >
447
453
  <span class="eg-header-title">
448
454
  <slot v-if="!cell.isGroup" :name="'header-' + cell.column.key" :column="cell.column">
@@ -527,6 +533,7 @@
527
533
  v-if="!isRowHidden(ri)"
528
534
  :key="'srh-' + ri"
529
535
  class="eg-row-header-cell"
536
+ :class="{ 'eg-row--active': activeCell && activeCell.row === ri }"
530
537
  :style="getRowHeaderStyle(ri)"
531
538
  :data-row="ri"
532
539
  @mousedown="onRowHeaderMouseDown($event, ri)"
@@ -569,7 +576,7 @@
569
576
  <div :style="{ height: totalVirtualHeight + 'px', position: 'relative' }">
570
577
  <div :style="{ transform: 'translateY(' + virtualOffsetTop + 'px)', willChange: 'transform', contain: 'layout style' }">
571
578
  <template v-for="ri in visibleRowRange">
572
- <div v-if="!isRowHidden(ri)" :key="'fc-row-' + ri" class="eg-row" :class="{ 'eg-row--even': ri % 2 === 0 }" :style="getRowStyle(ri)" :data-row="ri">
579
+ <div v-if="!isRowHidden(ri)" :key="'fc-row-' + ri" class="eg-row" :class="{ 'eg-row--even': ri % 2 === 0, 'eg-row--active': activeCell && activeCell.row === ri }" :style="getRowStyle(ri)" :data-row="ri">
573
580
  <template v-for="(col, ci) in leafCols">
574
581
  <template v-if="isColumnPinnedLeft(ci) && !isColHidden(ci)">
575
582
  <div
@@ -625,7 +632,7 @@
625
632
  v-if="!isRowHidden(ri)"
626
633
  :key="'row-' + ri"
627
634
  class="eg-row"
628
- :class="{ 'eg-row--even': ri % 2 === 0 }"
635
+ :class="{ 'eg-row--even': ri % 2 === 0, 'eg-row--active': activeCell && activeCell.row === ri }"
629
636
  :style="getRowStyle(ri)"
630
637
  :data-row="ri"
631
638
  >
@@ -688,7 +695,7 @@
688
695
  <div :style="{ height: totalVirtualHeight + 'px', position: 'relative' }">
689
696
  <div :style="{ transform: 'translateY(' + virtualOffsetTop + 'px)', willChange: 'transform', contain: 'layout style' }">
690
697
  <template v-for="ri in visibleRowRange">
691
- <div v-if="!isRowHidden(ri)" :key="'pr-row-' + ri" class="eg-row" :class="{ 'eg-row--even': ri % 2 === 0 }" :style="getRowStyle(ri)" :data-row="ri">
698
+ <div v-if="!isRowHidden(ri)" :key="'pr-row-' + ri" class="eg-row" :class="{ 'eg-row--even': ri % 2 === 0, 'eg-row--active': activeCell && activeCell.row === ri }" :style="getRowStyle(ri)" :data-row="ri">
692
699
  <template v-for="col in pinnedRightCols">
693
700
  <div
694
701
  :key="'pr-cell-' + ri + '-' + col._flatIndex"
@@ -966,6 +973,7 @@
966
973
  >{{ colDrag.ghostLabel }}</div>
967
974
 
968
975
  </div>
976
+ <div v-if="hoverTooltip" class="eg-option-tooltip" :style="hoverTooltipStyle">{{ hoverTooltip.text }}</div>
969
977
  </div>
970
978
  </template>
971
979
 
@@ -1064,6 +1072,19 @@ const ExcelGridComponent = {
1064
1072
  /** Array of row objects keyed by columns[].key */
1065
1073
  data: { type: Array, default: () => [] },
1066
1074
 
1075
+ /**
1076
+ * Sarlavhalardagi matn sig'may qolganda uning qanday harakatlanishini belgilaydi
1077
+ * (barcha ustunlar uchun umumiy qoida). Ustun (column) sozlamalarida
1078
+ * xuddi shu nomli xususiyat mavjud bo'lsa, ustun sozlamasi inobatga olinadi.
1079
+ * @type {String}
1080
+ * @default 'no-overflow'
1081
+ */
1082
+ overflowTitle: {
1083
+ type: String,
1084
+ default: 'no-overflow',
1085
+ validator: v => ['no-overflow', 'truncate', 'wrap'].includes(v)
1086
+ },
1087
+
1067
1088
  /**
1068
1089
  * Column definitions (may be nested via children[]).
1069
1090
  *
@@ -1615,6 +1636,8 @@ const ExcelGridComponent = {
1615
1636
  data() {
1616
1637
  return {
1617
1638
  calculatedHeaderHeight: null,
1639
+ hoverTooltip: null,
1640
+ _tooltipTimer: null,
1618
1641
  // Selection
1619
1642
  activeCell: { row: 0, col: 0 },
1620
1643
  selectionRanges: [], // [{ startRow, startCol, endRow, endCol }]
@@ -1812,6 +1835,15 @@ const ExcelGridComponent = {
1812
1835
  },
1813
1836
 
1814
1837
  computed: {
1838
+ hoverTooltipStyle() {
1839
+ if (!this.hoverTooltip) return {}
1840
+ const { rect, text } = this.hoverTooltip
1841
+ const estH = 20 + Math.ceil(text.length / 40) * 16
1842
+ const spaceBelow = window.innerHeight - rect.bottom
1843
+ const top = spaceBelow >= estH + 8 ? rect.bottom + 6 : rect.top - estH - 6
1844
+ const left = Math.min(rect.left, window.innerWidth - 280 - 8)
1845
+ return { position: 'fixed', top: top + 'px', left: Math.max(8, left) + 'px', zIndex: 10000 }
1846
+ },
1815
1847
  t() { return getMessages(this.locale) },
1816
1848
 
1817
1849
  // localSyncKey feature — the actual IndexedDB storage key. idbStore.js
@@ -2803,9 +2835,27 @@ const ExcelGridComponent = {
2803
2835
  },
2804
2836
 
2805
2837
  methods: {
2838
+ _showTooltip(text, el) {
2839
+ this._clearTooltipTimer()
2840
+ if (!text) return
2841
+ const rect = el.getBoundingClientRect()
2842
+ this._tooltipTimer = setTimeout(() => {
2843
+ this.hoverTooltip = { text, rect }
2844
+ }, 400)
2845
+ },
2846
+ _hideTooltip() {
2847
+ this._clearTooltipTimer()
2848
+ this.hoverTooltip = null
2849
+ },
2850
+ _clearTooltipTimer() {
2851
+ if (this._tooltipTimer) {
2852
+ clearTimeout(this._tooltipTimer)
2853
+ this._tooltipTimer = null
2854
+ }
2855
+ },
2806
2856
  _calcHeaderHeight() {
2807
2857
  if (!this.leafCols) return
2808
- const wrapCols = this.leafCols.filter(c => c.overflowTitle === 'wrap')
2858
+ const wrapCols = this.leafCols.filter(c => (c.overflowTitle || this.overflowTitle) === 'wrap')
2809
2859
  if (wrapCols.length === 0) {
2810
2860
  if (this.calculatedHeaderHeight !== null) this.calculatedHeaderHeight = null
2811
2861
  return
@@ -8635,11 +8685,13 @@ export default ExcelGridComponent
8635
8685
  background: var(--eg-color-row-stripe, var(--eg-color-row-stripe-default));
8636
8686
  }
8637
8687
  .eg-row:hover .eg-cell:not(.eg-cell-selected):not(.eg-cell-active):not(.eg-cell-fill-preview),
8638
- .eg-row.eg-row--hover .eg-cell:not(.eg-cell-selected):not(.eg-cell-active):not(.eg-cell-fill-preview) {
8688
+ .eg-row.eg-row--hover .eg-cell:not(.eg-cell-selected):not(.eg-cell-active):not(.eg-cell-fill-preview),
8689
+ .eg-row.eg-row--active .eg-cell:not(.eg-cell-selected):not(.eg-cell-active):not(.eg-cell-fill-preview) {
8639
8690
  background: var(--eg-color-row-hover, var(--eg-color-row-hover-default)) !important;
8640
8691
  }
8641
8692
  .eg-row-header-cell:hover,
8642
- .eg-row-header-cell.eg-row--hover {
8693
+ .eg-row-header-cell.eg-row--hover,
8694
+ .eg-row-header-cell.eg-row--active {
8643
8695
  background: var(--eg-color-row-hover, var(--eg-color-row-hover-default)) !important;
8644
8696
  }
8645
8697
 
package/src/index.js CHANGED
@@ -8,7 +8,19 @@ export { ExcelGrid, EgCheckbox, EgSelect, EgTreeSelect, version }
8
8
 
9
9
  export default {
10
10
  version,
11
- install(Vue) {
11
+ install(Vue, options = {}) {
12
+ if (options && typeof options === 'object') {
13
+ Object.keys(options).forEach(key => {
14
+ if (ExcelGrid.props && ExcelGrid.props[key] !== undefined) {
15
+ const val = options[key]
16
+ if (typeof ExcelGrid.props[key] !== 'object') {
17
+ // Convert to object notation if it was just a constructor like `props: { fitColumns: Boolean }`
18
+ ExcelGrid.props[key] = { type: ExcelGrid.props[key] }
19
+ }
20
+ ExcelGrid.props[key].default = (val !== null && typeof val === 'object') ? () => val : val
21
+ }
22
+ })
23
+ }
12
24
  Vue.component('Vue2ExcelGrid', ExcelGrid)
13
25
  Vue.component('Vue2EgCheckbox', EgCheckbox)
14
26
  Vue.component('Vue2EgSelect', EgSelect)