@react-aria/utils 3.8.0 → 3.10.0
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/dist/main.js +173 -45
- package/dist/main.js.map +1 -1
- package/dist/module.js +163 -43
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +16 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/index.ts +3 -0
- package/src/mergeProps.ts +24 -27
- package/src/useDescription.ts +2 -1
- package/src/useEvent.ts +39 -0
- package/src/useGlobalListeners.ts +8 -2
- package/src/useId.ts +28 -13
- package/src/useObjectRef.ts +46 -0
- package/src/useSyncRef.ts +1 -1
- package/src/useValueEffect.ts +65 -0
- package/src/useViewportSize.ts +7 -1
package/dist/main.js
CHANGED
|
@@ -8,6 +8,8 @@ exports.clamp = clamp;
|
|
|
8
8
|
|
|
9
9
|
var _clsx = $parcel$interopDefault(require("clsx"));
|
|
10
10
|
|
|
11
|
+
var _babelRuntimeHelpersExtends = $parcel$interopDefault(require("@babel/runtime/helpers/extends"));
|
|
12
|
+
|
|
11
13
|
var {
|
|
12
14
|
useSSRSafeId
|
|
13
15
|
} = require("@react-aria/ssr");
|
|
@@ -17,11 +19,10 @@ var _react2 = require("react");
|
|
|
17
19
|
var _react = $parcel$interopDefault(_react2);
|
|
18
20
|
|
|
19
21
|
var {
|
|
22
|
+
useCallback,
|
|
20
23
|
useEffect,
|
|
21
24
|
useRef,
|
|
22
|
-
useState
|
|
23
|
-
useCallback,
|
|
24
|
-
useLayoutEffect: _useLayoutEffect
|
|
25
|
+
useState
|
|
25
26
|
} = _react2;
|
|
26
27
|
|
|
27
28
|
function $parcel$interopDefault(a) {
|
|
@@ -43,7 +44,8 @@ function useId(defaultId) {
|
|
|
43
44
|
let isRendering = useRef(true);
|
|
44
45
|
isRendering.current = true;
|
|
45
46
|
let [value, setValue] = useState(defaultId);
|
|
46
|
-
let nextId = useRef(null);
|
|
47
|
+
let nextId = useRef(null);
|
|
48
|
+
let res = useSSRSafeId(value); // don't memo this, we want it new each render so that the Effects always run
|
|
47
49
|
|
|
48
50
|
let updateValue = val => {
|
|
49
51
|
if (!isRendering.current) {
|
|
@@ -53,9 +55,16 @@ function useId(defaultId) {
|
|
|
53
55
|
}
|
|
54
56
|
};
|
|
55
57
|
|
|
58
|
+
$f09fcd7f5f367fc80aacfeac62ed2$var$idsUpdaterMap.set(res, updateValue);
|
|
56
59
|
useLayoutEffect(() => {
|
|
57
60
|
isRendering.current = false;
|
|
58
61
|
}, [updateValue]);
|
|
62
|
+
useLayoutEffect(() => {
|
|
63
|
+
let r = res;
|
|
64
|
+
return () => {
|
|
65
|
+
$f09fcd7f5f367fc80aacfeac62ed2$var$idsUpdaterMap.delete(r);
|
|
66
|
+
};
|
|
67
|
+
}, [res]);
|
|
59
68
|
useEffect(() => {
|
|
60
69
|
let newId = nextId.current;
|
|
61
70
|
|
|
@@ -64,8 +73,6 @@ function useId(defaultId) {
|
|
|
64
73
|
nextId.current = null;
|
|
65
74
|
}
|
|
66
75
|
}, [setValue, updateValue]);
|
|
67
|
-
let res = useSSRSafeId(value);
|
|
68
|
-
$f09fcd7f5f367fc80aacfeac62ed2$var$idsUpdaterMap.set(res, updateValue);
|
|
69
76
|
return res;
|
|
70
77
|
}
|
|
71
78
|
/**
|
|
@@ -100,21 +107,27 @@ function mergeIds(idA, idB) {
|
|
|
100
107
|
/**
|
|
101
108
|
* Used to generate an id, and after render, check if that id is rendered so we know
|
|
102
109
|
* if we can use it in places such as labelledby.
|
|
110
|
+
* @param depArray - When to recalculate if the id is in the DOM.
|
|
103
111
|
*/
|
|
104
112
|
|
|
105
113
|
|
|
106
114
|
exports.mergeIds = mergeIds;
|
|
107
115
|
|
|
108
|
-
function useSlotId() {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
116
|
+
function useSlotId(depArray) {
|
|
117
|
+
if (depArray === void 0) {
|
|
118
|
+
depArray = [];
|
|
119
|
+
}
|
|
112
120
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
121
|
+
let id = useId();
|
|
122
|
+
let [resolvedId, setResolvedId] = useValueEffect(id);
|
|
123
|
+
let updateId = useCallback(() => {
|
|
124
|
+
setResolvedId(function* () {
|
|
125
|
+
yield id;
|
|
126
|
+
yield document.getElementById(id) ? id : null;
|
|
127
|
+
});
|
|
128
|
+
}, [id, setResolvedId]);
|
|
129
|
+
useLayoutEffect(updateId, [id, updateId, ...depArray]);
|
|
130
|
+
return resolvedId;
|
|
118
131
|
}
|
|
119
132
|
|
|
120
133
|
exports.useSlotId = useSlotId;
|
|
@@ -158,32 +171,30 @@ exports.chain = chain;
|
|
|
158
171
|
* @param args - Multiple sets of props to merge together.
|
|
159
172
|
*/
|
|
160
173
|
function mergeProps() {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
args[_key] = arguments[_key];
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
for (let props of args) {
|
|
168
|
-
for (let key in result) {
|
|
169
|
-
// Chain events
|
|
170
|
-
if (/^on[A-Z]/.test(key) && typeof result[key] === 'function' && typeof props[key] === 'function') {
|
|
171
|
-
result[key] = chain(result[key], props[key]); // Merge classnames, sometimes classNames are empty string which eval to false, so we just need to do a type check
|
|
172
|
-
} else if (key === 'className' && typeof result.className === 'string' && typeof props.className === 'string') {
|
|
173
|
-
result[key] = _clsx(result.className, props.className);
|
|
174
|
-
} else if (key === 'UNSAFE_className' && typeof result.UNSAFE_className === 'string' && typeof props.UNSAFE_className === 'string') {
|
|
175
|
-
result[key] = _clsx(result.UNSAFE_className, props.UNSAFE_className);
|
|
176
|
-
} else if (key === 'id' && result.id && props.id) {
|
|
177
|
-
result.id = mergeIds(result.id, props.id); // Override others
|
|
178
|
-
} else {
|
|
179
|
-
result[key] = props[key] !== undefined ? props[key] : result[key];
|
|
180
|
-
}
|
|
181
|
-
} // Add props from b that are not in a
|
|
174
|
+
// Start with a base clone of the first argument. This is a lot faster than starting
|
|
175
|
+
// with an empty object and adding properties as we go.
|
|
176
|
+
let result = _babelRuntimeHelpersExtends({}, arguments.length <= 0 ? undefined : arguments[0]);
|
|
182
177
|
|
|
178
|
+
for (let i = 1; i < arguments.length; i++) {
|
|
179
|
+
let props = i < 0 || arguments.length <= i ? undefined : arguments[i];
|
|
183
180
|
|
|
184
181
|
for (let key in props) {
|
|
185
|
-
|
|
186
|
-
|
|
182
|
+
let a = result[key];
|
|
183
|
+
let b = props[key]; // Chain events
|
|
184
|
+
|
|
185
|
+
if (typeof a === 'function' && typeof b === 'function' && // This is a lot faster than a regex.
|
|
186
|
+
key[0] === 'o' && key[1] === 'n' && key.charCodeAt(2) >=
|
|
187
|
+
/* 'A' */
|
|
188
|
+
65 && key.charCodeAt(2) <=
|
|
189
|
+
/* 'Z' */
|
|
190
|
+
90) {
|
|
191
|
+
result[key] = chain(a, b); // Merge classnames, sometimes classNames are empty string which eval to false, so we just need to do a type check
|
|
192
|
+
} else if ((key === 'className' || key === 'UNSAFE_className') && typeof a === 'string' && typeof b === 'string') {
|
|
193
|
+
result[key] = _clsx(a, b);
|
|
194
|
+
} else if (key === 'id' && a && b) {
|
|
195
|
+
result.id = mergeIds(a, b); // Override others
|
|
196
|
+
} else {
|
|
197
|
+
result[key] = b !== undefined ? b : a;
|
|
187
198
|
}
|
|
188
199
|
}
|
|
189
200
|
}
|
|
@@ -213,7 +224,7 @@ function filterDOMProps(props, opts) {
|
|
|
213
224
|
let filteredProps = {};
|
|
214
225
|
|
|
215
226
|
for (const prop in props) {
|
|
216
|
-
if (Object.prototype.hasOwnProperty.call(props, prop) && ($a736ffc3e05a0bfc1508098ba395b41$var$DOMPropNames.has(prop) || labelable && $a736ffc3e05a0bfc1508098ba395b41$var$labelablePropNames.has(prop) ||
|
|
227
|
+
if (Object.prototype.hasOwnProperty.call(props, prop) && ($a736ffc3e05a0bfc1508098ba395b41$var$DOMPropNames.has(prop) || labelable && $a736ffc3e05a0bfc1508098ba395b41$var$labelablePropNames.has(prop) || propNames != null && propNames.has(prop) || $a736ffc3e05a0bfc1508098ba395b41$var$propRe.test(prop))) {
|
|
217
228
|
filteredProps[prop] = props[prop];
|
|
218
229
|
}
|
|
219
230
|
}
|
|
@@ -613,15 +624,24 @@ exports.useDrag1D = useDrag1D;
|
|
|
613
624
|
function useGlobalListeners() {
|
|
614
625
|
let globalListeners = useRef(new Map());
|
|
615
626
|
let addGlobalListener = useCallback((eventTarget, type, listener, options) => {
|
|
627
|
+
// Make sure we remove the listener after it is called with the `once` option.
|
|
628
|
+
let fn = options != null && options.once ? function () {
|
|
629
|
+
globalListeners.current.delete(listener);
|
|
630
|
+
listener(...arguments);
|
|
631
|
+
} : listener;
|
|
616
632
|
globalListeners.current.set(listener, {
|
|
617
633
|
type,
|
|
618
634
|
eventTarget,
|
|
635
|
+
fn,
|
|
619
636
|
options
|
|
620
637
|
});
|
|
621
638
|
eventTarget.addEventListener(type, listener, options);
|
|
622
639
|
}, []);
|
|
623
640
|
let removeGlobalListener = useCallback((eventTarget, type, listener, options) => {
|
|
624
|
-
|
|
641
|
+
var _globalListeners$curr;
|
|
642
|
+
|
|
643
|
+
let fn = ((_globalListeners$curr = globalListeners.current.get(listener)) == null ? void 0 : _globalListeners$curr.fn) || listener;
|
|
644
|
+
eventTarget.removeEventListener(type, fn, options);
|
|
625
645
|
globalListeners.current.delete(listener);
|
|
626
646
|
}, []);
|
|
627
647
|
let removeAllGlobalListeners = useCallback(() => {
|
|
@@ -678,6 +698,39 @@ function useLabels(props, defaultLabel) {
|
|
|
678
698
|
|
|
679
699
|
exports.useLabels = useLabels;
|
|
680
700
|
|
|
701
|
+
/**
|
|
702
|
+
* Offers an object ref for a given callback ref or an object ref. Especially
|
|
703
|
+
* helfpul when passing forwarded refs (created using `React.forwardRef`) to
|
|
704
|
+
* React Aria Hooks.
|
|
705
|
+
*
|
|
706
|
+
* @param forwardedRef The original ref intended to be used.
|
|
707
|
+
* @returns An object ref that updates the given ref.
|
|
708
|
+
* @see https://reactjs.org/docs/forwarding-refs.html
|
|
709
|
+
*/
|
|
710
|
+
function useObjectRef(forwardedRef) {
|
|
711
|
+
const objRef = useRef();
|
|
712
|
+
/**
|
|
713
|
+
* We're using `useLayoutEffect` here instead of `useEffect` because we want
|
|
714
|
+
* to make sure that the `ref` value is up to date before other places in the
|
|
715
|
+
* the execution cycle try to read it.
|
|
716
|
+
*/
|
|
717
|
+
|
|
718
|
+
useLayoutEffect(() => {
|
|
719
|
+
if (!forwardedRef) {
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
if (typeof forwardedRef === 'function') {
|
|
724
|
+
forwardedRef(objRef.current);
|
|
725
|
+
} else {
|
|
726
|
+
forwardedRef.current = objRef.current;
|
|
727
|
+
}
|
|
728
|
+
}, [forwardedRef]);
|
|
729
|
+
return objRef;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
exports.useObjectRef = useObjectRef;
|
|
733
|
+
|
|
681
734
|
// Like useEffect, but only called for updates after the initial render.
|
|
682
735
|
function useUpdateEffect(effect, dependencies) {
|
|
683
736
|
const isInitialMount = useRef(true);
|
|
@@ -737,7 +790,7 @@ exports.useResizeObserver = useResizeObserver;
|
|
|
737
790
|
// Syncs ref from context with ref passed to hook
|
|
738
791
|
function useSyncRef(context, ref) {
|
|
739
792
|
useLayoutEffect(() => {
|
|
740
|
-
if (context && context.ref) {
|
|
793
|
+
if (context && context.ref && ref) {
|
|
741
794
|
context.ref.current = ref.current;
|
|
742
795
|
return () => {
|
|
743
796
|
context.ref.current = null;
|
|
@@ -771,7 +824,15 @@ function useViewportSize() {
|
|
|
771
824
|
useEffect(() => {
|
|
772
825
|
// Use visualViewport api to track available height even on iOS virtual keyboard opening
|
|
773
826
|
let onResize = () => {
|
|
774
|
-
setSize(
|
|
827
|
+
setSize(size => {
|
|
828
|
+
let newSize = $f1a92c0e19f2e1ad09851454bf93009$var$getViewportSize();
|
|
829
|
+
|
|
830
|
+
if (newSize.width === size.width && newSize.height === size.height) {
|
|
831
|
+
return size;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
return newSize;
|
|
835
|
+
});
|
|
775
836
|
};
|
|
776
837
|
|
|
777
838
|
if (!$f1a92c0e19f2e1ad09851454bf93009$var$visualViewport) {
|
|
@@ -805,8 +866,7 @@ const $bd5928122fc632cc7302c36df9f$var$descriptionNodes = new Map();
|
|
|
805
866
|
|
|
806
867
|
function useDescription(description) {
|
|
807
868
|
let [id, setId] = useState(null);
|
|
808
|
-
|
|
809
|
-
_useLayoutEffect(() => {
|
|
869
|
+
useLayoutEffect(() => {
|
|
810
870
|
if (!description) {
|
|
811
871
|
return;
|
|
812
872
|
}
|
|
@@ -838,7 +898,6 @@ function useDescription(description) {
|
|
|
838
898
|
}
|
|
839
899
|
};
|
|
840
900
|
}, [description]);
|
|
841
|
-
|
|
842
901
|
return {
|
|
843
902
|
'aria-describedby': description ? id : undefined
|
|
844
903
|
};
|
|
@@ -902,4 +961,73 @@ function isAndroid() {
|
|
|
902
961
|
}
|
|
903
962
|
|
|
904
963
|
exports.isAndroid = isAndroid;
|
|
964
|
+
|
|
965
|
+
function useEvent(ref, event, handler, options) {
|
|
966
|
+
let handlerRef = useRef(handler);
|
|
967
|
+
handlerRef.current = handler;
|
|
968
|
+
let isDisabled = handler == null;
|
|
969
|
+
useEffect(() => {
|
|
970
|
+
if (isDisabled) {
|
|
971
|
+
return;
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
let element = ref.current;
|
|
975
|
+
|
|
976
|
+
let handler = e => handlerRef.current.call(this, e);
|
|
977
|
+
|
|
978
|
+
element.addEventListener(event, handler, options);
|
|
979
|
+
return () => {
|
|
980
|
+
element.removeEventListener(event, handler, options);
|
|
981
|
+
};
|
|
982
|
+
}, [ref, event, options, isDisabled]);
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
exports.useEvent = useEvent;
|
|
986
|
+
|
|
987
|
+
// This hook works like `useState`, but when setting the value, you pass a generator function
|
|
988
|
+
// that can yield multiple values. Each yielded value updates the state and waits for the next
|
|
989
|
+
// layout effect, then continues the generator. This allows sequential updates to state to be
|
|
990
|
+
// written linearly.
|
|
991
|
+
function useValueEffect(defaultValue) {
|
|
992
|
+
let [value, setValue] = useState(defaultValue);
|
|
993
|
+
let valueRef = useRef(value);
|
|
994
|
+
let effect = useRef(null);
|
|
995
|
+
valueRef.current = value; // Store the function in a ref so we can always access the current version
|
|
996
|
+
// which has the proper `value` in scope.
|
|
997
|
+
|
|
998
|
+
let nextRef = useRef(null);
|
|
999
|
+
|
|
1000
|
+
nextRef.current = () => {
|
|
1001
|
+
// Run the generator to the next yield.
|
|
1002
|
+
let newValue = effect.current.next(); // If the generator is done, reset the effect.
|
|
1003
|
+
|
|
1004
|
+
if (newValue.done) {
|
|
1005
|
+
effect.current = null;
|
|
1006
|
+
return;
|
|
1007
|
+
} // If the value is the same as the current value,
|
|
1008
|
+
// then continue to the next yield. Otherwise,
|
|
1009
|
+
// set the value in state and wait for the next layout effect.
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
if (value === newValue.value) {
|
|
1013
|
+
nextRef.current();
|
|
1014
|
+
} else {
|
|
1015
|
+
setValue(newValue.value);
|
|
1016
|
+
}
|
|
1017
|
+
};
|
|
1018
|
+
|
|
1019
|
+
useLayoutEffect(() => {
|
|
1020
|
+
// If there is an effect currently running, continue to the next yield.
|
|
1021
|
+
if (effect.current) {
|
|
1022
|
+
nextRef.current();
|
|
1023
|
+
}
|
|
1024
|
+
});
|
|
1025
|
+
let queue = useCallback(fn => {
|
|
1026
|
+
effect.current = fn(valueRef.current);
|
|
1027
|
+
nextRef.current();
|
|
1028
|
+
}, [effect, nextRef]);
|
|
1029
|
+
return [value, queue];
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
exports.useValueEffect = useValueEffect;
|
|
905
1033
|
//# sourceMappingURL=main.js.map
|