@gm-pc/keyboard 1.24.9-beta.12 → 1.24.9-beta.13

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/src/core/wrap.tsx CHANGED
@@ -1,253 +1,253 @@
1
- import React, { FC, useEffect, useRef } from 'react'
2
- import { throttle } from 'lodash'
3
-
4
- import {
5
- doFocus,
6
- getKey,
7
- KEYBOARD_DIRECTION,
8
- KEYBOARD_ENTER,
9
- KEYBOARD_TAB,
10
- KeyboardActionsName,
11
- WrapContext,
12
- } from '../utils'
13
- import { KeyboardCustomEvent, WrapProps } from '../types'
14
-
15
- /**
16
- * 包裹 Table,使 Table 具有键盘响应能力
17
- *
18
- * Wrap 负责调度,接收来自 Cell 的操作反馈,然后做出后续动作
19
- * Cell 监听键盘事件,把 方向、Enter、Tab 反馈给 Wrap
20
- * Wrap 做出动作,其中包括 focus 到 Cell
21
- * */
22
- const Wrap: FC<WrapProps> = ({
23
- id,
24
- children,
25
- onAddRow,
26
- allowAddRowOnDownKey = true,
27
- columnKeys,
28
- dataLength,
29
- fixedWidths,
30
- onBeforeDispatch,
31
- }) => {
32
- const timer = useRef<number | undefined>()
33
-
34
- // 处理 focus
35
- const doFocusWithColumnRowKey = (
36
- actionName: string,
37
- rowKey: number,
38
- columnKey: string,
39
- cellKey: string
40
- ) => {
41
- const result =
42
- onBeforeDispatch &&
43
- onBeforeDispatch({
44
- actionName,
45
- to: { rowKey, columnKey },
46
- from: getKey(cellKey),
47
- })
48
-
49
- // 返回 false 组织默认行为
50
- if (result === false) {
51
- return
52
- }
53
-
54
- doFocus(id, rowKey, columnKey)
55
- }
56
-
57
- // 处理方向
58
- const doDirectionRight = (rowKey: number, columnKey: string, cellKey: string) => {
59
- const columnIndex = columnKeys.indexOf(columnKey)
60
- // 如果不是最后一列
61
- if (columnIndex < columnKeys.length - 1) {
62
- doFocusWithColumnRowKey(
63
- KeyboardActionsName.RIGHT,
64
- rowKey,
65
- columnKeys[columnIndex + 1],
66
- cellKey
67
- )
68
- }
69
- }
70
- const doDirectionLeft = (rowKey: number, columnKey: string, cellKey: string) => {
71
- const columnIndex = columnKeys.indexOf(columnKey)
72
- // 如果不是第一列
73
- if (columnIndex > 0) {
74
- doFocusWithColumnRowKey(
75
- KeyboardActionsName.LEFT,
76
- rowKey,
77
- columnKeys[columnIndex - 1],
78
- cellKey
79
- )
80
- }
81
- }
82
- const doDirectionDown = (rowKey: number, columnKey: string, cellKey: string) => {
83
- window.clearTimeout(timer.current)
84
-
85
- // 往下一个
86
- if (rowKey < dataLength - 1) {
87
- doFocusWithColumnRowKey(KeyboardActionsName.DOWN, rowKey + 1, columnKey, cellKey)
88
- }
89
- // 最后一行
90
- else if (rowKey === dataLength - 1) {
91
- if (allowAddRowOnDownKey) {
92
- onAddRow()
93
- }
94
- timer.current = window.setTimeout(() => {
95
- // 去到第一列
96
- doFocusWithColumnRowKey(
97
- KeyboardActionsName.DOWN,
98
- rowKey + 1,
99
- columnKeys[0],
100
- cellKey
101
- )
102
- const table = document.querySelector('.gm-table-x')
103
- if (table) table.scrollLeft = 0
104
- }, 10)
105
- }
106
- }
107
- const doDirectionUp = (rowKey: number, columnKey: string, cellKey: string) => {
108
- // 往上一个
109
- if (rowKey > 0) {
110
- doFocusWithColumnRowKey(KeyboardActionsName.UP, rowKey - 1, columnKey, cellKey)
111
- }
112
- // 循环到最后一个
113
- else if (rowKey === 0) {
114
- doFocusWithColumnRowKey(KeyboardActionsName.UP, dataLength - 1, columnKey, cellKey)
115
- }
116
- }
117
-
118
- // 处理方向事件,依赖 dataLength 的变动
119
- useEffect(() => {
120
- const handleDirection = throttle((event: CustomEvent<KeyboardCustomEvent>) => {
121
- const { cellKey, direction } = event.detail
122
- const { rowKey, columnKey } = getKey(cellKey)
123
- if (direction === 'right') {
124
- doDirectionRight(rowKey, columnKey, cellKey)
125
- } else if (direction === 'down') {
126
- doDirectionDown(rowKey, columnKey, cellKey)
127
- } else if (direction === 'left') {
128
- doDirectionLeft(rowKey, columnKey, cellKey)
129
- } else if (direction === 'up') {
130
- doDirectionUp(rowKey, columnKey, cellKey)
131
- }
132
- }, 50)
133
- window.addEventListener(
134
- `${KEYBOARD_DIRECTION}${id}`,
135
- (handleDirection as any) as EventListener
136
- )
137
-
138
- return () => {
139
- window.removeEventListener(
140
- `${KEYBOARD_DIRECTION}${id}`,
141
- (handleDirection as any) as EventListener
142
- )
143
- }
144
- }, [dataLength, columnKeys.join('')])
145
-
146
- // 处理 Enter,依赖 dataLength 的变动
147
- useEffect(() => {
148
- const handleEnter = throttle((event: CustomEvent<KeyboardCustomEvent>) => {
149
- window.clearTimeout(timer.current)
150
-
151
- const { cellKey } = event.detail
152
- const { rowKey, columnKey } = getKey(cellKey)
153
- const columnIndex = columnKeys.indexOf(columnKey)
154
-
155
- // 如果不是最后一列
156
- if (columnIndex < columnKeys.length - 1) {
157
- doFocusWithColumnRowKey(
158
- KeyboardActionsName.ENTER,
159
- rowKey,
160
- columnKeys[columnIndex + 1],
161
- cellKey
162
- )
163
- }
164
- // 最后一列
165
- else if (columnIndex === columnKeys.length - 1) {
166
- // 如果不是最后一行
167
- if (rowKey < dataLength - 1) {
168
- doFocusWithColumnRowKey(
169
- KeyboardActionsName.ENTER,
170
- rowKey + 1,
171
- columnKeys[0],
172
- cellKey
173
- )
174
- }
175
- // 最后一行
176
- else if (rowKey === dataLength - 1) {
177
- onAddRow()
178
- timer.current = window.setTimeout(() => {
179
- // 去到最后一行
180
- doFocusWithColumnRowKey(
181
- KeyboardActionsName.ENTER,
182
- rowKey + 1,
183
- columnKeys[0],
184
- cellKey
185
- )
186
- }, 10)
187
- }
188
- }
189
- }, 50)
190
- window.addEventListener(
191
- `${KEYBOARD_ENTER}${id}`,
192
- (handleEnter as any) as EventListener
193
- )
194
-
195
- return () => {
196
- window.removeEventListener(
197
- `${KEYBOARD_ENTER}${id}`,
198
- (handleEnter as any) as EventListener
199
- )
200
- }
201
- }, [dataLength, columnKeys.join('')])
202
-
203
- // 处理 Tab 键
204
- useEffect(() => {
205
- const handleTab = throttle((event: CustomEvent<KeyboardCustomEvent>) => {
206
- const { cellKey } = event.detail
207
- const { rowKey, columnKey } = getKey(cellKey)
208
- const columnIndex = columnKeys.indexOf(columnKey)
209
-
210
- // 如果不是最后一列
211
- if (columnIndex < columnKeys.length - 1) {
212
- doFocusWithColumnRowKey(
213
- KeyboardActionsName.TAB,
214
- rowKey + 1,
215
- columnKeys[0],
216
- cellKey
217
- )
218
- }
219
- // 最后一列
220
- else if (columnIndex === columnKeys.length - 1) {
221
- // 如果不是最后一行
222
- if (rowKey < dataLength - 1) {
223
- doFocusWithColumnRowKey(
224
- KeyboardActionsName.TAB,
225
- rowKey + 1,
226
- columnKeys[0],
227
- cellKey
228
- )
229
- }
230
- // 最后一行
231
- else if (rowKey === dataLength - 1) {
232
- doFocusWithColumnRowKey(KeyboardActionsName.TAB, 0, columnKeys[0], cellKey)
233
- }
234
- }
235
- }, 50)
236
-
237
- window.addEventListener(`${KEYBOARD_TAB}${id}`, (handleTab as any) as EventListener)
238
- return () => {
239
- window.removeEventListener(
240
- `${KEYBOARD_TAB}${id}`,
241
- (handleTab as any) as EventListener
242
- )
243
- }
244
- }, [dataLength, columnKeys.join('')])
245
-
246
- return (
247
- <WrapContext.Provider value={JSON.stringify({ id, fixedWidths })}>
248
- {children}
249
- </WrapContext.Provider>
250
- )
251
- }
252
-
253
- export default Wrap
1
+ import React, { FC, useEffect, useRef } from 'react'
2
+ import { throttle } from 'lodash'
3
+
4
+ import {
5
+ doFocus,
6
+ getKey,
7
+ KEYBOARD_DIRECTION,
8
+ KEYBOARD_ENTER,
9
+ KEYBOARD_TAB,
10
+ KeyboardActionsName,
11
+ WrapContext,
12
+ } from '../utils'
13
+ import { KeyboardCustomEvent, WrapProps } from '../types'
14
+
15
+ /**
16
+ * 包裹 Table,使 Table 具有键盘响应能力
17
+ *
18
+ * Wrap 负责调度,接收来自 Cell 的操作反馈,然后做出后续动作
19
+ * Cell 监听键盘事件,把 方向、Enter、Tab 反馈给 Wrap
20
+ * Wrap 做出动作,其中包括 focus 到 Cell
21
+ * */
22
+ const Wrap: FC<WrapProps> = ({
23
+ id,
24
+ children,
25
+ onAddRow,
26
+ allowAddRowOnDownKey = true,
27
+ columnKeys,
28
+ dataLength,
29
+ fixedWidths,
30
+ onBeforeDispatch,
31
+ }) => {
32
+ const timer = useRef<number | undefined>()
33
+
34
+ // 处理 focus
35
+ const doFocusWithColumnRowKey = (
36
+ actionName: string,
37
+ rowKey: number,
38
+ columnKey: string,
39
+ cellKey: string
40
+ ) => {
41
+ const result =
42
+ onBeforeDispatch &&
43
+ onBeforeDispatch({
44
+ actionName,
45
+ to: { rowKey, columnKey },
46
+ from: getKey(cellKey),
47
+ })
48
+
49
+ // 返回 false 组织默认行为
50
+ if (result === false) {
51
+ return
52
+ }
53
+
54
+ doFocus(id, rowKey, columnKey)
55
+ }
56
+
57
+ // 处理方向
58
+ const doDirectionRight = (rowKey: number, columnKey: string, cellKey: string) => {
59
+ const columnIndex = columnKeys.indexOf(columnKey)
60
+ // 如果不是最后一列
61
+ if (columnIndex < columnKeys.length - 1) {
62
+ doFocusWithColumnRowKey(
63
+ KeyboardActionsName.RIGHT,
64
+ rowKey,
65
+ columnKeys[columnIndex + 1],
66
+ cellKey
67
+ )
68
+ }
69
+ }
70
+ const doDirectionLeft = (rowKey: number, columnKey: string, cellKey: string) => {
71
+ const columnIndex = columnKeys.indexOf(columnKey)
72
+ // 如果不是第一列
73
+ if (columnIndex > 0) {
74
+ doFocusWithColumnRowKey(
75
+ KeyboardActionsName.LEFT,
76
+ rowKey,
77
+ columnKeys[columnIndex - 1],
78
+ cellKey
79
+ )
80
+ }
81
+ }
82
+ const doDirectionDown = (rowKey: number, columnKey: string, cellKey: string) => {
83
+ window.clearTimeout(timer.current)
84
+
85
+ // 往下一个
86
+ if (rowKey < dataLength - 1) {
87
+ doFocusWithColumnRowKey(KeyboardActionsName.DOWN, rowKey + 1, columnKey, cellKey)
88
+ }
89
+ // 最后一行
90
+ else if (rowKey === dataLength - 1) {
91
+ if (allowAddRowOnDownKey) {
92
+ onAddRow()
93
+ }
94
+ timer.current = window.setTimeout(() => {
95
+ // 去到第一列
96
+ doFocusWithColumnRowKey(
97
+ KeyboardActionsName.DOWN,
98
+ rowKey + 1,
99
+ columnKeys[0],
100
+ cellKey
101
+ )
102
+ const table = document.querySelector('.gm-table-x')
103
+ if (table) table.scrollLeft = 0
104
+ }, 10)
105
+ }
106
+ }
107
+ const doDirectionUp = (rowKey: number, columnKey: string, cellKey: string) => {
108
+ // 往上一个
109
+ if (rowKey > 0) {
110
+ doFocusWithColumnRowKey(KeyboardActionsName.UP, rowKey - 1, columnKey, cellKey)
111
+ }
112
+ // 循环到最后一个
113
+ else if (rowKey === 0) {
114
+ doFocusWithColumnRowKey(KeyboardActionsName.UP, dataLength - 1, columnKey, cellKey)
115
+ }
116
+ }
117
+
118
+ // 处理方向事件,依赖 dataLength 的变动
119
+ useEffect(() => {
120
+ const handleDirection = throttle((event: CustomEvent<KeyboardCustomEvent>) => {
121
+ const { cellKey, direction } = event.detail
122
+ const { rowKey, columnKey } = getKey(cellKey)
123
+ if (direction === 'right') {
124
+ doDirectionRight(rowKey, columnKey, cellKey)
125
+ } else if (direction === 'down') {
126
+ doDirectionDown(rowKey, columnKey, cellKey)
127
+ } else if (direction === 'left') {
128
+ doDirectionLeft(rowKey, columnKey, cellKey)
129
+ } else if (direction === 'up') {
130
+ doDirectionUp(rowKey, columnKey, cellKey)
131
+ }
132
+ }, 50)
133
+ window.addEventListener(
134
+ `${KEYBOARD_DIRECTION}${id}`,
135
+ (handleDirection as any) as EventListener
136
+ )
137
+
138
+ return () => {
139
+ window.removeEventListener(
140
+ `${KEYBOARD_DIRECTION}${id}`,
141
+ (handleDirection as any) as EventListener
142
+ )
143
+ }
144
+ }, [dataLength, columnKeys.join('')])
145
+
146
+ // 处理 Enter,依赖 dataLength 的变动
147
+ useEffect(() => {
148
+ const handleEnter = throttle((event: CustomEvent<KeyboardCustomEvent>) => {
149
+ window.clearTimeout(timer.current)
150
+
151
+ const { cellKey } = event.detail
152
+ const { rowKey, columnKey } = getKey(cellKey)
153
+ const columnIndex = columnKeys.indexOf(columnKey)
154
+
155
+ // 如果不是最后一列
156
+ if (columnIndex < columnKeys.length - 1) {
157
+ doFocusWithColumnRowKey(
158
+ KeyboardActionsName.ENTER,
159
+ rowKey,
160
+ columnKeys[columnIndex + 1],
161
+ cellKey
162
+ )
163
+ }
164
+ // 最后一列
165
+ else if (columnIndex === columnKeys.length - 1) {
166
+ // 如果不是最后一行
167
+ if (rowKey < dataLength - 1) {
168
+ doFocusWithColumnRowKey(
169
+ KeyboardActionsName.ENTER,
170
+ rowKey + 1,
171
+ columnKeys[0],
172
+ cellKey
173
+ )
174
+ }
175
+ // 最后一行
176
+ else if (rowKey === dataLength - 1) {
177
+ onAddRow()
178
+ timer.current = window.setTimeout(() => {
179
+ // 去到最后一行
180
+ doFocusWithColumnRowKey(
181
+ KeyboardActionsName.ENTER,
182
+ rowKey + 1,
183
+ columnKeys[0],
184
+ cellKey
185
+ )
186
+ }, 10)
187
+ }
188
+ }
189
+ }, 50)
190
+ window.addEventListener(
191
+ `${KEYBOARD_ENTER}${id}`,
192
+ (handleEnter as any) as EventListener
193
+ )
194
+
195
+ return () => {
196
+ window.removeEventListener(
197
+ `${KEYBOARD_ENTER}${id}`,
198
+ (handleEnter as any) as EventListener
199
+ )
200
+ }
201
+ }, [dataLength, columnKeys.join('')])
202
+
203
+ // 处理 Tab 键
204
+ useEffect(() => {
205
+ const handleTab = throttle((event: CustomEvent<KeyboardCustomEvent>) => {
206
+ const { cellKey } = event.detail
207
+ const { rowKey, columnKey } = getKey(cellKey)
208
+ const columnIndex = columnKeys.indexOf(columnKey)
209
+
210
+ // 如果不是最后一列
211
+ if (columnIndex < columnKeys.length - 1) {
212
+ doFocusWithColumnRowKey(
213
+ KeyboardActionsName.TAB,
214
+ rowKey + 1,
215
+ columnKeys[0],
216
+ cellKey
217
+ )
218
+ }
219
+ // 最后一列
220
+ else if (columnIndex === columnKeys.length - 1) {
221
+ // 如果不是最后一行
222
+ if (rowKey < dataLength - 1) {
223
+ doFocusWithColumnRowKey(
224
+ KeyboardActionsName.TAB,
225
+ rowKey + 1,
226
+ columnKeys[0],
227
+ cellKey
228
+ )
229
+ }
230
+ // 最后一行
231
+ else if (rowKey === dataLength - 1) {
232
+ doFocusWithColumnRowKey(KeyboardActionsName.TAB, 0, columnKeys[0], cellKey)
233
+ }
234
+ }
235
+ }, 50)
236
+
237
+ window.addEventListener(`${KEYBOARD_TAB}${id}`, (handleTab as any) as EventListener)
238
+ return () => {
239
+ window.removeEventListener(
240
+ `${KEYBOARD_TAB}${id}`,
241
+ (handleTab as any) as EventListener
242
+ )
243
+ }
244
+ }, [dataLength, columnKeys.join('')])
245
+
246
+ return (
247
+ <WrapContext.Provider value={JSON.stringify({ id, fixedWidths })}>
248
+ {children}
249
+ </WrapContext.Provider>
250
+ )
251
+ }
252
+
253
+ export default Wrap