vue2-excel-grid 2.9.0 → 2.11.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.9.0",
3
+ "version": "2.11.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",
@@ -60,6 +60,9 @@
60
60
  <div v-if="clearable && selectedOpt" class="eg-select-footer">
61
61
  <button class="eg-select-btn eg-select-btn--clear" tabindex="-1" @mousedown.prevent="pickClear">{{ t.clear }}</button>
62
62
  </div>
63
+ <div v-if="$slots['dropdown-footer']" class="eg-select-dropdown-footer">
64
+ <slot name="dropdown-footer"></slot>
65
+ </div>
63
66
  </template>
64
67
 
65
68
  <!-- Options panel in standalone mode (floating dropdown below trigger) -->
@@ -103,6 +106,9 @@
103
106
  <div v-if="clearable && selectedOpt" class="eg-select-footer">
104
107
  <button class="eg-select-btn eg-select-btn--clear" tabindex="-1" @mousedown.prevent="pickClear">{{ t.clear }}</button>
105
108
  </div>
109
+ <div v-if="$slots['dropdown-footer']" class="eg-select-dropdown-footer">
110
+ <slot name="dropdown-footer"></slot>
111
+ </div>
106
112
  </div>
107
113
 
108
114
  <div v-if="hoverTooltip" class="eg-option-tooltip" :style="hoverTooltipStyle">{{ hoverTooltip.text }}</div>
@@ -557,6 +563,10 @@ export default {
557
563
  padding: 4px 6px 6px;
558
564
  border-top: 1px solid var(--eg-color-border, var(--eg-color-border-default));
559
565
  }
566
+ .eg-select-dropdown-footer {
567
+ border-top: 1px solid var(--eg-color-border, var(--eg-color-border-default));
568
+ padding: 4px;
569
+ }
560
570
  .eg-select-btn {
561
571
  background: none;
562
572
  border: 1px solid var(--eg-color-border, var(--eg-color-border-default));
@@ -66,6 +66,9 @@
66
66
  <div v-if="clearable && selectedLabel != null" class="eg-select-footer">
67
67
  <button class="eg-select-btn eg-select-btn--clear" tabindex="-1" @mousedown.prevent="pickClear">{{ t.clear }}</button>
68
68
  </div>
69
+ <div v-if="$slots['dropdown-footer']" class="eg-select-dropdown-footer">
70
+ <slot name="dropdown-footer"></slot>
71
+ </div>
69
72
  </template>
70
73
 
71
74
  <!-- Options panel in standalone mode -->
@@ -116,6 +119,9 @@
116
119
  <div v-if="clearable && selectedLabel != null" class="eg-select-footer">
117
120
  <button class="eg-select-btn eg-select-btn--clear" tabindex="-1" @mousedown.prevent="pickClear">{{ t.clear }}</button>
118
121
  </div>
122
+ <div v-if="$slots['dropdown-footer']" class="eg-select-dropdown-footer">
123
+ <slot name="dropdown-footer"></slot>
124
+ </div>
119
125
  </div>
120
126
 
121
127
  <div v-if="hoverTooltip" class="eg-option-tooltip" :style="hoverTooltipStyle">{{ hoverTooltip.text }}</div>
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div
3
3
  class="eg-shell"
4
- :class="['eg-size-' + internalSize, 'eg-theme-' + internalTheme, { 'eg-shell-fullscreen': isFullscreen, 'eg-locked': internalLocked }]"
4
+ :class="['eg-size-' + internalSize, 'eg-theme-' + internalTheme, { 'eg-shell-fullscreen': isFullscreen, 'eg-locked': internalLocked, 'eg-dark': isDarkMode }]"
5
5
  :style="shellStyle"
6
6
  >
7
7
  <!-- Toolbar -->
@@ -97,6 +97,7 @@
97
97
  <option value="antd">Ant Design</option>
98
98
  <option value="fluent">Fluent</option>
99
99
  <option value="carbon">Carbon</option>
100
+ <option value="polaris">Shopify Polaris</option>
100
101
  </select>
101
102
  </div>
102
103
 
@@ -917,7 +918,11 @@
917
918
  :clearable="selectDropdown.clearable"
918
919
  @select="onComponentSelect"
919
920
  @close="closeSelectDropdown"
920
- />
921
+ >
922
+ <template #dropdown-footer>
923
+ <slot :name="'dropdown-footer-' + selectDropdown.col.key" :column="selectDropdown.col" :close="closeSelectDropdown"></slot>
924
+ </template>
925
+ </eg-select>
921
926
  <!-- Tree select dropdown overlay -->
922
927
  <eg-tree-select
923
928
  v-if="selectDropdown && selectDropdown.tree"
@@ -935,7 +940,11 @@
935
940
  :clearable="selectDropdown.clearable"
936
941
  @select="onComponentSelect"
937
942
  @close="closeSelectDropdown"
938
- />
943
+ >
944
+ <template #dropdown-footer>
945
+ <slot :name="'dropdown-footer-' + selectDropdown.col.key" :column="selectDropdown.col" :close="closeSelectDropdown"></slot>
946
+ </template>
947
+ </eg-tree-select>
939
948
 
940
949
  <!-- Date picker overlay -->
941
950
  <eg-date-picker
@@ -1012,6 +1021,7 @@ import { formatNumber as _formatNumber } from '../utils/numberFormat.js'
1012
1021
  import { Mask, MaskInput } from '../utils/mask.js'
1013
1022
  import { listVersions, getVersion, deleteVersion, saveOrTouchVersion, putBuffer, getBuffer, clearBuffer } from '../utils/idbStore.js'
1014
1023
  import { hashRows, hashRowsAsync } from '../utils/dataHash.js'
1024
+ import { globalConfig } from '../config.js'
1015
1025
 
1016
1026
  const SIZE_CONFIG = {
1017
1027
  small: { row: 22, header: 24, footer: 24, filter: 26 },
@@ -1051,7 +1061,7 @@ const DEFAULT_TOOLBAR_LIST = ['undoRedo', 'export', 'import', 'print', 'localSyn
1051
1061
  // retarget smoothly from whatever intermediate position an element is currently
1052
1062
  // at when the drop slot changes mid-flight — no JS animation library races.
1053
1063
  const COL_DRAG_TRANSITION = 'transform 200ms cubic-bezier(0.2, 0, 0, 1)'
1054
- const THEME_LIST = ['excel', 'material', 'antd', 'fluent', 'carbon']
1064
+ const THEME_LIST = ['excel', 'material', 'antd', 'fluent', 'carbon', 'polaris']
1055
1065
 
1056
1066
  // Kept as a named const (rather than an inline `export default {}`) so the
1057
1067
  // local-sync preview modal can receive the plain component definition
@@ -1456,7 +1466,7 @@ const ExcelGridComponent = {
1456
1466
 
1457
1467
  /**
1458
1468
  * Visual theme of the grid.
1459
- * Built-in: 'excel' | 'material' | 'antd' | 'fluent' | 'carbon'
1469
+ * Built-in: 'excel' | 'material' | 'antd' | 'fluent' | 'carbon' | 'polaris'
1460
1470
  * Default is the classic Excel 365 look. Use 'material' for Material Design 3.
1461
1471
  * Mirrors the `size` prop's convention: an internal `internalTheme` state
1462
1472
  * mirrors this prop and is what the toolbar's theme picker actually reads
@@ -1466,6 +1476,15 @@ const ExcelGridComponent = {
1466
1476
  */
1467
1477
  theme: { type: String, default: 'antd' },
1468
1478
 
1479
+ /**
1480
+ * Dark mode toggle.
1481
+ * - `true`: enables dark mode styling and sets `color-scheme: dark`.
1482
+ * - `false`: forces light mode styling and sets `color-scheme: light` (prevents OS dark mode leak).
1483
+ * - `null` / `undefined` (default): inherits the global configuration from `Vue.use(Vue2ExcelGrid, { darkMode })`.
1484
+ * Accepts a Boolean, a getter Function (`() => boolean`), or `'auto'` / `'system'`.
1485
+ */
1486
+ darkMode: { type: [Boolean, Function, String], default: null },
1487
+
1469
1488
  /**
1470
1489
  * Shows a filter row directly beneath the column headers (inside the
1471
1490
  * sticky header area). Each leaf column gets a filter control matched to
@@ -1835,6 +1854,19 @@ const ExcelGridComponent = {
1835
1854
  },
1836
1855
 
1837
1856
  computed: {
1857
+ isDarkMode() {
1858
+ let val = this.darkMode
1859
+ if (val === null || val === undefined) {
1860
+ val = globalConfig ? globalConfig.darkMode : null
1861
+ }
1862
+ if (typeof val === 'function') {
1863
+ val = val()
1864
+ }
1865
+ if (val === 'auto' || val === 'system') {
1866
+ return typeof window !== 'undefined' && !!window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
1867
+ }
1868
+ return Boolean(val)
1869
+ },
1838
1870
  hoverTooltipStyle() {
1839
1871
  if (!this.hoverTooltip) return {}
1840
1872
  const { rect, text } = this.hoverTooltip
@@ -7395,6 +7427,9 @@ export default ExcelGridComponent
7395
7427
  border: 1px solid var(--eg-color-border, var(--eg-color-border-default));
7396
7428
  border-radius: var(--eg-radius, var(--eg-radius-default));
7397
7429
  overflow: hidden;
7430
+ color-scheme: light;
7431
+ background: var(--eg-color-cell-bg, var(--eg-color-cell-bg-default));
7432
+ color: var(--eg-color-text, var(--eg-color-text-default));
7398
7433
  }
7399
7434
 
7400
7435
  .eg-shell-fullscreen {
@@ -7633,6 +7668,184 @@ export default ExcelGridComponent
7633
7668
  --eg-color-row-stripe-default: #F4F4F4;
7634
7669
  }
7635
7670
 
7671
+ /* ── Shopify Polaris — toza, zamonaviy e-commerce uslubi, 8px radius ── */
7672
+ .eg-shell.eg-theme-polaris {
7673
+ --eg-font-family-default: -apple-system, BlinkMacSystemFont, 'San Francisco', 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
7674
+ --eg-font-size-default: 13px;
7675
+ --eg-font-size-header-default: 12px;
7676
+ --eg-radius-default: 8px;
7677
+ --eg-cell-padding-x-default: 8px;
7678
+
7679
+ --eg-color-accent-default: #008060;
7680
+ --eg-color-accent-dark-default: #004c3f;
7681
+ --eg-color-accent-soft-default: #E3F1DF;
7682
+
7683
+ --eg-color-error-default: #D72C0D;
7684
+ --eg-color-error-soft-default: #FFF4F4;
7685
+ --eg-color-error-dark-default: #8C1000;
7686
+
7687
+ /* Polaris borderlar: yumshoq kulrang */
7688
+ --eg-color-border-default: #D2D5D8;
7689
+ --eg-color-border-cell-default: #E1E3E5;
7690
+ --eg-color-border-strong-default: #8C9196;
7691
+
7692
+ /* Polaris header: yengil neytral kulrang (#F6F6F7) */
7693
+ --eg-color-header-bg-default: #F6F6F7;
7694
+ --eg-color-header-group-bg-default: #EDEEEF;
7695
+ --eg-color-group-border-default: #008060;
7696
+ --eg-color-group-bg-collapsed-default: #004c3f;
7697
+
7698
+ --eg-color-cell-bg-default: #FFFFFF;
7699
+ --eg-color-cell-selected-default: #E3F1DF;
7700
+ --eg-color-cell-fill-preview-default: #BBE5B3;
7701
+ --eg-color-cell-readonly-default: #FAFBFB;
7702
+ --eg-color-cell-readonly-selected-default: #D8ECE5;
7703
+ --eg-color-cell-readonly-pattern-default: rgba(0, 128, 96, 0.05);
7704
+ --eg-color-footer-bg-default: #F6F6F7;
7705
+
7706
+ --eg-color-text-default: #202223;
7707
+ --eg-color-text-secondary-default: #6D7175;
7708
+ --eg-color-text-muted-default: #8C9196;
7709
+
7710
+ --eg-shadow-dropdown-default: 0 4px 12px rgba(0, 0, 0, 0.08), 0 1px 3px rgba(0, 0, 0, 0.05);
7711
+ --eg-shadow-dialog-default: 0 8px 24px rgba(0, 0, 0, 0.12);
7712
+ --eg-shadow-tooltip-default: 0 2px 6px rgba(0, 0, 0, 0.15);
7713
+ --eg-color-freeze-shadow-default: rgba(0, 0, 0, 0.08);
7714
+
7715
+ --eg-color-overlay-bg-default: rgba(255, 255, 255, 0.94);
7716
+ --eg-color-option-hover-bg-default: #F6F6F7;
7717
+ --eg-color-option-active-hover-bg-default: #E3F1DF;
7718
+
7719
+ --eg-color-checkbox-border-default: #8C9196;
7720
+ --eg-color-checkbox-disabled-checked-default: #C9CCCF;
7721
+
7722
+ /* Polaris hover va stripe */
7723
+ --eg-color-row-hover-default: #F1F2F4;
7724
+ --eg-color-row-stripe-default: #FAFBFB;
7725
+ }
7726
+
7727
+ /* ── Dark Mode ─────────────────────────────────────────────────── */
7728
+ .eg-shell.eg-dark {
7729
+ color-scheme: dark;
7730
+
7731
+ /* Accent (lighter for dark backgrounds) */
7732
+ --eg-color-accent-default: #4aba7c;
7733
+ --eg-color-accent-dark-default: #2d9e5c;
7734
+ --eg-color-accent-soft-default: rgba(74, 186, 124, 0.2);
7735
+
7736
+ /* Error */
7737
+ --eg-color-error-default: #f87171;
7738
+ --eg-color-error-soft-default: #2d0f0f;
7739
+ --eg-color-error-dark-default: #fca5a5;
7740
+
7741
+ /* Borders */
7742
+ --eg-color-border-default: #3d3d3d;
7743
+ --eg-color-border-cell-default: #2a2a2a;
7744
+ --eg-color-border-strong-default: #555555;
7745
+
7746
+ /* Headers */
7747
+ --eg-color-header-bg-default: #252525;
7748
+ --eg-color-header-group-bg-default: #252525;
7749
+ --eg-color-group-border-default: #2d9e5c;
7750
+ --eg-color-group-bg-collapsed-default: #217346;
7751
+
7752
+ /* Cell states */
7753
+ --eg-color-cell-bg-default: #1e1e1e;
7754
+ --eg-color-cell-selected-default: #1a3d2a;
7755
+ --eg-color-cell-fill-preview-default: #145022;
7756
+ --eg-color-cell-readonly-default: #171717;
7757
+ --eg-color-cell-readonly-selected-default: #163020;
7758
+ --eg-color-cell-readonly-pattern-default: rgba(255, 255, 255, 0.06);
7759
+ --eg-color-footer-bg-default: #1a1a1a;
7760
+
7761
+ /* Row effects */
7762
+ --eg-color-row-hover-default: #242f27;
7763
+ --eg-color-row-stripe-default: #1a1a1a;
7764
+
7765
+ /* Dropdown / Select / Context menu */
7766
+ --eg-color-option-hover-bg-default: #242f27;
7767
+ --eg-color-option-active-hover-bg-default: #1a4d30;
7768
+ --eg-color-overlay-bg-default: rgba(28, 28, 28, 0.95);
7769
+
7770
+ /* Checkbox */
7771
+ --eg-color-checkbox-border-default: #6e6e6e;
7772
+ --eg-color-checkbox-disabled-checked-default: #404040;
7773
+
7774
+ /* Text */
7775
+ --eg-color-text-default: #d4d4d4;
7776
+ --eg-color-text-secondary-default: #a0a0a0;
7777
+ --eg-color-text-muted-default: #6e6e6e;
7778
+
7779
+ /* Shadows */
7780
+ --eg-shadow-dropdown-default: 1px 2px 10px rgba(0, 0, 0, 0.55);
7781
+ --eg-shadow-dialog-default: 0 2px 16px rgba(0, 0, 0, 0.65);
7782
+ --eg-shadow-tooltip-default: 0 1px 5px rgba(0, 0, 0, 0.55);
7783
+ --eg-color-freeze-shadow-default: rgba(0, 0, 0, 0.45);
7784
+ }
7785
+
7786
+ /* Theme-specific dark mode adjustments */
7787
+ .eg-shell.eg-theme-antd.eg-dark {
7788
+ --eg-color-accent-default: #1668DC;
7789
+ --eg-color-accent-dark-default: #1554AD;
7790
+ --eg-color-accent-soft-default: #111A2C;
7791
+ --eg-color-cell-selected-default: #111A2C;
7792
+ --eg-color-cell-fill-preview-default: #153450;
7793
+ --eg-color-row-hover-default: #1f1f1f;
7794
+ --eg-color-option-hover-bg-default: #111A2C;
7795
+ }
7796
+
7797
+ .eg-shell.eg-theme-material.eg-dark {
7798
+ --eg-color-accent-default: #90CAF9;
7799
+ --eg-color-accent-dark-default: #42A5F5;
7800
+ --eg-color-accent-soft-default: #1E2A38;
7801
+ --eg-color-cell-selected-default: #1E2A38;
7802
+ }
7803
+
7804
+ .eg-shell.eg-theme-polaris.eg-dark {
7805
+ --eg-color-accent-default: #00A67E;
7806
+ --eg-color-accent-dark-default: #008060;
7807
+ --eg-color-accent-soft-default: #102A22;
7808
+ --eg-color-cell-selected-default: #102A22;
7809
+ }
7810
+
7811
+ .eg-shell.eg-theme-carbon.eg-dark {
7812
+ --eg-color-accent-default: #4589FF;
7813
+ --eg-color-accent-dark-default: #0F62FE;
7814
+ --eg-color-accent-soft-default: #002D9C;
7815
+ --eg-color-cell-selected-default: #002D9C;
7816
+ }
7817
+
7818
+ .eg-shell.eg-theme-fluent.eg-dark {
7819
+ --eg-color-accent-default: #2886DE;
7820
+ --eg-color-accent-dark-default: #0078D4;
7821
+ --eg-color-accent-soft-default: #0C2B47;
7822
+ --eg-color-cell-selected-default: #0C2B47;
7823
+ }
7824
+
7825
+ /* Dark scrollbars */
7826
+ .eg-shell.eg-dark .eg-container::-webkit-scrollbar,
7827
+ .eg-shell.eg-dark .eg-scroll-body::-webkit-scrollbar,
7828
+ .eg-shell.eg-dark .eg-main-cells::-webkit-scrollbar {
7829
+ width: 10px;
7830
+ height: 10px;
7831
+ }
7832
+ .eg-shell.eg-dark .eg-container::-webkit-scrollbar-track,
7833
+ .eg-shell.eg-dark .eg-scroll-body::-webkit-scrollbar-track,
7834
+ .eg-shell.eg-dark .eg-main-cells::-webkit-scrollbar-track {
7835
+ background: #1e1e1e;
7836
+ }
7837
+ .eg-shell.eg-dark .eg-container::-webkit-scrollbar-thumb,
7838
+ .eg-shell.eg-dark .eg-scroll-body::-webkit-scrollbar-thumb,
7839
+ .eg-shell.eg-dark .eg-main-cells::-webkit-scrollbar-thumb {
7840
+ background: #3d3d3d;
7841
+ border-radius: 4px;
7842
+ }
7843
+ .eg-shell.eg-dark .eg-container::-webkit-scrollbar-thumb:hover,
7844
+ .eg-shell.eg-dark .eg-scroll-body::-webkit-scrollbar-thumb:hover,
7845
+ .eg-shell.eg-dark .eg-main-cells::-webkit-scrollbar-thumb:hover {
7846
+ background: #555555;
7847
+ }
7848
+
7636
7849
  .eg-wrapper {
7637
7850
  display: flex;
7638
7851
  flex-direction: column;
@@ -8914,6 +9127,10 @@ export default ExcelGridComponent
8914
9127
  padding: 4px 6px 6px;
8915
9128
  border-top: 1px solid var(--eg-color-border, var(--eg-color-border-default));
8916
9129
  }
9130
+ .eg-select-dropdown-footer {
9131
+ border-top: 1px solid var(--eg-color-border, var(--eg-color-border-default));
9132
+ padding: 4px;
9133
+ }
8917
9134
  .eg-select-btn {
8918
9135
  background: none;
8919
9136
  border: 1px solid var(--eg-color-border, var(--eg-color-border-default));
package/src/config.js ADDED
@@ -0,0 +1,22 @@
1
+ import Vue from 'vue'
2
+
3
+ const state = (Vue && typeof Vue.observable === 'function')
4
+ ? Vue.observable({ darkMode: null })
5
+ : { darkMode: null }
6
+
7
+ export const globalConfig = state
8
+
9
+ /**
10
+ * Update global vue2-excel-grid configuration reactively.
11
+ * @param {Object} options
12
+ */
13
+ export function setGlobalGridConfig(options = {}) {
14
+ if (options && typeof options === 'object') {
15
+ Object.keys(options).forEach(key => {
16
+ globalConfig[key] = options[key]
17
+ })
18
+ }
19
+ }
20
+
21
+ export const setGlobalConfig = setGlobalGridConfig
22
+
package/src/index.js CHANGED
@@ -3,15 +3,17 @@ import EgCheckbox from './components/EgCheckbox.vue'
3
3
  import EgSelect from './components/EgSelect.vue'
4
4
  import EgTreeSelect from './components/EgTreeSelect.vue'
5
5
  import { version } from '../package.json'
6
+ import { globalConfig, setGlobalGridConfig, setGlobalConfig } from './config.js'
6
7
 
7
- export { ExcelGrid, EgCheckbox, EgSelect, EgTreeSelect, version }
8
+ export { ExcelGrid, EgCheckbox, EgSelect, EgTreeSelect, version, globalConfig, setGlobalGridConfig, setGlobalConfig }
8
9
 
9
10
  export default {
10
11
  version,
11
12
  install(Vue, options = {}) {
12
13
  if (options && typeof options === 'object') {
13
14
  Object.keys(options).forEach(key => {
14
- if (ExcelGrid.props && ExcelGrid.props[key] !== undefined) {
15
+ globalConfig[key] = options[key]
16
+ if (key !== 'darkMode' && ExcelGrid.props && ExcelGrid.props[key] !== undefined) {
15
17
  const val = options[key]
16
18
  if (typeof ExcelGrid.props[key] !== 'object') {
17
19
  // Convert to object notation if it was just a constructor like `props: { fitColumns: Boolean }`
@@ -21,6 +23,7 @@ export default {
21
23
  }
22
24
  })
23
25
  }
26
+ Vue.prototype.$excelGridConfig = globalConfig
24
27
  Vue.component('Vue2ExcelGrid', ExcelGrid)
25
28
  Vue.component('Vue2EgCheckbox', EgCheckbox)
26
29
  Vue.component('Vue2EgSelect', EgSelect)