vxe-table 4.6.7-beta.2 → 4.6.7

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 (51) hide show
  1. package/README.en.md +1 -0
  2. package/README.md +1 -0
  3. package/README.zh-TW.md +1 -0
  4. package/es/button/src/button.js +44 -8
  5. package/es/button/src/group.js +7 -2
  6. package/es/dynamics/index.js +2 -3
  7. package/es/grid/src/grid.js +2 -2
  8. package/es/icon/style.css +1 -1
  9. package/es/style.css +1 -1
  10. package/es/style.min.css +1 -1
  11. package/es/tools/log.js +1 -1
  12. package/es/v-x-e-table/index.js +1 -1
  13. package/helper/vetur/attributes.json +9 -5
  14. package/helper/vetur/tags.json +1 -0
  15. package/lib/button/src/button.js +49 -10
  16. package/lib/button/src/button.min.js +1 -1
  17. package/lib/button/src/group.js +9 -1
  18. package/lib/button/src/group.min.js +1 -1
  19. package/lib/dynamics/index.js +1 -3
  20. package/lib/dynamics/index.min.js +1 -1
  21. package/lib/grid/src/grid.js +3 -2
  22. package/lib/grid/src/grid.min.js +1 -1
  23. package/lib/icon/style/style.css +1 -1
  24. package/lib/icon/style/style.min.css +1 -1
  25. package/lib/index.umd.js +3172 -3125
  26. package/lib/index.umd.min.js +1 -1
  27. package/lib/style.css +1 -1
  28. package/lib/style.min.css +1 -1
  29. package/lib/tools/log.js +1 -1
  30. package/lib/tools/log.min.js +1 -1
  31. package/lib/v-x-e-table/index.js +1 -1
  32. package/lib/v-x-e-table/index.min.js +1 -1
  33. package/package.json +1 -1
  34. package/packages/button/src/button.ts +47 -8
  35. package/packages/button/src/group.ts +7 -2
  36. package/packages/dynamics/index.ts +2 -3
  37. package/packages/grid/src/grid.ts +2 -2
  38. package/types/button-group.d.ts +10 -0
  39. package/types/table.d.ts +6 -0
  40. /package/es/icon/style/{iconfont.1714377664388.ttf → iconfont.1714444998024.ttf} +0 -0
  41. /package/es/icon/style/{iconfont.1714377664388.woff → iconfont.1714444998024.woff} +0 -0
  42. /package/es/icon/style/{iconfont.1714377664388.woff2 → iconfont.1714444998024.woff2} +0 -0
  43. /package/es/{iconfont.1714377664388.ttf → iconfont.1714444998024.ttf} +0 -0
  44. /package/es/{iconfont.1714377664388.woff → iconfont.1714444998024.woff} +0 -0
  45. /package/es/{iconfont.1714377664388.woff2 → iconfont.1714444998024.woff2} +0 -0
  46. /package/lib/icon/style/{iconfont.1714377664388.ttf → iconfont.1714444998024.ttf} +0 -0
  47. /package/lib/icon/style/{iconfont.1714377664388.woff → iconfont.1714444998024.woff} +0 -0
  48. /package/lib/icon/style/{iconfont.1714377664388.woff2 → iconfont.1714444998024.woff2} +0 -0
  49. /package/lib/{iconfont.1714377664388.ttf → iconfont.1714444998024.ttf} +0 -0
  50. /package/lib/{iconfont.1714377664388.woff → iconfont.1714444998024.woff} +0 -0
  51. /package/lib/{iconfont.1714377664388.woff2 → iconfont.1714444998024.woff2} +0 -0
package/lib/tools/log.js CHANGED
@@ -9,7 +9,7 @@ exports.warnLog = void 0;
9
9
  var _conf = _interopRequireDefault(require("../v-x-e-table/src/conf"));
10
10
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
11
  function getLog(message, params) {
12
- return `[vxe-table v${"4.6.7-beta.2"}] ${_conf.default.i18n(message, params)}`;
12
+ return `[vxe-table v${"4.6.7"}] ${_conf.default.i18n(message, params)}`;
13
13
  }
14
14
  function outLog(type) {
15
15
  return function (message, params) {
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.errLog=void 0,exports.getLog=getLog,exports.warnLog=void 0;var _conf=_interopRequireDefault(require("../v-x-e-table/src/conf"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function getLog(e,o){return"[vxe-table v4.6.7-beta.2] "+_conf.default.i18n(e,o)}function outLog(r){return function(e,o){e=getLog(e,o);return console[r](e),e}}const warnLog=exports.warnLog=outLog("warn"),errLog=exports.errLog=outLog("error");
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.errLog=void 0,exports.getLog=getLog,exports.warnLog=void 0;var _conf=_interopRequireDefault(require("../v-x-e-table/src/conf"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function getLog(e,o){return"[vxe-table v4.6.7] "+_conf.default.i18n(e,o)}function outLog(r){return function(e,o){e=getLog(e,o);return console[r](e),e}}const warnLog=exports.warnLog=outLog("warn"),errLog=exports.errLog=outLog("error");
@@ -181,7 +181,7 @@ const setup = exports.setup = _config.config;
181
181
  const globalStore = exports.globalStore = {};
182
182
  const VXETable = exports.VXETable = {
183
183
  v,
184
- version: "4.6.7-beta.2",
184
+ version: "4.6.7",
185
185
  config: _config.config,
186
186
  globalStore,
187
187
  interceptor: _interceptor.interceptor,
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var _exportNames={use:!0,t:!0,_t:!0,globalConfs:!0,v:!0,setup:!0,globalStore:!0,VXETable:!0},_xeUtils=(exports.VXETable=void 0,exports._t=_t,exports.setup=exports.globalStore=exports.globalConfs=exports.default=void 0,exports.t=t,exports.use=use,exports.v=void 0,_interopRequireDefault(require("xe-utils"))),_conf=_interopRequireDefault(require("./src/conf")),_interceptor=require("./src/interceptor"),_renderer=(Object.keys(_interceptor).forEach(function(e){"default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(_exportNames,e)||e in exports&&exports[e]===_interceptor[e]||Object.defineProperty(exports,e,{enumerable:!0,get:function(){return _interceptor[e]}})}),require("./src/renderer")),_commands=(Object.keys(_renderer).forEach(function(e){"default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(_exportNames,e)||e in exports&&exports[e]===_renderer[e]||Object.defineProperty(exports,e,{enumerable:!0,get:function(){return _renderer[e]}})}),require("./src/commands")),_menus=(Object.keys(_commands).forEach(function(e){"default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(_exportNames,e)||e in exports&&exports[e]===_commands[e]||Object.defineProperty(exports,e,{enumerable:!0,get:function(){return _commands[e]}})}),require("./src/menus")),_formats=(Object.keys(_menus).forEach(function(e){"default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(_exportNames,e)||e in exports&&exports[e]===_menus[e]||Object.defineProperty(exports,e,{enumerable:!0,get:function(){return _menus[e]}})}),require("./src/formats")),_validators=(Object.keys(_formats).forEach(function(e){"default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(_exportNames,e)||e in exports&&exports[e]===_formats[e]||Object.defineProperty(exports,e,{enumerable:!0,get:function(){return _formats[e]}})}),require("./src/validators")),_hooks=(Object.keys(_validators).forEach(function(e){"default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(_exportNames,e)||e in exports&&exports[e]===_validators[e]||Object.defineProperty(exports,e,{enumerable:!0,get:function(){return _validators[e]}})}),require("./src/hooks")),_config=(Object.keys(_hooks).forEach(function(e){"default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(_exportNames,e)||e in exports&&exports[e]===_hooks[e]||Object.defineProperty(exports,e,{enumerable:!0,get:function(){return _hooks[e]}})}),require("./src/config")),_utils=(Object.keys(_config).forEach(function(e){"default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(_exportNames,e)||e in exports&&exports[e]===_config[e]||Object.defineProperty(exports,e,{enumerable:!0,get:function(){return _config[e]}})}),require("../tools/utils"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function getExportOrImpotType(e,r){const o=[];return _xeUtils.default.objectEach(e,(e,t)=>{0!==e&&e!==r||o.push(t)}),o}const installedPlugins=[];function use(e,t){return e&&e.install&&-1===installedPlugins.indexOf(e)&&(e.install(VXETable,t),installedPlugins.push(e)),VXETable}function t(e,t){return _conf.default.i18n(e,t)}function _t(e,t){return e?_xeUtils.default.toValueString(_conf.default.translate?_conf.default.translate(e,t):e):""}class VXETableConfig{get zIndex(){return(0,_utils.getLastZIndex)()}get nextZIndex(){return(0,_utils.nextZIndex)()}get exportTypes(){return getExportOrImpotType(_conf.default.export.types,1)}get importTypes(){return getExportOrImpotType(_conf.default.export.types,2)}}const globalConfs=exports.globalConfs=new VXETableConfig,v=exports.v="v4",setup=exports.setup=_config.config,globalStore=exports.globalStore={},VXETable=exports.VXETable={v:v,version:"4.6.7-beta.2",config:_config.config,globalStore:globalStore,interceptor:_interceptor.interceptor,renderer:_renderer.renderer,commands:_commands.commands,formats:_formats.formats,validators:_validators.validators,menus:_menus.menus,hooks:_hooks.hooks,use:use,t:t,_t:_t,setup:setup,globalConfs:globalConfs};var _default=exports.default=VXETable;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var _exportNames={use:!0,t:!0,_t:!0,globalConfs:!0,v:!0,setup:!0,globalStore:!0,VXETable:!0},_xeUtils=(exports.VXETable=void 0,exports._t=_t,exports.setup=exports.globalStore=exports.globalConfs=exports.default=void 0,exports.t=t,exports.use=use,exports.v=void 0,_interopRequireDefault(require("xe-utils"))),_conf=_interopRequireDefault(require("./src/conf")),_interceptor=require("./src/interceptor"),_renderer=(Object.keys(_interceptor).forEach(function(e){"default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(_exportNames,e)||e in exports&&exports[e]===_interceptor[e]||Object.defineProperty(exports,e,{enumerable:!0,get:function(){return _interceptor[e]}})}),require("./src/renderer")),_commands=(Object.keys(_renderer).forEach(function(e){"default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(_exportNames,e)||e in exports&&exports[e]===_renderer[e]||Object.defineProperty(exports,e,{enumerable:!0,get:function(){return _renderer[e]}})}),require("./src/commands")),_menus=(Object.keys(_commands).forEach(function(e){"default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(_exportNames,e)||e in exports&&exports[e]===_commands[e]||Object.defineProperty(exports,e,{enumerable:!0,get:function(){return _commands[e]}})}),require("./src/menus")),_formats=(Object.keys(_menus).forEach(function(e){"default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(_exportNames,e)||e in exports&&exports[e]===_menus[e]||Object.defineProperty(exports,e,{enumerable:!0,get:function(){return _menus[e]}})}),require("./src/formats")),_validators=(Object.keys(_formats).forEach(function(e){"default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(_exportNames,e)||e in exports&&exports[e]===_formats[e]||Object.defineProperty(exports,e,{enumerable:!0,get:function(){return _formats[e]}})}),require("./src/validators")),_hooks=(Object.keys(_validators).forEach(function(e){"default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(_exportNames,e)||e in exports&&exports[e]===_validators[e]||Object.defineProperty(exports,e,{enumerable:!0,get:function(){return _validators[e]}})}),require("./src/hooks")),_config=(Object.keys(_hooks).forEach(function(e){"default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(_exportNames,e)||e in exports&&exports[e]===_hooks[e]||Object.defineProperty(exports,e,{enumerable:!0,get:function(){return _hooks[e]}})}),require("./src/config")),_utils=(Object.keys(_config).forEach(function(e){"default"===e||"__esModule"===e||Object.prototype.hasOwnProperty.call(_exportNames,e)||e in exports&&exports[e]===_config[e]||Object.defineProperty(exports,e,{enumerable:!0,get:function(){return _config[e]}})}),require("../tools/utils"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function getExportOrImpotType(e,r){const o=[];return _xeUtils.default.objectEach(e,(e,t)=>{0!==e&&e!==r||o.push(t)}),o}const installedPlugins=[];function use(e,t){return e&&e.install&&-1===installedPlugins.indexOf(e)&&(e.install(VXETable,t),installedPlugins.push(e)),VXETable}function t(e,t){return _conf.default.i18n(e,t)}function _t(e,t){return e?_xeUtils.default.toValueString(_conf.default.translate?_conf.default.translate(e,t):e):""}class VXETableConfig{get zIndex(){return(0,_utils.getLastZIndex)()}get nextZIndex(){return(0,_utils.nextZIndex)()}get exportTypes(){return getExportOrImpotType(_conf.default.export.types,1)}get importTypes(){return getExportOrImpotType(_conf.default.export.types,2)}}const globalConfs=exports.globalConfs=new VXETableConfig,v=exports.v="v4",setup=exports.setup=_config.config,globalStore=exports.globalStore={},VXETable=exports.VXETable={v:v,version:"4.6.7",config:_config.config,globalStore:globalStore,interceptor:_interceptor.interceptor,renderer:_renderer.renderer,commands:_commands.commands,formats:_formats.formats,validators:_validators.validators,menus:_menus.menus,hooks:_hooks.hooks,use:use,t:t,_t:_t,setup:setup,globalConfs:globalConfs};var _default=exports.default=VXETable;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vxe-table",
3
- "version": "4.6.7-beta.2",
3
+ "version": "4.6.7",
4
4
  "description": "一个基于 vue 的 PC 端表单/表格组件,支持增删改查、虚拟列表、虚拟树、懒加载、快捷菜单、数据校验、树形结构、打印导出、表单渲染、数据分页、弹窗、自定义模板、渲染器、JSON 配置式...",
5
5
  "scripts": {
6
6
  "update": "npm install --legacy-peer-deps",
@@ -129,7 +129,43 @@ export default defineComponent({
129
129
 
130
130
  const computeBtnMode = computed(() => {
131
131
  const { type, mode } = props
132
- return (mode === 'text' || type === 'text') ? 'text' : 'button'
132
+ if (mode === 'text' || type === 'text' || ($xebuttonggroup && $xebuttonggroup.props.mode === 'text')) {
133
+ return 'text'
134
+ }
135
+ return 'button'
136
+ })
137
+
138
+ const computeBtnStatus = computed(() => {
139
+ const { status } = props
140
+ if (status) {
141
+ return status
142
+ }
143
+ if ($xebuttonggroup) {
144
+ return $xebuttonggroup.props.status
145
+ }
146
+ return ''
147
+ })
148
+
149
+ const computeBtnRound = computed(() => {
150
+ const { round } = props
151
+ if (round) {
152
+ return round
153
+ }
154
+ if ($xebuttonggroup) {
155
+ return $xebuttonggroup.props.round
156
+ }
157
+ return false
158
+ })
159
+
160
+ const computeBtnCircle = computed(() => {
161
+ const { circle } = props
162
+ if (circle) {
163
+ return circle
164
+ }
165
+ if ($xebuttonggroup) {
166
+ return $xebuttonggroup.props.circle
167
+ }
168
+ return false
133
169
  })
134
170
 
135
171
  const updateZindex = () => {
@@ -394,10 +430,13 @@ export default defineComponent({
394
430
  })
395
431
 
396
432
  const renderVN = () => {
397
- const { className, popupClassName, transfer, title, type, round, circle, destroyOnClose, status, name, disabled, loading } = props
433
+ const { className, popupClassName, transfer, title, type, destroyOnClose, name, disabled, loading } = props
398
434
  const { inited, showPanel } = reactData
399
435
  const isFormBtn = computeIsFormBtn.value
400
436
  const btnMode = computeBtnMode.value
437
+ const btnStatus = computeBtnStatus.value
438
+ const btnRound = computeBtnRound.value
439
+ const btnCircle = computeBtnCircle.value
401
440
  const vSize = computeSize.value
402
441
  if (slots.dropdowns) {
403
442
  return h('div', {
@@ -411,9 +450,9 @@ export default defineComponent({
411
450
  ref: refButton,
412
451
  class: ['vxe-button', `type--${btnMode}`, {
413
452
  [`size--${vSize}`]: vSize,
414
- [`theme--${status}`]: status,
415
- 'is--round': round,
416
- 'is--circle': circle,
453
+ [`theme--${btnStatus}`]: btnStatus,
454
+ 'is--round': btnRound,
455
+ 'is--circle': btnCircle,
417
456
  'is--disabled': disabled || loading,
418
457
  'is--loading': loading
419
458
  }],
@@ -458,9 +497,9 @@ export default defineComponent({
458
497
  ref: refButton,
459
498
  class: ['vxe-button', `type--${btnMode}`, className ? (XEUtils.isFunction(className) ? className({ $button: $xebutton }) : className) : '', {
460
499
  [`size--${vSize}`]: vSize,
461
- [`theme--${status}`]: status,
462
- 'is--round': round,
463
- 'is--circle': circle,
500
+ [`theme--${btnStatus}`]: btnStatus,
501
+ 'is--round': btnRound,
502
+ 'is--circle': btnCircle,
464
503
  'is--disabled': disabled || loading,
465
504
  'is--loading': loading
466
505
  }],
@@ -10,6 +10,11 @@ export default defineComponent({
10
10
  name: 'VxeButtonGroup',
11
11
  props: {
12
12
  options: Array as PropType<VxeButtonGroupPropTypes.Options>,
13
+ mode: String as PropType<VxeButtonGroupPropTypes.Mode>,
14
+ status: String as PropType<VxeButtonGroupPropTypes.Status>,
15
+ round: Boolean as PropType<VxeButtonGroupPropTypes.Round>,
16
+ circle: Boolean as PropType<VxeButtonGroupPropTypes.Circle>,
17
+ className: [String, Function] as PropType<VxeButtonGroupPropTypes.ClassName>,
13
18
  disabled: Boolean as PropType<VxeButtonGroupPropTypes.Disabled>,
14
19
  size: { type: String as PropType<VxeButtonGroupPropTypes.Size>, default: () => GlobalConfig.buttonGroup.size || GlobalConfig.size }
15
20
  },
@@ -51,10 +56,10 @@ export default defineComponent({
51
56
  Object.assign($xebuttongroup, buttonGroupMethods, buttonGroupPrivateMethods)
52
57
 
53
58
  const renderVN = () => {
54
- const { options } = props
59
+ const { className, options } = props
55
60
  const defaultSlot = slots.default
56
61
  return h('div', {
57
- class: 'vxe-button-group'
62
+ class: ['vxe-button-group', className ? (XEUtils.isFunction(className) ? className({ $buttonGroup: $xebuttongroup }) : className) : '']
58
63
  }, defaultSlot ? defaultSlot({}) : (options ? options.map((item, index) => {
59
64
  return h(VxeButtonComponent, {
60
65
  key: index,
@@ -1,5 +1,4 @@
1
- import { defineComponent, h, createApp, reactive } from 'vue'
2
- import VxeModalComponent from '../modal'
1
+ import { defineComponent, h, createApp, resolveComponent, reactive, ComponentOptions } from 'vue'
3
2
 
4
3
  import { VxeModalDefines } from '../../types/all'
5
4
 
@@ -18,7 +17,7 @@ const VxeDynamics = defineComponent({
18
17
  const { modals } = dynamicStore
19
18
  return h('div', {
20
19
  class: 'vxe-dynamics--modal'
21
- }, modals.map((item) => h(VxeModalComponent, item)))
20
+ }, modals.map((item) => h(resolveComponent('vxe-modal') as ComponentOptions, item)))
22
21
  }
23
22
  }
24
23
  })
@@ -712,7 +712,7 @@ export default defineComponent({
712
712
  * @param {String/Object} code 字符串或对象
713
713
  */
714
714
  commitProxy (proxyTarget: string | VxeToolbarPropTypes.ButtonConfig, ...args: any[]) {
715
- const { toolbarConfig, pagerConfig, editRules } = props
715
+ const { toolbarConfig, pagerConfig, editRules, validConfig } = props
716
716
  const { tablePage, formData } = reactData
717
717
  const isMsg = computeIsMsg.value
718
718
  const proxyOpts = computeProxyOpts.value
@@ -940,7 +940,7 @@ export default defineComponent({
940
940
  let restPromise: Promise<any> = Promise.resolve()
941
941
  if (editRules) {
942
942
  // 只校验新增和修改的数据
943
- restPromise = $xetable.validate(body.insertRecords.concat(updateRecords))
943
+ restPromise = $xetable[validConfig && validConfig.msgMode === 'full' ? 'fullValidate' : 'validate'](body.insertRecords.concat(updateRecords))
944
944
  }
945
945
  return restPromise.then((errMap) => {
946
946
  if (errMap) {
@@ -26,16 +26,26 @@ export interface VxeButtonGroupConstructor extends VxeComponentBase, VxeButtonGr
26
26
  export type VxeButtonGroupProps = {
27
27
  size?: VxeButtonGroupPropTypes.Size
28
28
  options?: VxeButtonGroupPropTypes.Options
29
+ mode?: VxeButtonGroupPropTypes.Mode
30
+ status?: VxeButtonGroupPropTypes.Status
31
+ round?: VxeButtonGroupPropTypes.Round
32
+ circle?: VxeButtonGroupPropTypes.Circle
29
33
  /**
30
34
  * 是否禁用
31
35
  */
32
36
  disabled?: VxeButtonGroupPropTypes.Disabled
37
+ className?: VxeButtonGroupPropTypes.ClassName
33
38
  }
34
39
 
35
40
  export namespace VxeButtonGroupPropTypes {
36
41
  export type Size = SizeType
37
42
  export type Options = VxeButtonProps[]
43
+ export type Round = boolean
44
+ export type Circle = boolean
38
45
  export type Disabled = boolean
46
+ export type Mode = VxeButtonPropTypes.Mode
47
+ export type Status = VxeButtonPropTypes.Status
48
+ export type ClassName = string | ((params: { $buttonGroup: VxeButtonGroupConstructor }) => string)
39
49
  }
40
50
 
41
51
  export interface ButtonPrivateComputed {
package/types/table.d.ts CHANGED
@@ -1968,6 +1968,12 @@ export namespace VxeTablePropTypes {
1968
1968
  * 用于 mouse-config.area & column.type=checkbox|radio,开启空格键切换复选框或单选框状态功能
1969
1969
  */
1970
1970
  isChecked?: boolean
1971
+ /**
1972
+ * 用于 mouse-config.area,方向键光标锁,开启后将支持两种状态
1973
+ * 非聚焦式输入状态:默认情况下,可以按方向键移动单元格。
1974
+ * 聚焦式输入状态:如果需要移动光标,可以按 F2 键或者鼠标左键点击输入框,切换为聚焦输入状态,就可以用方向键左右移动光标
1975
+ */
1976
+ arrowCursorLock?: boolean
1971
1977
  /**
1972
1978
  * 用于 mouse-config.area,是否将回车键行为改成 Tab 键行为
1973
1979
  */