@rc-component/util 1.10.0 → 1.10.1
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/es/Dom/focus.js +37 -8
- package/lib/Dom/focus.js +36 -7
- package/package.json +1 -1
package/es/Dom/focus.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
1
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
2
|
import isVisible from "./isVisible";
|
|
3
3
|
import useId from "../hooks/useId";
|
|
4
4
|
function focusable(node, includePositive = false) {
|
|
@@ -173,6 +173,30 @@ export function lockFocus(element, id) {
|
|
|
173
173
|
};
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
+
/**
|
|
177
|
+
* Retry an effect until it reports ready.
|
|
178
|
+
* When `ready` is `false`, it will schedule one more effect cycle and call `func` again
|
|
179
|
+
* with the next `retryTimes`.
|
|
180
|
+
*/
|
|
181
|
+
|
|
182
|
+
function useRetryEffect(func, deps) {
|
|
183
|
+
/* eslint-disable react-hooks/exhaustive-deps */
|
|
184
|
+
const retryTimesRef = useRef(0);
|
|
185
|
+
const [retryMark, setRetryMark] = useState(0);
|
|
186
|
+
useEffect(() => {
|
|
187
|
+
retryTimesRef.current = 0;
|
|
188
|
+
}, deps);
|
|
189
|
+
useEffect(() => {
|
|
190
|
+
const [clearFn, ready] = func(retryTimesRef.current);
|
|
191
|
+
if (!ready) {
|
|
192
|
+
retryTimesRef.current += 1;
|
|
193
|
+
setRetryMark(count => count + 1);
|
|
194
|
+
}
|
|
195
|
+
return clearFn;
|
|
196
|
+
}, [...deps, retryMark]);
|
|
197
|
+
/* eslint-enable react-hooks/exhaustive-deps */
|
|
198
|
+
}
|
|
199
|
+
|
|
176
200
|
/**
|
|
177
201
|
* Lock focus within an element.
|
|
178
202
|
* When locked, focus will be restricted to focusable elements within the specified element.
|
|
@@ -181,14 +205,19 @@ export function lockFocus(element, id) {
|
|
|
181
205
|
*/
|
|
182
206
|
export function useLockFocus(lock, getElement) {
|
|
183
207
|
const id = useId();
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
208
|
+
const getElementRef = useRef(getElement);
|
|
209
|
+
getElementRef.current = getElement;
|
|
210
|
+
const lockEffect = retryTimes => {
|
|
211
|
+
if (!lock) {
|
|
212
|
+
return [undefined, true];
|
|
213
|
+
}
|
|
214
|
+
const element = getElementRef.current();
|
|
215
|
+
if (element) {
|
|
216
|
+
return [lockFocus(element, id), true];
|
|
190
217
|
}
|
|
191
|
-
|
|
218
|
+
return [undefined, retryTimes >= 1];
|
|
219
|
+
};
|
|
220
|
+
useRetryEffect(lockEffect, [id, lock]);
|
|
192
221
|
const ignoreElement = ele => {
|
|
193
222
|
if (ele) {
|
|
194
223
|
// Set the ignored element using stable ID
|
package/lib/Dom/focus.js
CHANGED
|
@@ -183,6 +183,30 @@ function lockFocus(element, id) {
|
|
|
183
183
|
};
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
/**
|
|
187
|
+
* Retry an effect until it reports ready.
|
|
188
|
+
* When `ready` is `false`, it will schedule one more effect cycle and call `func` again
|
|
189
|
+
* with the next `retryTimes`.
|
|
190
|
+
*/
|
|
191
|
+
|
|
192
|
+
function useRetryEffect(func, deps) {
|
|
193
|
+
/* eslint-disable react-hooks/exhaustive-deps */
|
|
194
|
+
const retryTimesRef = (0, _react.useRef)(0);
|
|
195
|
+
const [retryMark, setRetryMark] = (0, _react.useState)(0);
|
|
196
|
+
(0, _react.useEffect)(() => {
|
|
197
|
+
retryTimesRef.current = 0;
|
|
198
|
+
}, deps);
|
|
199
|
+
(0, _react.useEffect)(() => {
|
|
200
|
+
const [clearFn, ready] = func(retryTimesRef.current);
|
|
201
|
+
if (!ready) {
|
|
202
|
+
retryTimesRef.current += 1;
|
|
203
|
+
setRetryMark(count => count + 1);
|
|
204
|
+
}
|
|
205
|
+
return clearFn;
|
|
206
|
+
}, [...deps, retryMark]);
|
|
207
|
+
/* eslint-enable react-hooks/exhaustive-deps */
|
|
208
|
+
}
|
|
209
|
+
|
|
186
210
|
/**
|
|
187
211
|
* Lock focus within an element.
|
|
188
212
|
* When locked, focus will be restricted to focusable elements within the specified element.
|
|
@@ -191,14 +215,19 @@ function lockFocus(element, id) {
|
|
|
191
215
|
*/
|
|
192
216
|
function useLockFocus(lock, getElement) {
|
|
193
217
|
const id = (0, _useId.default)();
|
|
194
|
-
(0, _react.
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
218
|
+
const getElementRef = (0, _react.useRef)(getElement);
|
|
219
|
+
getElementRef.current = getElement;
|
|
220
|
+
const lockEffect = retryTimes => {
|
|
221
|
+
if (!lock) {
|
|
222
|
+
return [undefined, true];
|
|
223
|
+
}
|
|
224
|
+
const element = getElementRef.current();
|
|
225
|
+
if (element) {
|
|
226
|
+
return [lockFocus(element, id), true];
|
|
200
227
|
}
|
|
201
|
-
|
|
228
|
+
return [undefined, retryTimes >= 1];
|
|
229
|
+
};
|
|
230
|
+
useRetryEffect(lockEffect, [id, lock]);
|
|
202
231
|
const ignoreElement = ele => {
|
|
203
232
|
if (ele) {
|
|
204
233
|
// Set the ignored element using stable ID
|