resolver-egretimp-plus 0.0.4

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 (121) hide show
  1. package/babel.config.js +14 -0
  2. package/dist/index.js +2 -0
  3. package/dist/index.js.LICENSE.txt +8 -0
  4. package/dist/theme/element/index.css +1 -0
  5. package/dist/theme/element/src/components/card.scss +4 -0
  6. package/dist/theme/element/src/components/collapse.scss +16 -0
  7. package/dist/theme/element/src/components/date.scss +13 -0
  8. package/dist/theme/element/src/components/form.scss +54 -0
  9. package/dist/theme/element/src/components/index.scss +42 -0
  10. package/dist/theme/element/src/components/input.scss +15 -0
  11. package/dist/theme/element/src/components/message.scss +31 -0
  12. package/dist/theme/element/src/components/scrollbar.scss +14 -0
  13. package/dist/theme/element/src/components/select.scss +17 -0
  14. package/dist/theme/element/src/components/steps.scss +6 -0
  15. package/dist/theme/element/src/components/table.scss +8 -0
  16. package/dist/theme/element/src/components/tabs.scss +68 -0
  17. package/dist/theme/element/src/components/tree.scss +0 -0
  18. package/dist/theme/element/src/index.scss +79 -0
  19. package/index.js +17 -0
  20. package/package.json +45 -0
  21. package/scripts/gulpfile.mjs +73 -0
  22. package/scripts/webpack.config.js +81 -0
  23. package/src/analysisComponent.jsx +166 -0
  24. package/src/components/helper/button.js +17 -0
  25. package/src/components/helper/dock.js +120 -0
  26. package/src/components/icons/question-filled.vue +13 -0
  27. package/src/components/packages/CmiButton.vue +84 -0
  28. package/src/components/packages/CmiCalendar.vue +138 -0
  29. package/src/components/packages/CmiCell.vue +34 -0
  30. package/src/components/packages/CmiCheckbox.vue +63 -0
  31. package/src/components/packages/CmiDatetimePicker.vue +84 -0
  32. package/src/components/packages/CmiDropdownMenu.vue +57 -0
  33. package/src/components/packages/CmiInput.vue +45 -0
  34. package/src/components/packages/CmiLink.vue +28 -0
  35. package/src/components/packages/CmiPicker.vue +120 -0
  36. package/src/components/packages/CmiRadio.vue +29 -0
  37. package/src/components/packages/CmiSearch.vue +39 -0
  38. package/src/components/packages/CmiSelect.vue +84 -0
  39. package/src/components/packages/CustomComponentCard.vue +40 -0
  40. package/src/components/packages/CustomComponentCardH5.vue +40 -0
  41. package/src/components/packages/CustomComponentCol.vue +69 -0
  42. package/src/components/packages/CustomComponentColH5.vue +8 -0
  43. package/src/components/packages/CustomComponentCollapse.vue +183 -0
  44. package/src/components/packages/CustomComponentCollapseH5.vue +37 -0
  45. package/src/components/packages/CustomComponentCycle.vue +95 -0
  46. package/src/components/packages/CustomComponentCycleTabPane.vue +92 -0
  47. package/src/components/packages/CustomComponentDialog.vue +162 -0
  48. package/src/components/packages/CustomComponentEditor.vue +43 -0
  49. package/src/components/packages/CustomComponentFormLayout.vue +63 -0
  50. package/src/components/packages/CustomComponentFormLayoutH5.vue +55 -0
  51. package/src/components/packages/CustomComponentGrid.vue +29 -0
  52. package/src/components/packages/CustomComponentGridCol.vue +29 -0
  53. package/src/components/packages/CustomComponentInputDialog.vue +144 -0
  54. package/src/components/packages/CustomComponentPlain.vue +80 -0
  55. package/src/components/packages/CustomComponentRow.vue +67 -0
  56. package/src/components/packages/CustomComponentSelectEmployees.vue +133 -0
  57. package/src/components/packages/CustomComponentSendMail.vue +72 -0
  58. package/src/components/packages/CustomComponentSteps.vue +41 -0
  59. package/src/components/packages/CustomComponentTabPane.vue +41 -0
  60. package/src/components/packages/CustomComponentTabPaneH5.vue +30 -0
  61. package/src/components/packages/CustomComponentTable.jsx +406 -0
  62. package/src/components/packages/CustomComponentTableH5.vue +58 -0
  63. package/src/components/packages/CustomComponentTabs.vue +75 -0
  64. package/src/components/packages/CustomComponentTabsH5.vue +86 -0
  65. package/src/components/packages/CustomComponentTree.vue +28 -0
  66. package/src/components/packages/ElButton.vue +90 -0
  67. package/src/components/packages/ElCheckbox.vue +55 -0
  68. package/src/components/packages/ElDatePicker.vue +58 -0
  69. package/src/components/packages/ElInput.vue +23 -0
  70. package/src/components/packages/ElInputNumber.vue +54 -0
  71. package/src/components/packages/ElPagination.vue +56 -0
  72. package/src/components/packages/ElRadio.vue +44 -0
  73. package/src/components/packages/ElSelect.vue +73 -0
  74. package/src/components/packages/ElText.vue +48 -0
  75. package/src/components/packages/ElTimePicker.vue +34 -0
  76. package/src/components/patchComponents.js +46 -0
  77. package/src/components/styles/CustomComponenTable.scss +125 -0
  78. package/src/components/tabs/index.js +8 -0
  79. package/src/components/tabs/src/constants.js +23 -0
  80. package/src/components/tabs/src/tab-bar.js +8 -0
  81. package/src/components/tabs/src/tab-bar.vue +92 -0
  82. package/src/components/tabs/src/tab-nav.jsx +413 -0
  83. package/src/components/tabs/src/tab-pane.js +15 -0
  84. package/src/components/tabs/src/tab-pane.vue +80 -0
  85. package/src/components/tabs/src/tabs.jsx +217 -0
  86. package/src/components/tabs/style/css.js +2 -0
  87. package/src/components/tabs/style/index.js +2 -0
  88. package/src/components/thirdPartyFrame/index.js +32 -0
  89. package/src/components/thirdPartyFrame/src/ThirdPartyFrame.vue +123 -0
  90. package/src/hooks/index.js +129 -0
  91. package/src/hooks/pageConfig.js +20 -0
  92. package/src/index.jsx +140 -0
  93. package/src/renderer.jsx +68 -0
  94. package/src/rules/eventsSupplement.js +439 -0
  95. package/src/rules/parseCondition.js +359 -0
  96. package/src/rules/ruleUtils.js +208 -0
  97. package/src/rules/rulesDriver.js +118 -0
  98. package/src/theme/element/components/card.scss +4 -0
  99. package/src/theme/element/components/collapse.scss +16 -0
  100. package/src/theme/element/components/date.scss +13 -0
  101. package/src/theme/element/components/form.scss +54 -0
  102. package/src/theme/element/components/index.scss +42 -0
  103. package/src/theme/element/components/input.scss +15 -0
  104. package/src/theme/element/components/message.scss +31 -0
  105. package/src/theme/element/components/scrollbar.scss +14 -0
  106. package/src/theme/element/components/select.scss +17 -0
  107. package/src/theme/element/components/steps.scss +6 -0
  108. package/src/theme/element/components/table.scss +8 -0
  109. package/src/theme/element/components/tabs.scss +68 -0
  110. package/src/theme/element/components/tree.scss +0 -0
  111. package/src/theme/element/index.scss +79 -0
  112. package/src/utils/common.js +230 -0
  113. package/src/utils/const.js +198 -0
  114. package/src/utils/defaultVal.js +23 -0
  115. package/src/utils/format.js +19 -0
  116. package/src/utils/index.js +4 -0
  117. package/src/utils/is.js +69 -0
  118. package/src/utils/preserveFunc.js +33 -0
  119. package/src/utils/render.jsx +714 -0
  120. package/src/utils/request.js +10 -0
  121. package/src/utils/valid.js +71 -0
@@ -0,0 +1,125 @@
1
+ .error-tip-block {
2
+ & + .el-form-item__error {
3
+ position: relative;
4
+ }
5
+ }
6
+ .custom-component-table {
7
+ --boder-radius: 4px;
8
+ border-radius: var(--boder-radius);
9
+ width: 100%;
10
+ .el-table, &.el-table {
11
+ --el-table-header-bg-color: #f5f6f7;
12
+ --el-table-header-text-color: #646a73;
13
+ }
14
+ .el-table--border {
15
+ border: 1px solid var(--el-table-border-color);
16
+ border-radius: var(--boder-radius);
17
+ &::before {
18
+ width: 0px;
19
+ // border-left: 1px solid var(--el-table-border-color);
20
+ // border-radius: var(--boder-radius);
21
+ // background-color: transparent;
22
+ }
23
+ &::after {
24
+ width: 0px;
25
+ // border-right: 1px solid var(--el-table-border-color);
26
+ // border-radius: var(--boder-radius);
27
+ // background-color: transparent;
28
+ }
29
+ .el-table__inner-wrapper {
30
+ &::before {
31
+ height: 0px;
32
+ // border-bottom: 1px solid var(--el-table-border-color);
33
+ // border-radius: var(--boder-radius);
34
+ // background-color: transparent;
35
+ }
36
+ &::after {
37
+ height: 0px;
38
+ // border-top: 1px solid var(--el-table-border-color);
39
+ // border-radius: var(--boder-radius);
40
+ // background-color: transparent;
41
+ }
42
+ .el-table__border-left-patch {
43
+ display: none;
44
+ }
45
+ }
46
+ .el-table__cell:last-of-type {
47
+ border-right: none;
48
+ }
49
+ .el-table__body {
50
+ tbody {
51
+ tr:last-of-type {
52
+ .el-table__cell {
53
+ border-bottom: none;
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+ .el-table .el-table__cell {
60
+ padding: 4px 0;
61
+ }
62
+ .el-form-item {
63
+ margin-right: 0;
64
+ margin-bottom: 0;
65
+ }
66
+ thead th {
67
+ font-weight: 400;
68
+ height: 40px;
69
+ .head-span {
70
+ text-overflow: ellipsis;
71
+ overflow: hidden;
72
+ white-space: nowrap;
73
+ }
74
+ }
75
+ th.el-table__cell.is-leaf {
76
+ border-bottom: none;
77
+ }
78
+ td.el-table__cell {
79
+ color: var(--el-input-text-color,var(--el-text-color-regular));
80
+ }
81
+ .el-table__cell {
82
+ height: 40px;
83
+ .el-date-editor, .el-date-editor--date{
84
+ .el-input__wrapper{
85
+ padding: 0 8px;
86
+ }
87
+ }
88
+ .el-select__wrapper, .el-input__wrapper {
89
+ box-shadow: none;
90
+ border-bottom: 1px solid var(--el-border-color);
91
+ padding: 0;
92
+ border-radius: 0;
93
+ background-color: transparent;
94
+ min-height: 26px;
95
+ &.is-focused {
96
+ border-color: var(--el-color-primary);
97
+ }
98
+ &.is-focus {
99
+ border-color: var(--el-color-primary);
100
+ }
101
+ }
102
+ .is-error {
103
+ .el-select__wrapper, .el-input__wrapper {
104
+ box-shadow: none;
105
+ border-bottom: 1px solid var(--el-color-danger);
106
+ }
107
+ }
108
+ }
109
+ .cell {
110
+ // line-height: 16px;
111
+ }
112
+ .pagination-wrap {
113
+ display: flex;
114
+ margin-top: 16px;
115
+ }
116
+ .hidden-column {
117
+ display: none;
118
+ }
119
+ .hidden-column + .el-table__cell {
120
+ border: none;
121
+ }
122
+ .next-hidden-column {
123
+ border: none;
124
+ }
125
+ }
@@ -0,0 +1,8 @@
1
+ import Tabs from './src/tabs.jsx'
2
+ import TabPane from './src/tab-pane.vue'
3
+
4
+ export default Tabs
5
+
6
+ export {
7
+ TabPane
8
+ }
@@ -0,0 +1,23 @@
1
+ // import type { ComputedRef, InjectionKey, Ref, Slots, UnwrapRef } from 'vue'
2
+ // import type { TabsProps } from './tabs'
3
+ // import type { TabPaneProps } from './tab-pane'
4
+
5
+ // export type TabsPaneContext = UnwrapRef<{
6
+ // uid: number
7
+ // slots: Slots
8
+ // props: TabPaneProps
9
+ // paneName: ComputedRef<string | number | undefined>
10
+ // active: ComputedRef<boolean>
11
+ // index: Ref<string | undefined>
12
+ // isClosable: ComputedRef<boolean>
13
+ // }>
14
+
15
+ // export interface TabsRootContext {
16
+ // props: TabsProps
17
+ // currentName: Ref<string | number>
18
+ // registerPane: (pane: TabsPaneContext) => void
19
+ // unregisterPane: (uid: number) => void
20
+ // }
21
+
22
+ export const tabsRootContextKey =
23
+ Symbol('tabsRootContextKey')
@@ -0,0 +1,8 @@
1
+ import { buildProps, definePropType, mutable } from 'element-plus/es/utils/index.mjs'
2
+
3
+ export const tabBarProps = buildProps({
4
+ tabs: {
5
+ type: definePropType(Array),
6
+ default: () => mutable([]),
7
+ },
8
+ })
@@ -0,0 +1,92 @@
1
+ <template>
2
+ <div
3
+ ref="barRef"
4
+ :class="[ns.e('active-bar'), ns.is(rootTabs.props.tabPosition)]"
5
+ :style="barStyle"
6
+ />
7
+ </template>
8
+
9
+ <script setup>
10
+ import { getCurrentInstance, defineOptions, defineProps, inject, nextTick, ref, watch } from 'vue'
11
+ import { useResizeObserver } from '@vueuse/core'
12
+ import { capitalize, throwError } from 'element-plus/es/utils/index.mjs'
13
+ import { useNamespace } from 'element-plus/es/hooks/index.mjs'
14
+ import { tabsRootContextKey } from './constants.js'
15
+ import { tabBarProps } from './tab-bar'
16
+
17
+ // import type { CSSProperties } from 'vue'
18
+
19
+ const COMPONENT_NAME = 'ElTabBar'
20
+ defineOptions({
21
+ name: COMPONENT_NAME,
22
+ })
23
+ const props = defineProps(tabBarProps)
24
+
25
+ const instance = getCurrentInstance()
26
+ const rootTabs = inject(tabsRootContextKey)
27
+ if (!rootTabs) throwError(COMPONENT_NAME, '<el-tabs><el-tab-bar /></el-tabs>')
28
+
29
+ const ns = useNamespace('tabs')
30
+
31
+ const barRef = ref()
32
+ const barStyle = ref()
33
+
34
+ const getBarStyle = () => {
35
+ let offset = 0
36
+ let tabSize = 0
37
+
38
+ const sizeName = ['top', 'bottom'].includes(rootTabs.props.tabPosition)
39
+ ? 'width'
40
+ : 'height'
41
+ const sizeDir = sizeName === 'width' ? 'x' : 'y'
42
+ const position = sizeDir === 'x' ? 'left' : 'top'
43
+
44
+ props.tabs.every((tab) => {
45
+ const $el = instance.parent?.refs?.[`tab-${tab.uid}`]
46
+ if (!$el) return false
47
+
48
+ if (!tab.active) {
49
+ return true
50
+ }
51
+
52
+ offset = $el[`offset${capitalize(position)}`]
53
+ tabSize = $el[`client${capitalize(sizeName)}`]
54
+
55
+ const tabStyles = window.getComputedStyle($el)
56
+
57
+ if (sizeName === 'width') {
58
+ if (props.tabs.length > 1) {
59
+ tabSize -=
60
+ Number.parseFloat(tabStyles.paddingLeft) +
61
+ Number.parseFloat(tabStyles.paddingRight)
62
+ }
63
+ offset += Number.parseFloat(tabStyles.paddingLeft)
64
+ }
65
+ return false
66
+ })
67
+
68
+ return {
69
+ [sizeName]: `${tabSize}px`,
70
+ transform: `translate${capitalize(sizeDir)}(${offset}px)`,
71
+ }
72
+ }
73
+
74
+ const update = () => (barStyle.value = getBarStyle())
75
+
76
+ watch(
77
+ () => props.tabs,
78
+ async () => {
79
+ await nextTick()
80
+ update()
81
+ },
82
+ { immediate: true }
83
+ )
84
+ useResizeObserver(barRef, () => update())
85
+
86
+ defineExpose({
87
+ /** @description tab root html element */
88
+ ref: barRef,
89
+ /** @description method to manually update tab bar style */
90
+ update,
91
+ })
92
+ </script>
@@ -0,0 +1,413 @@
1
+ import {
2
+ computed,
3
+ defineComponent,
4
+ getCurrentInstance,
5
+ inject,
6
+ nextTick,
7
+ onMounted,
8
+ onUpdated,
9
+ ref,
10
+ watch,
11
+ } from 'vue'
12
+ import {
13
+ useDocumentVisibility,
14
+ useResizeObserver,
15
+ useWindowFocus,
16
+ } from '@vueuse/core'
17
+ import {
18
+ buildProps,
19
+ capitalize,
20
+ definePropType,
21
+ mutable,
22
+ throwError,
23
+ } from 'element-plus/es/utils/index.mjs'
24
+ import { EVENT_CODE } from 'element-plus/es/constants/index.mjs'
25
+ import { ElIcon } from 'element-plus/es/components/icon/index.mjs'
26
+ import { ArrowLeft, ArrowRight, Close } from '@element-plus/icons-vue'
27
+ import { useNamespace } from 'element-plus/es/hooks/index.mjs'
28
+ import TabBar from './tab-bar.vue'
29
+ import { tabsRootContextKey } from './constants.js'
30
+
31
+ // import type { CSSProperties, ExtractPropTypes } from 'vue'
32
+ // import type { TabsPaneContext } from './constants'
33
+ // import type { TabPaneName } from './tabs'
34
+
35
+ // interface Scrollable {
36
+ // next?: boolean
37
+ // prev?: number
38
+ // }
39
+
40
+ export const tabNavProps = buildProps({
41
+ panes: {
42
+ type: definePropType(Array),
43
+ default: () => mutable([]),
44
+ },
45
+ currentName: {
46
+ type: [String, Number],
47
+ default: '',
48
+ },
49
+ editable: Boolean,
50
+ type: {
51
+ type: String,
52
+ values: ['card', 'border-card', ''],
53
+ default: '',
54
+ },
55
+ stretch: Boolean,
56
+ })
57
+
58
+ export const tabNavEmits = {
59
+ tabClick: (tab, tabName, ev) =>
60
+ ev instanceof Event,
61
+ tabRemove: (tab, ev) => ev instanceof Event,
62
+ }
63
+
64
+ // export type TabNavProps = ExtractPropTypes<typeof tabNavProps>
65
+ // export type TabNavEmits = typeof tabNavEmits
66
+
67
+ const COMPONENT_NAME = 'ElTabNav'
68
+ const TabNav = defineComponent({
69
+ name: COMPONENT_NAME,
70
+ props: tabNavProps,
71
+ emits: tabNavEmits,
72
+ setup(props, { expose, emit }) {
73
+ const vm = getCurrentInstance()
74
+
75
+ const rootTabs = inject(tabsRootContextKey)
76
+ if (!rootTabs) throwError(COMPONENT_NAME, `<el-tabs><tab-nav /></el-tabs>`)
77
+
78
+ const ns = useNamespace('tabs')
79
+ const visibility = useDocumentVisibility()
80
+ const focused = useWindowFocus()
81
+
82
+ const navScroll$ = ref()
83
+ const nav$ = ref()
84
+ const el$ = ref()
85
+
86
+ const tabBarRef = ref()
87
+
88
+ const scrollable = ref(false)
89
+ const navOffset = ref(0)
90
+ const isFocus = ref(false)
91
+ const focusable = ref(true)
92
+
93
+ const sizeName = computed(() =>
94
+ ['top', 'bottom'].includes(rootTabs.props.tabPosition)
95
+ ? 'width'
96
+ : 'height'
97
+ )
98
+ const navStyle = computed(() => {
99
+ const dir = sizeName.value === 'width' ? 'X' : 'Y'
100
+ return {
101
+ transform: `translate${dir}(-${navOffset.value}px)`,
102
+ }
103
+ })
104
+
105
+ const scrollPrev = () => {
106
+ if (!navScroll$.value) return
107
+
108
+ const containerSize =
109
+ navScroll$.value[`offset${capitalize(sizeName.value)}`]
110
+ const currentOffset = navOffset.value
111
+
112
+ if (!currentOffset) return
113
+
114
+ const newOffset =
115
+ currentOffset > containerSize ? currentOffset - containerSize : 0
116
+
117
+ navOffset.value = newOffset
118
+ }
119
+
120
+ const scrollNext = () => {
121
+ if (!navScroll$.value || !nav$.value) return
122
+
123
+ const navSize = nav$.value[`offset${capitalize(sizeName.value)}`]
124
+ const containerSize =
125
+ navScroll$.value[`offset${capitalize(sizeName.value)}`]
126
+ const currentOffset = navOffset.value
127
+
128
+ if (navSize - currentOffset <= containerSize) return
129
+
130
+ const newOffset =
131
+ navSize - currentOffset > containerSize * 2
132
+ ? currentOffset + containerSize
133
+ : navSize - containerSize
134
+
135
+ navOffset.value = newOffset
136
+ }
137
+
138
+ const scrollToActiveTab = async () => {
139
+ const nav = nav$.value
140
+ if (!scrollable.value || !el$.value || !navScroll$.value || !nav) return
141
+
142
+ await nextTick()
143
+
144
+ const activeTab = el$.value.querySelector('.is-active')
145
+ if (!activeTab) return
146
+
147
+ const navScroll = navScroll$.value
148
+ const isHorizontal = ['top', 'bottom'].includes(
149
+ rootTabs.props.tabPosition
150
+ )
151
+ const activeTabBounding = activeTab.getBoundingClientRect()
152
+ const navScrollBounding = navScroll.getBoundingClientRect()
153
+ const maxOffset = isHorizontal
154
+ ? nav.offsetWidth - navScrollBounding.width
155
+ : nav.offsetHeight - navScrollBounding.height
156
+ const currentOffset = navOffset.value
157
+ let newOffset = currentOffset
158
+
159
+ if (isHorizontal) {
160
+ if (activeTabBounding.left < navScrollBounding.left) {
161
+ newOffset =
162
+ currentOffset - (navScrollBounding.left - activeTabBounding.left)
163
+ }
164
+ if (activeTabBounding.right > navScrollBounding.right) {
165
+ newOffset =
166
+ currentOffset + activeTabBounding.right - navScrollBounding.right
167
+ }
168
+ } else {
169
+ if (activeTabBounding.top < navScrollBounding.top) {
170
+ newOffset =
171
+ currentOffset - (navScrollBounding.top - activeTabBounding.top)
172
+ }
173
+ if (activeTabBounding.bottom > navScrollBounding.bottom) {
174
+ newOffset =
175
+ currentOffset +
176
+ (activeTabBounding.bottom - navScrollBounding.bottom)
177
+ }
178
+ }
179
+ newOffset = Math.max(newOffset, 0)
180
+ navOffset.value = Math.min(newOffset, maxOffset)
181
+ }
182
+
183
+ const update = () => {
184
+ if (!nav$.value || !navScroll$.value) return
185
+
186
+ props.stretch && tabBarRef.value?.update()
187
+
188
+ const navSize = nav$.value[`offset${capitalize(sizeName.value)}`]
189
+ const containerSize =
190
+ navScroll$.value[`offset${capitalize(sizeName.value)}`]
191
+ const currentOffset = navOffset.value
192
+
193
+ if (containerSize < navSize) {
194
+ scrollable.value = scrollable.value || {}
195
+ scrollable.value.prev = currentOffset
196
+ scrollable.value.next = currentOffset + containerSize < navSize
197
+ if (navSize - currentOffset < containerSize) {
198
+ navOffset.value = navSize - containerSize
199
+ }
200
+ } else {
201
+ scrollable.value = false
202
+ if (currentOffset > 0) {
203
+ navOffset.value = 0
204
+ }
205
+ }
206
+ }
207
+
208
+ const changeTab = (e) => {
209
+ const code = e.code
210
+
211
+ const { up, down, left, right } = EVENT_CODE
212
+ if (![up, down, left, right].includes(code)) return
213
+
214
+ // 左右上下键更换tab
215
+ const tabList = Array.from(
216
+ (e.currentTarget).querySelectorAll<HTMLDivElement>(
217
+ '[role=tab]:not(.is-disabled)'
218
+ )
219
+ )
220
+ const currentIndex = tabList.indexOf(e.target)
221
+
222
+ let nextIndex
223
+ if (code === left || code === up) {
224
+ // left
225
+ if (currentIndex === 0) {
226
+ // first
227
+ nextIndex = tabList.length - 1
228
+ } else {
229
+ nextIndex = currentIndex - 1
230
+ }
231
+ } else {
232
+ // right
233
+ if (currentIndex < tabList.length - 1) {
234
+ // not last
235
+ nextIndex = currentIndex + 1
236
+ } else {
237
+ nextIndex = 0
238
+ }
239
+ }
240
+ tabList[nextIndex].focus({ preventScroll: true }) // 改变焦点元素
241
+ tabList[nextIndex].click() // 选中下一个tab
242
+ setFocus()
243
+ }
244
+
245
+ const setFocus = () => {
246
+ if (focusable.value) isFocus.value = true
247
+ }
248
+ const removeFocus = () => (isFocus.value = false)
249
+
250
+ watch(visibility, (visibility) => {
251
+ if (visibility === 'hidden') {
252
+ focusable.value = false
253
+ } else if (visibility === 'visible') {
254
+ setTimeout(() => (focusable.value = true), 50)
255
+ }
256
+ })
257
+ watch(focused, (focused) => {
258
+ if (focused) {
259
+ setTimeout(() => (focusable.value = true), 50)
260
+ } else {
261
+ focusable.value = false
262
+ }
263
+ })
264
+
265
+ useResizeObserver(el$, update)
266
+
267
+ onMounted(() => setTimeout(() => scrollToActiveTab(), 0))
268
+ onUpdated(() => update())
269
+
270
+ expose({
271
+ scrollToActiveTab,
272
+ removeFocus,
273
+ })
274
+
275
+ watch(
276
+ () => props.panes,
277
+ () => vm.update(),
278
+ { flush: 'post', deep: true }
279
+ )
280
+
281
+ return () => {
282
+ const scrollBtn = scrollable.value
283
+ ? [
284
+ <span
285
+ class={[
286
+ ns.e('nav-prev'),
287
+ ns.is('disabled', !scrollable.value.prev),
288
+ ]}
289
+ onClick={scrollPrev}
290
+ >
291
+ <ElIcon>
292
+ <ArrowLeft />
293
+ </ElIcon>
294
+ </span>,
295
+ <span
296
+ class={[
297
+ ns.e('nav-next'),
298
+ ns.is('disabled', !scrollable.value.next),
299
+ ]}
300
+ onClick={scrollNext}
301
+ >
302
+ <ElIcon>
303
+ <ArrowRight />
304
+ </ElIcon>
305
+ </span>,
306
+ ]
307
+ : null
308
+
309
+ const tabs = props.panes.map((pane, index) => {
310
+ const uid = pane.uid
311
+ const disabled = pane.props.disabled
312
+ const tabName = pane.props.name ?? pane.index ?? `${index}`
313
+ const closable = !disabled && (pane.isClosable || props.editable)
314
+ pane.index = `${index}`
315
+
316
+ const btnClose = closable ? (
317
+ <ElIcon
318
+ class="is-icon-close"
319
+ // `onClick` not exist when generate dts
320
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
321
+ // @ts-ignore
322
+ onClick={(ev) => emit('tabRemove', pane, ev)}
323
+ >
324
+ <Close />
325
+ </ElIcon>
326
+ ) : null
327
+
328
+ const tabLabelContent = pane.slots.label?.() || pane.props.label
329
+ const tabindex = !disabled && pane.active ? 0 : -1
330
+
331
+ return (
332
+ <div
333
+ ref={`tab-${uid}`}
334
+ class={[
335
+ ns.e('item'),
336
+ ns.is(rootTabs.props.tabPosition),
337
+ ns.is('active', pane.active),
338
+ ns.is('disabled', disabled),
339
+ ns.is('closable', closable),
340
+ ns.is('focus', isFocus.value),
341
+ ]}
342
+ id={`tab-${tabName}`}
343
+ key={`tab-${uid}`}
344
+ aria-controls={`pane-${tabName}`}
345
+ role="tab"
346
+ aria-selected={pane.active}
347
+ tabindex={tabindex}
348
+ onFocus={() => setFocus()}
349
+ onBlur={() => removeFocus()}
350
+ onClick={(ev) => {
351
+ removeFocus()
352
+ emit('tabClick', pane, tabName, ev)
353
+ }}
354
+ onKeydown={(ev) => {
355
+ if (
356
+ closable &&
357
+ (ev.code === EVENT_CODE.delete ||
358
+ ev.code === EVENT_CODE.backspace)
359
+ ) {
360
+ emit('tabRemove', pane, ev)
361
+ }
362
+ }}
363
+ >
364
+ {...[tabLabelContent, btnClose]}
365
+ </div>
366
+ )
367
+ })
368
+
369
+ return (
370
+ <div
371
+ ref={el$}
372
+ class={[
373
+ ns.e('nav-wrap'),
374
+ ns.is('scrollable', !!scrollable.value),
375
+ ns.is(rootTabs.props.tabPosition),
376
+ ]}
377
+ >
378
+ {scrollBtn}
379
+ <div class={ns.e('nav-scroll')} ref={navScroll$}>
380
+ <div
381
+ class={[
382
+ ns.e('nav'),
383
+ ns.is(rootTabs.props.tabPosition),
384
+ ns.is(
385
+ 'stretch',
386
+ props.stretch &&
387
+ ['top', 'bottom'].includes(rootTabs.props.tabPosition)
388
+ ),
389
+ ]}
390
+ ref={nav$}
391
+ style={navStyle.value}
392
+ role="tablist"
393
+ onKeydown={changeTab}
394
+ >
395
+ {...[
396
+ !props.type ? (
397
+ <TabBar ref={tabBarRef} tabs={[...props.panes]} />
398
+ ) : null,
399
+ tabs,
400
+ ]}
401
+ </div>
402
+ </div>
403
+ </div>
404
+ )
405
+ }
406
+ },
407
+ })
408
+
409
+ // export type TabNavInstance = InstanceType<typeof TabNav> & {
410
+ // scrollToActiveTab: () => Promise<void>
411
+ // removeFocus: () => void
412
+ // }
413
+ export default TabNav
@@ -0,0 +1,15 @@
1
+ import { buildProps } from 'element-plus/es/utils/index.mjs'
2
+
3
+ export const tabPaneProps = buildProps({
4
+ label: {
5
+ type: String,
6
+ default: '',
7
+ },
8
+ name: {
9
+ type: [String, Number],
10
+ },
11
+ closable: Boolean,
12
+ disabled: Boolean,
13
+ lazy: Boolean,
14
+ })
15
+