vue2-excel-grid 2.1.0 → 2.2.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.1.0",
3
+ "version": "2.2.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",
@@ -57,6 +57,9 @@
57
57
  {{ opt.label }}
58
58
  </div>
59
59
  <div v-if="!filteredOptions.length" class="eg-select-empty">{{ t.noOptions }}</div>
60
+ <div v-if="clearable && selectedOpt" class="eg-select-footer">
61
+ <button class="eg-select-btn eg-select-btn--clear" tabindex="-1" @mousedown.prevent="pickClear">{{ t.clear }}</button>
62
+ </div>
60
63
  </template>
61
64
 
62
65
  <!-- Options panel in standalone mode (floating dropdown below trigger) -->
@@ -97,6 +100,9 @@
97
100
  {{ opt.label }}
98
101
  </div>
99
102
  <div v-if="!filteredOptions.length" class="eg-select-empty">{{ t.noOptions }}</div>
103
+ <div v-if="clearable && selectedOpt" class="eg-select-footer">
104
+ <button class="eg-select-btn eg-select-btn--clear" tabindex="-1" @mousedown.prevent="pickClear">{{ t.clear }}</button>
105
+ </div>
100
106
  </div>
101
107
 
102
108
  <div v-if="hoverTooltip" class="eg-option-tooltip" :style="hoverTooltipStyle">{{ hoverTooltip.text }}</div>
@@ -129,7 +135,8 @@ export default {
129
135
  dropdownOnly: { type: Boolean, default: false },
130
136
  triggerRect: { type: Object, default: null },
131
137
  size: { type: String, default: 'middle' },
132
- locale: { type: String, default: 'en' }
138
+ locale: { type: String, default: 'en' },
139
+ clearable: { type: Boolean, default: true }
133
140
  },
134
141
  data() {
135
142
  return {
@@ -239,6 +246,11 @@ export default {
239
246
  this.highlight = -1
240
247
  }
241
248
  },
249
+ // Reuses pickOption's write path (same input/select emit + dropdown-close
250
+ // handling) — a clear is just "pick the empty option", not a separate flow.
251
+ pickClear() {
252
+ this.pickOption({ value: '', label: '' })
253
+ },
242
254
  onSearch(e) {
243
255
  this._hideTooltip()
244
256
  this.searchQuery = e.target.value
@@ -535,6 +547,29 @@ export default {
535
547
  margin-top: 3px;
536
548
  }
537
549
 
550
+ /* "Clear" footer — same recipe as EgDatePicker.vue's .eg-dp-footer/.eg-dp-btn,
551
+ just a single right-aligned button (no "Today" equivalent here). Also
552
+ duplicated in ExcelGrid.vue's own <style> — see the comment above
553
+ .eg-select-wrapper there for why, and keep both copies token-identical. */
554
+ .eg-select-footer {
555
+ display: flex;
556
+ justify-content: flex-end;
557
+ padding: 4px 6px 6px;
558
+ border-top: 1px solid var(--eg-color-border, var(--eg-color-border-default));
559
+ }
560
+ .eg-select-btn {
561
+ background: none;
562
+ border: 1px solid var(--eg-color-border, var(--eg-color-border-default));
563
+ border-radius: var(--eg-radius, var(--eg-radius-default));
564
+ padding: 4px 10px;
565
+ cursor: pointer;
566
+ font-size: 12px;
567
+ color: var(--eg-color-text, var(--eg-color-text-default));
568
+ }
569
+ .eg-select-btn:hover { background: var(--eg-color-option-hover-bg, var(--eg-color-option-hover-bg-default)); }
570
+ .eg-select-btn--clear { color: var(--eg-color-danger, #c62828); border-color: var(--eg-color-danger, #f1b0b0); }
571
+ .eg-select-btn--clear:hover { background: #fff0f0; }
572
+
538
573
  /* Themed option/trigger tooltip — same recipe as .eg-select-dropdown
539
574
  (cell-bg/border/radius) plus .eg-validation-tooltip's shadow, so it reads
540
575
  as part of the grid's own chrome in every built-in theme instead of a
@@ -63,6 +63,9 @@
63
63
  {{ opt.label }}
64
64
  </div>
65
65
  <div v-if="!filteredOptions.length" class="eg-select-empty">{{ t.noOptions }}</div>
66
+ <div v-if="clearable && selectedLabel != null" class="eg-select-footer">
67
+ <button class="eg-select-btn eg-select-btn--clear" tabindex="-1" @mousedown.prevent="pickClear">{{ t.clear }}</button>
68
+ </div>
66
69
  </template>
67
70
 
68
71
  <!-- Options panel in standalone mode -->
@@ -110,6 +113,9 @@
110
113
  {{ opt.label }}
111
114
  </div>
112
115
  <div v-if="!filteredOptions.length" class="eg-select-empty">{{ t.noOptions }}</div>
116
+ <div v-if="clearable && selectedLabel != null" class="eg-select-footer">
117
+ <button class="eg-select-btn eg-select-btn--clear" tabindex="-1" @mousedown.prevent="pickClear">{{ t.clear }}</button>
118
+ </div>
113
119
  </div>
114
120
 
115
121
  <div v-if="hoverTooltip" class="eg-option-tooltip" :style="hoverTooltipStyle">{{ hoverTooltip.text }}</div>
@@ -140,7 +146,8 @@ export default {
140
146
  dropdownOnly: { type: Boolean, default: false },
141
147
  triggerRect: { type: Object, default: null },
142
148
  size: { type: String, default: 'middle' },
143
- locale: { type: String, default: 'en' }
149
+ locale: { type: String, default: 'en' },
150
+ clearable: { type: Boolean, default: true }
144
151
  },
145
152
  data() {
146
153
  return {
@@ -269,6 +276,11 @@ export default {
269
276
  this.highlight = -1
270
277
  }
271
278
  },
279
+ // Reuses pickOption's write path (same input/select emit + dropdown-close
280
+ // handling) — a clear is just "pick the empty option", not a separate flow.
281
+ pickClear() {
282
+ this.pickOption({ value: '', label: '' })
283
+ },
272
284
  toggleNode(idx) {
273
285
  const opt = this.flatOptions[idx]
274
286
  if (!opt || !opt.hasChildren) return
@@ -854,6 +854,7 @@
854
854
  :dropdown-only="true"
855
855
  :size="internalSize"
856
856
  :locale="locale"
857
+ :clearable="selectDropdown.clearable"
857
858
  @select="onComponentSelect"
858
859
  @close="closeSelectDropdown"
859
860
  />
@@ -871,6 +872,7 @@
871
872
  :dropdown-only="true"
872
873
  :size="internalSize"
873
874
  :locale="locale"
875
+ :clearable="selectDropdown.clearable"
874
876
  @select="onComponentSelect"
875
877
  @close="closeSelectDropdown"
876
878
  />
@@ -4298,7 +4300,8 @@ const ExcelGridComponent = {
4298
4300
  rawOptions: this.resolveOptionsArray(col, ri, ci),
4299
4301
  currentValue,
4300
4302
  rect: rectObj,
4301
- enableSearch: !!col.enableSearch
4303
+ enableSearch: !!col.enableSearch,
4304
+ clearable: col.clearable !== false
4302
4305
  }
4303
4306
  },
4304
4307
 
@@ -4330,7 +4333,10 @@ const ExcelGridComponent = {
4330
4333
  const { row, col } = this.selectDropdown
4331
4334
  const colDef = this.leafCols[col]
4332
4335
  if (colDef) {
4333
- if (!this.isCellValueValid(row, col, value)) {
4336
+ // Clearing (value === '') always goes through, same as onDatePick()'s
4337
+ // empty-string bypass — "no selection" is a valid state regardless of
4338
+ // what cellValidator requires of a real picked value.
4339
+ if (value !== '' && !this.isCellValueValid(row, col, value)) {
4334
4340
  this._showInvalidCell(row, col, value)
4335
4341
  this.closeSelectDropdown()
4336
4342
  return
@@ -8268,6 +8274,24 @@ export default ExcelGridComponent
8268
8274
  word-break: break-word;
8269
8275
  z-index: 10000;
8270
8276
  }
8277
+ .eg-select-footer {
8278
+ display: flex;
8279
+ justify-content: flex-end;
8280
+ padding: 4px 6px 6px;
8281
+ border-top: 1px solid var(--eg-color-border, var(--eg-color-border-default));
8282
+ }
8283
+ .eg-select-btn {
8284
+ background: none;
8285
+ border: 1px solid var(--eg-color-border, var(--eg-color-border-default));
8286
+ border-radius: var(--eg-radius, var(--eg-radius-default));
8287
+ padding: 4px 10px;
8288
+ cursor: pointer;
8289
+ font-size: 12px;
8290
+ color: var(--eg-color-text, var(--eg-color-text-default));
8291
+ }
8292
+ .eg-select-btn:hover { background: var(--eg-color-option-hover-bg, var(--eg-color-option-hover-bg-default)); }
8293
+ .eg-select-btn--clear { color: var(--eg-color-danger, #c62828); border-color: var(--eg-color-danger, #f1b0b0); }
8294
+ .eg-select-btn--clear:hover { background: #fff0f0; }
8271
8295
  /* Grid `size` overrides — must live in this *unscoped* style block, not the
8272
8296
  scoped one above: .eg-select-option is rendered by the separate EgSelect /
8273
8297
  EgTreeSelect components, so Vue's scoped-CSS attribute (added only to this