hy-virtual-tree 1.1.70 → 1.1.72

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 (3) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/index.js +187 -37
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  ## Changelog
2
2
 
3
+ ### 1.1.72
4
+
5
+ _2026-02-02_
6
+
7
+ - 扩展[VirtualTree] 功能
8
+ (1)修复树形的展开和选中逻辑问题,提取展开逻辑函数
9
+
10
+ ### 1.1.71
11
+
12
+ _2026-01-31_
13
+
14
+ - 扩展[VirtualTree] 功能
15
+ (1)修复 channel业务下,设备下全部通道离线会导致设备的下拉选项隐藏问题
16
+ (2)修复 tooltip 快速滚动导致不会隐藏问题
17
+
3
18
  ### 1.1.70
4
19
 
5
20
  _2026-01-31_
package/dist/index.js CHANGED
@@ -6607,18 +6607,75 @@ const encryptToBase64 = (str) => {
6607
6607
  function base64Decrypt(str) {
6608
6608
  return CryptoJS.enc.Base64.parse(str).toString(CryptoJS.enc.Utf8);
6609
6609
  }
6610
+ /**
6611
+ * @function generateRandomCode 生成随机码
6612
+ * @description 随机生成包含小写字母和数字的随机码
6613
+ * @param {Number} number 生成随机码的个数,默认为 13
6614
+ * @returns {String}
6615
+ */
6616
+ function generateRandomCode(number = 13) {
6617
+ const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
6618
+ const charCount = chars.length;
6619
+ let randomString1 = '';
6620
+ for (let i = 0; i < number; i++) {
6621
+ const randomIndex = Math.floor(Math.random() * charCount);
6622
+ randomString1 += chars[randomIndex];
6623
+ }
6624
+ return randomString1;
6625
+ }
6610
6626
 
6627
+ let btnBlurMap$1 = new Map();
6628
+ const btnBlurMapFn$1 = () => {
6629
+ btnBlurMap$1.keys().forEach((key) => {
6630
+ const fn = btnBlurMap$1.get(key);
6631
+ fn && fn();
6632
+ });
6633
+ btnBlurMap$1 = new Map();
6634
+ };
6635
+ let isWheelListenerate$1 = false;
6636
+ let isScrolling$1 = false;
6637
+ let scrollTimer$1;
6638
+ const addWeelListenerate$1 = () => {
6639
+ if (isWheelListenerate$1)
6640
+ return;
6641
+ window.addEventListener('wheel', (e) => {
6642
+ btnBlurMapFn$1();
6643
+ scrollTimer$1 && clearTimeout(scrollTimer$1);
6644
+ isScrolling$1 = true;
6645
+ scrollTimer$1 = setTimeout(() => {
6646
+ isScrolling$1 = false;
6647
+ }, 100);
6648
+ });
6649
+ isWheelListenerate$1 = true;
6650
+ };
6651
+ let focusTimer$1;
6611
6652
  const setElementFocus = (config) => {
6612
- const { container, trigger, onFocus, onBlur } = config;
6653
+ addWeelListenerate$1();
6654
+ const { container, trigger, openDelay, onFocus, onBlur } = config;
6655
+ const id = generateRandomCode();
6613
6656
  let btn = document.createElement('button');
6657
+ let isBlur = false;
6614
6658
  const btnFocus = () => {
6615
- btn.focus();
6616
- onFocus && onFocus();
6659
+ btnBlurMapFn$1();
6660
+ if (isScrolling$1)
6661
+ return;
6662
+ isBlur = false;
6663
+ focusTimer$1 && clearTimeout(focusTimer$1);
6664
+ focusTimer$1 = setTimeout(() => {
6665
+ if (isBlur)
6666
+ return;
6667
+ btn.focus();
6668
+ onFocus && onFocus();
6669
+ }, openDelay || 0);
6670
+ btnBlurMap$1.set(id, btnBlur);
6617
6671
  };
6618
6672
  const btnBlur = () => {
6673
+ isBlur = true;
6674
+ focusTimer$1 && clearTimeout(focusTimer$1);
6619
6675
  btn.blur();
6620
- onBlur && onBlur();
6676
+ onBlur && onBlur(id);
6621
6677
  };
6678
+ btn.addEventListener('blur', btnBlur);
6622
6679
  if (trigger === 'click') {
6623
6680
  container.addEventListener('click', btnFocus);
6624
6681
  btn.addEventListener('blur', btnBlur);
@@ -6900,8 +6957,111 @@ const setGlobalTreeConfig = (config, isReset = true) => {
6900
6957
  setGlobalVirtualTreeConfig(config.tree || {}, isReset);
6901
6958
  };
6902
6959
 
6960
+ let btnBlurMap = new Map();
6961
+ const btnBlurMapFn = () => {
6962
+ btnBlurMap.keys().forEach((key) => {
6963
+ const fn = btnBlurMap.get(key);
6964
+ fn && fn();
6965
+ });
6966
+ btnBlurMap = new Map();
6967
+ };
6968
+ let isWheelListenerate = false;
6969
+ let isScrolling = false;
6970
+ let scrollTimer;
6971
+ const addWeelListenerate = () => {
6972
+ if (isWheelListenerate)
6973
+ return;
6974
+ window.addEventListener('wheel', (e) => {
6975
+ btnBlurMapFn();
6976
+ scrollTimer && clearTimeout(scrollTimer);
6977
+ isScrolling = true;
6978
+ scrollTimer = setTimeout(() => {
6979
+ isScrolling = false;
6980
+ }, 100);
6981
+ });
6982
+ isWheelListenerate = true;
6983
+ };
6984
+ let focusTimer;
6985
+ class Trigger {
6986
+ _id = generateRandomCode();
6987
+ _btn = document.createElement('button');
6988
+ _isBlur = true;
6989
+ el;
6990
+ bind;
6991
+ _focus = () => { };
6992
+ _blur = () => { };
6993
+ trigger = 'hover';
6994
+ openDelay = 200;
6995
+ onFocus;
6996
+ onBlur;
6997
+ constructor(props) {
6998
+ if (!props.bind || !isElement(props.bind) || !isElement(props.el)) {
6999
+ throw Error('【参数错误】:请传入元素节点');
7000
+ }
7001
+ addWeelListenerate();
7002
+ this._setConfig(props)
7003
+ ._init();
7004
+ }
7005
+ _setConfig(config) {
7006
+ const { el, bind, trigger, openDelay, onFocus, onBlur } = config;
7007
+ this.el = el;
7008
+ this.bind = bind;
7009
+ this.trigger = ['click', 'hover'].includes(trigger) ? trigger : this.trigger;
7010
+ this.openDelay = isNumber(openDelay) ? openDelay : this.openDelay;
7011
+ this.onFocus = onFocus;
7012
+ this.onBlur = onBlur;
7013
+ return this;
7014
+ }
7015
+ _init() {
7016
+ if (!this.bind || !this.el)
7017
+ return;
7018
+ this._isBlur = true;
7019
+ this._focus = this.focus.bind(this);
7020
+ this._blur = this.blur.bind(this);
7021
+ if (this.trigger === 'click') {
7022
+ this.bind.addEventListener('click', this._focus);
7023
+ this._btn.addEventListener('blur', this._blur);
7024
+ }
7025
+ else {
7026
+ this.bind.addEventListener('mouseenter', this._focus);
7027
+ this.bind.addEventListener('mouseleave', this._blur);
7028
+ }
7029
+ }
7030
+ focus() {
7031
+ btnBlurMapFn();
7032
+ if (isScrolling)
7033
+ return;
7034
+ this._isBlur = false;
7035
+ focusTimer && clearTimeout(focusTimer);
7036
+ focusTimer = setTimeout(() => {
7037
+ if (this._isBlur)
7038
+ return;
7039
+ this._btn?.focus();
7040
+ this.onFocus && this.onFocus();
7041
+ }, this.openDelay || 0);
7042
+ btnBlurMap.set(this._id, this._blur);
7043
+ }
7044
+ blur() {
7045
+ this._isBlur = true;
7046
+ focusTimer && clearTimeout(focusTimer);
7047
+ this._btn?.blur();
7048
+ this.onBlur && this.onBlur(this._id);
7049
+ }
7050
+ destroy() {
7051
+ this._blur();
7052
+ if (!this.bind)
7053
+ return;
7054
+ if (this.trigger === 'click') {
7055
+ this.bind.removeEventListener('click', this._focus);
7056
+ }
7057
+ else {
7058
+ this.bind.removeEventListener('mouseenter', this._focus);
7059
+ this.bind.removeEventListener('mouseleave', this._blur);
7060
+ }
7061
+ }
7062
+ }
7063
+
6903
7064
  let container;
6904
- let closeActiveTooltip;
6905
7065
  const getContainer$1 = () => {
6906
7066
  if (container)
6907
7067
  return container;
@@ -6922,34 +7082,16 @@ const styleVar = {
6922
7082
  padding: '--hy-tooltip-padding',
6923
7083
  zIndex: '--hy-tooltip-z-index',
6924
7084
  };
6925
- let isWheelListenerate = false;
6926
- let isScrolling = false;
6927
- let scrollTimer;
6928
- const addWeelListenerate = () => {
6929
- if (isWheelListenerate)
6930
- return;
6931
- window.addEventListener('wheel', (e) => {
6932
- closeActiveTooltip && closeActiveTooltip();
6933
- closeActiveTooltip = null;
6934
- scrollTimer && clearTimeout(scrollTimer);
6935
- isScrolling = true;
6936
- scrollTimer = setTimeout(() => {
6937
- isScrolling = false;
6938
- }, 100);
6939
- });
6940
- isWheelListenerate = true;
6941
- };
6942
7085
  class Tooltip {
6943
7086
  _el;
6944
7087
  _config;
6945
- _focus;
7088
+ _trigger;
6946
7089
  _timer;
6947
7090
  _openTimer;
6948
7091
  _closeTimer;
6949
7092
  _style = getGlobalTooltipConfig().style;
6950
7093
  _isHover = false;
6951
7094
  constructor(props) {
6952
- addWeelListenerate();
6953
7095
  if (!props.bind || !isElement(props.bind))
6954
7096
  throw Error('【bind参数错误】:请传入元素节点');
6955
7097
  this._config = this._generateConfig(props);
@@ -6992,19 +7134,18 @@ class Tooltip {
6992
7134
  this.setPopper();
6993
7135
  });
6994
7136
  el.addEventListener('mouseleave', (e) => {
7137
+ this._openTimer && clearTimeout(this._openTimer);
6995
7138
  this.setIsHover(false);
6996
7139
  this.hide();
6997
7140
  });
6998
- this._focus = setElementFocus({
6999
- container: bind,
7141
+ this._trigger = new Trigger({
7142
+ el: this._el,
7143
+ bind: bind,
7000
7144
  trigger: this._config.trigger === 'click' ? 'click' : 'hover',
7145
+ openDelay: this._config.openDelay || 0,
7001
7146
  onFocus: () => {
7002
- if (isScrolling) {
7003
- return;
7004
- }
7005
7147
  if (this.isHover)
7006
7148
  return;
7007
- closeActiveTooltip && closeActiveTooltip();
7008
7149
  if (!this._el || !this._config)
7009
7150
  return;
7010
7151
  if (this._config?.trigger === 'hover-overflow' && !isOverflowing(this._config.bind))
@@ -7025,10 +7166,10 @@ class Tooltip {
7025
7166
  if (this._config?.autoClose && isNumber(this._config.autoClose)) {
7026
7167
  this._timer && clearTimeout(this._timer);
7027
7168
  this._timer = setTimeout(() => {
7028
- this._focus && this._focus.blur();
7169
+ this._trigger && this._trigger.blur();
7029
7170
  }, this._config?.autoClose);
7030
7171
  }
7031
- }, this._config.openDelay || 0);
7172
+ }, 200);
7032
7173
  },
7033
7174
  onBlur: () => {
7034
7175
  if (this.isHover)
@@ -7083,7 +7224,6 @@ class Tooltip {
7083
7224
  this._el.style.setProperty('left', `${left + width + offset}px`);
7084
7225
  break;
7085
7226
  }
7086
- closeActiveTooltip = this.hide.bind(this);
7087
7227
  }
7088
7228
  hide() {
7089
7229
  this._openTimer && clearTimeout(this._openTimer);
@@ -7105,8 +7245,9 @@ class Tooltip {
7105
7245
  }, 200);
7106
7246
  }
7107
7247
  destroy() {
7248
+ this.hide();
7108
7249
  this._timer && clearTimeout(this._timer);
7109
- this._focus && this._focus.destroy();
7250
+ this._trigger && this._trigger.destroy();
7110
7251
  this._config = undefined;
7111
7252
  }
7112
7253
  }
@@ -7973,6 +8114,14 @@ const isCheckLeaf = (config, node) => {
7973
8114
  }
7974
8115
  return node.isLeaf;
7975
8116
  };
8117
+ const isExpandLeaf = (config, node) => {
8118
+ // 非通道业务 或 非设备类型
8119
+ if (config.business !== Business.CHANNEL || node.data.dataType !== DataType.DEVICE) {
8120
+ return node.isLeaf;
8121
+ }
8122
+ // 设备类型
8123
+ return config.businessConfig?.showOnlineState ? !node.count : !node.total;
8124
+ };
7976
8125
  function useCheck(props, instance) {
7977
8126
  const tree = instance._tree;
7978
8127
  const checkedKeys = new Set();
@@ -9517,7 +9666,7 @@ class VirtualTree {
9517
9666
  const icon = document.createElement('div');
9518
9667
  icon.classList.add('hy-tree-node__expand-icon');
9519
9668
  el.appendChild(icon);
9520
- if (isCheckLeaf(config, item) || this._hiddenExpandIconKeySet.has(item.key)) {
9669
+ if (isExpandLeaf(config, item) || this._hiddenExpandIconKeySet.has(item.key)) {
9521
9670
  el.style.setProperty('visibility', 'hidden');
9522
9671
  }
9523
9672
  else {
@@ -9686,7 +9835,7 @@ class VirtualTree {
9686
9835
  if (config.onNodeClick) {
9687
9836
  await config.onNodeClick(getNodeData(item), item, e);
9688
9837
  }
9689
- const isLeaf = isCheckLeaf(config, item);
9838
+ const isLeaf = isExpandLeaf(config, item);
9690
9839
  if (!getDisabled(config, item) && isShowSelect(config, item)) {
9691
9840
  if (config.checkOnClickNode) {
9692
9841
  toggleCheckbox(item, !(isChecked(item) || isIndeterminate(item)), true, true);
@@ -9736,6 +9885,7 @@ class VirtualTree {
9736
9885
  nodeClickTimer = setTimeout(() => {
9737
9886
  if (nodeClickCount === 1) {
9738
9887
  nodeClickHandle(e);
9888
+ nodeClickCount = 0;
9739
9889
  }
9740
9890
  else {
9741
9891
  nodeClickCount = 0;
@@ -10127,4 +10277,4 @@ class VirtualTree {
10127
10277
  };
10128
10278
  }
10129
10279
 
10130
- export { Business, DataType, DeviceStatus, VirtualScroll, VirtualTree, base64Decrypt, cloneDeep, encryptToBase64, getGlobalDeviceConfig, getGlobalTooltipConfig, getGlobalTreeConfig, getGlobalVirtualTreeConfig, isArray, isBoolean, isElement, isEmpty, isFunction, isNull, isNumber, isObject, isOverflowing, isString, isUndefined, mergeDeep, setElementFocus, setGlobalDeviceConfig, setGlobalTooltipConfig, setGlobalTreeConfig, setGlobalVirtualTreeConfig };
10280
+ export { Business, DataType, DeviceStatus, VirtualScroll, VirtualTree, base64Decrypt, cloneDeep, encryptToBase64, generateRandomCode, getGlobalDeviceConfig, getGlobalTooltipConfig, getGlobalTreeConfig, getGlobalVirtualTreeConfig, isArray, isBoolean, isElement, isEmpty, isFunction, isNull, isNumber, isObject, isOverflowing, isString, isUndefined, mergeDeep, setElementFocus, setGlobalDeviceConfig, setGlobalTooltipConfig, setGlobalTreeConfig, setGlobalVirtualTreeConfig };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hy-virtual-tree",
3
- "version": "1.1.70",
3
+ "version": "1.1.72",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite",