@wordpress/compose 8.0.0 → 8.1.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.
Files changed (63) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +5 -5
  3. package/build/higher-order/pure/index.cjs +15 -0
  4. package/build/higher-order/pure/index.cjs.map +3 -3
  5. package/build/hooks/use-disabled/index.cjs +2 -2
  6. package/build/hooks/use-disabled/index.cjs.map +2 -2
  7. package/build/hooks/use-focus-return/index.cjs.map +1 -1
  8. package/build/hooks/use-media-query/index.cjs +2 -2
  9. package/build/hooks/use-media-query/index.cjs.map +2 -2
  10. package/build/hooks/use-merge-refs/index.cjs +28 -8
  11. package/build/hooks/use-merge-refs/index.cjs.map +2 -2
  12. package/build/hooks/use-resize-observer/use-resize-observer.cjs.map +2 -2
  13. package/build/hooks/use-viewport-match/index.cjs +1 -1
  14. package/build/hooks/use-viewport-match/index.cjs.map +2 -2
  15. package/build-module/higher-order/pure/index.mjs +5 -0
  16. package/build-module/higher-order/pure/index.mjs.map +2 -2
  17. package/build-module/hooks/use-disabled/index.mjs +2 -2
  18. package/build-module/hooks/use-disabled/index.mjs.map +2 -2
  19. package/build-module/hooks/use-focus-return/index.mjs.map +1 -1
  20. package/build-module/hooks/use-media-query/index.mjs +2 -2
  21. package/build-module/hooks/use-media-query/index.mjs.map +2 -2
  22. package/build-module/hooks/use-merge-refs/index.mjs +28 -8
  23. package/build-module/hooks/use-merge-refs/index.mjs.map +2 -2
  24. package/build-module/hooks/use-resize-observer/use-resize-observer.mjs.map +2 -2
  25. package/build-module/hooks/use-viewport-match/index.mjs +1 -1
  26. package/build-module/hooks/use-viewport-match/index.mjs.map +2 -2
  27. package/build-types/higher-order/pure/index.d.ts.map +1 -1
  28. package/build-types/higher-order/with-safe-timeout/index.d.ts +3 -1
  29. package/build-types/higher-order/with-safe-timeout/index.d.ts.map +1 -1
  30. package/build-types/hooks/use-media-query/index.d.ts +1 -1
  31. package/build-types/hooks/use-media-query/index.d.ts.map +1 -1
  32. package/build-types/hooks/use-merge-refs/index.d.ts +7 -5
  33. package/build-types/hooks/use-merge-refs/index.d.ts.map +1 -1
  34. package/build-types/hooks/use-viewport-match/index.d.ts +1 -1
  35. package/build-types/hooks/use-viewport-match/index.d.ts.map +1 -1
  36. package/package.json +17 -13
  37. package/src/higher-order/pure/index.tsx +6 -0
  38. package/src/higher-order/pure/test/index.js +14 -81
  39. package/src/hooks/use-disabled/index.ts +3 -3
  40. package/src/hooks/use-disabled/test/index.js +4 -4
  41. package/src/hooks/use-drop-zone/README.md +1 -1
  42. package/src/hooks/use-focus-return/index.js +2 -2
  43. package/src/hooks/use-media-query/index.ts +10 -3
  44. package/src/hooks/use-media-query/test/ssr.js +47 -0
  45. package/src/hooks/use-merge-refs/index.ts +51 -20
  46. package/src/hooks/use-merge-refs/test/index.js +288 -0
  47. package/src/hooks/use-resize-observer/use-resize-observer.ts +1 -1
  48. package/src/hooks/use-viewport-match/index.js +8 -2
  49. package/src/higher-order/with-network-connectivity/README.md +0 -20
  50. package/src/higher-order/with-network-connectivity/index.native.js +0 -19
  51. package/src/higher-order/with-preferred-color-scheme/index.native.js +0 -40
  52. package/src/hooks/use-constrained-tabbing/index.native.js +0 -14
  53. package/src/hooks/use-focus-outside/index.native.js +0 -170
  54. package/src/hooks/use-keyboard-shortcut/index.native.js +0 -2
  55. package/src/hooks/use-network-connectivity/index.native.js +0 -59
  56. package/src/hooks/use-network-connectivity/test/index.native.js +0 -87
  57. package/src/hooks/use-preferred-color-scheme/index.android.js +0 -30
  58. package/src/hooks/use-preferred-color-scheme/index.ios.js +0 -13
  59. package/src/hooks/use-preferred-color-scheme-style/index.native.js +0 -33
  60. package/src/hooks/use-resize-observer/index.native.js +0 -1
  61. package/src/hooks/use-resize-observer/legacy/index.native.js +0 -59
  62. package/src/hooks/use-resize-observer/legacy/test/index.native.js +0 -46
  63. package/src/index.native.js +0 -44
@@ -2,25 +2,40 @@
2
2
  import { useRef, useCallback, useLayoutEffect } from "@wordpress/element";
3
3
  function assignRef(ref, value) {
4
4
  if (typeof ref === "function") {
5
- ref(value);
5
+ const returned = ref(value);
6
+ return typeof returned === "function" ? returned : void 0;
6
7
  } else if (ref && ref.hasOwnProperty("current")) {
7
8
  ref.current = value;
8
9
  }
10
+ return void 0;
11
+ }
12
+ function detachRef(ref, index, cleanups) {
13
+ const cleanup = cleanups[index];
14
+ if (cleanup) {
15
+ cleanups[index] = void 0;
16
+ cleanup();
17
+ } else {
18
+ assignRef(ref, null);
19
+ }
9
20
  }
10
21
  function useMergeRefs(refs) {
11
- const element = useRef(null);
22
+ const elementRef = useRef(null);
12
23
  const isAttachedRef = useRef(false);
13
24
  const didElementChangeRef = useRef(false);
14
25
  const previousRefsRef = useRef([]);
15
26
  const currentRefsRef = useRef(refs);
27
+ const cleanupsRef = useRef([]);
16
28
  currentRefsRef.current = refs;
17
29
  useLayoutEffect(() => {
18
30
  if (didElementChangeRef.current === false && isAttachedRef.current === true) {
19
31
  refs.forEach((ref, index) => {
20
32
  const previousRef = previousRefsRef.current[index];
21
33
  if (ref !== previousRef) {
22
- assignRef(previousRef, null);
23
- assignRef(ref, element.current);
34
+ detachRef(previousRef, index, cleanupsRef.current);
35
+ cleanupsRef.current[index] = assignRef(
36
+ ref,
37
+ elementRef.current
38
+ );
24
39
  }
25
40
  });
26
41
  }
@@ -30,12 +45,17 @@ function useMergeRefs(refs) {
30
45
  didElementChangeRef.current = false;
31
46
  });
32
47
  return useCallback((value) => {
33
- assignRef(element, value);
48
+ elementRef.current = value;
34
49
  didElementChangeRef.current = true;
35
50
  isAttachedRef.current = value !== null;
36
- const refsToAssign = value ? currentRefsRef.current : previousRefsRef.current;
37
- for (const ref of refsToAssign) {
38
- assignRef(ref, value);
51
+ if (value === null) {
52
+ previousRefsRef.current.forEach((ref, index) => {
53
+ detachRef(ref, index, cleanupsRef.current);
54
+ });
55
+ } else {
56
+ currentRefsRef.current.forEach((ref, index) => {
57
+ cleanupsRef.current[index] = assignRef(ref, value);
58
+ });
39
59
  }
40
60
  }, []);
41
61
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/hooks/use-merge-refs/index.ts"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useRef, useCallback, useLayoutEffect } from '@wordpress/element';\nimport type { Ref, RefCallback } from 'react';\n\nfunction assignRef< T >( ref: Ref< T >, value: T ) {\n\tif ( typeof ref === 'function' ) {\n\t\tref( value );\n\t} else if ( ref && ref.hasOwnProperty( 'current' ) ) {\n\t\tref.current = value;\n\t}\n}\n\n/**\n * Merges refs into one ref callback.\n *\n * It also ensures that the merged ref callbacks are only called when they\n * change (as a result of a `useCallback` dependency update) OR when the ref\n * value changes, just as React does when passing a single ref callback to the\n * component.\n *\n * As expected, if you pass a new function on every render, the ref callback\n * will be called after every render.\n *\n * If you don't wish a ref callback to be called after every render, wrap it\n * with `useCallback( callback, dependencies )`. When a dependency changes, the\n * old ref callback will be called with `null` and the new ref callback will be\n * called with the same value.\n *\n * To make ref callbacks easier to use, you can also pass the result of\n * `useRefEffect`, which makes cleanup easier by allowing you to return a\n * cleanup function instead of handling `null`.\n *\n * It's also possible to _disable_ a ref (and its behaviour) by simply not\n * passing the ref.\n *\n * ```jsx\n * const ref = useRefEffect( ( node ) => {\n * node.addEventListener( ... );\n * return () => {\n * node.removeEventListener( ... );\n * };\n * }, [ ...dependencies ] );\n * const otherRef = useRef();\n * const mergedRefs useMergeRefs( [\n * enabled && ref,\n * otherRef,\n * ] );\n * return <div ref={ mergedRefs } />;\n * ```\n *\n * @param refs The refs to be merged.\n * @return The merged ref callback.\n */\nexport default function useMergeRefs< T >(\n\trefs: Ref< T >[]\n): RefCallback< T > {\n\tconst element = useRef( null );\n\tconst isAttachedRef = useRef( false );\n\tconst didElementChangeRef = useRef( false );\n\tconst previousRefsRef = useRef< Ref< T >[] >( [] );\n\tconst currentRefsRef = useRef( refs );\n\n\t// Update on render before the ref callback is called, so the ref callback\n\t// always has access to the current refs.\n\tcurrentRefsRef.current = refs;\n\n\t// If any of the refs change, call the previous ref with `null` and the new\n\t// ref with the node, except when the element changes in the same cycle, in\n\t// which case the ref callbacks will already have been called.\n\tuseLayoutEffect( () => {\n\t\tif (\n\t\t\tdidElementChangeRef.current === false &&\n\t\t\tisAttachedRef.current === true\n\t\t) {\n\t\t\trefs.forEach( ( ref, index ) => {\n\t\t\t\tconst previousRef = previousRefsRef.current[ index ];\n\t\t\t\tif ( ref !== previousRef ) {\n\t\t\t\t\tassignRef( previousRef, null );\n\t\t\t\t\tassignRef( ref, element.current );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\tpreviousRefsRef.current = refs;\n\t}, refs );\n\n\t// No dependencies, must be reset after every render so ref callbacks are\n\t// correctly called after a ref change.\n\tuseLayoutEffect( () => {\n\t\tdidElementChangeRef.current = false;\n\t} );\n\n\t// There should be no dependencies so that `callback` is only called when\n\t// the node changes.\n\treturn useCallback( ( value: T | null ) => {\n\t\t// Update the element so it can be used when calling ref callbacks on a\n\t\t// dependency change.\n\t\tassignRef( element, value );\n\n\t\tdidElementChangeRef.current = true;\n\t\tisAttachedRef.current = value !== null;\n\n\t\t// When an element changes, the current ref callback should be called\n\t\t// with the new element and the previous one with `null`.\n\t\tconst refsToAssign = value\n\t\t\t? currentRefsRef.current\n\t\t\t: previousRefsRef.current;\n\n\t\t// Update the latest refs.\n\t\tfor ( const ref of refsToAssign ) {\n\t\t\tassignRef( ref, value );\n\t\t}\n\t}, [] );\n}\n"],
5
- "mappings": ";AAGA,SAAS,QAAQ,aAAa,uBAAuB;AAGrD,SAAS,UAAgB,KAAe,OAAW;AAClD,MAAK,OAAO,QAAQ,YAAa;AAChC,QAAK,KAAM;AAAA,EACZ,WAAY,OAAO,IAAI,eAAgB,SAAU,GAAI;AACpD,QAAI,UAAU;AAAA,EACf;AACD;AA2Ce,SAAR,aACN,MACmB;AACnB,QAAM,UAAU,OAAQ,IAAK;AAC7B,QAAM,gBAAgB,OAAQ,KAAM;AACpC,QAAM,sBAAsB,OAAQ,KAAM;AAC1C,QAAM,kBAAkB,OAAsB,CAAC,CAAE;AACjD,QAAM,iBAAiB,OAAQ,IAAK;AAIpC,iBAAe,UAAU;AAKzB,kBAAiB,MAAM;AACtB,QACC,oBAAoB,YAAY,SAChC,cAAc,YAAY,MACzB;AACD,WAAK,QAAS,CAAE,KAAK,UAAW;AAC/B,cAAM,cAAc,gBAAgB,QAAS,KAAM;AACnD,YAAK,QAAQ,aAAc;AAC1B,oBAAW,aAAa,IAAK;AAC7B,oBAAW,KAAK,QAAQ,OAAQ;AAAA,QACjC;AAAA,MACD,CAAE;AAAA,IACH;AAEA,oBAAgB,UAAU;AAAA,EAC3B,GAAG,IAAK;AAIR,kBAAiB,MAAM;AACtB,wBAAoB,UAAU;AAAA,EAC/B,CAAE;AAIF,SAAO,YAAa,CAAE,UAAqB;AAG1C,cAAW,SAAS,KAAM;AAE1B,wBAAoB,UAAU;AAC9B,kBAAc,UAAU,UAAU;AAIlC,UAAM,eAAe,QAClB,eAAe,UACf,gBAAgB;AAGnB,eAAY,OAAO,cAAe;AACjC,gBAAW,KAAK,KAAM;AAAA,IACvB;AAAA,EACD,GAAG,CAAC,CAAE;AACP;",
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useRef, useCallback, useLayoutEffect } from '@wordpress/element';\nimport type { MutableRefObject, Ref, RefCallback } from 'react';\n\n// Returns a cleanup function if the ref callback returned one (React 19 ref\n// callback cleanup pattern), otherwise `undefined`. Object refs never have a\n// cleanup and only set `.current`.\nfunction assignRef< T >( ref: Ref< T >, value: T ): ( () => void ) | undefined {\n\tif ( typeof ref === 'function' ) {\n\t\tconst returned = ref( value );\n\t\treturn typeof returned === 'function' ? returned : undefined;\n\t} else if ( ref && ref.hasOwnProperty( 'current' ) ) {\n\t\t( ref as MutableRefObject< T > ).current = value;\n\t}\n\treturn undefined;\n}\n\n// Tear down a ref at the given index: prefer the stored cleanup; otherwise\n// fall back to calling the ref with `null`.\nfunction detachRef< T >(\n\tref: Ref< T >,\n\tindex: number,\n\tcleanups: Array< ( () => void ) | undefined >\n): void {\n\tconst cleanup = cleanups[ index ];\n\tif ( cleanup ) {\n\t\tcleanups[ index ] = undefined;\n\t\tcleanup();\n\t} else {\n\t\tassignRef( ref, null );\n\t}\n}\n\n/**\n * Merges refs into one ref callback.\n *\n * It also ensures that the merged ref callbacks are only called when they\n * change (as a result of a `useCallback` dependency update) OR when the ref\n * value changes, just as React does when passing a single ref callback to the\n * component.\n *\n * As expected, if you pass a new function on every render, the ref callback\n * will be called after every render.\n *\n * If you don't wish a ref callback to be called after every render, wrap it\n * with `useCallback( callback, dependencies )`. When a dependency changes, the\n * old ref callback will be called with `null` and the new ref callback will be\n * called with the same value.\n *\n * Inner ref callbacks may return a cleanup function (React 19's ref callback\n * cleanup pattern). When a ref callback returns a function, that function is\n * invoked at teardown (node change, dependency change, or unmount) **instead\n * of** the callback being called with `null`. Callbacks that do not return a\n * cleanup continue to receive `null` on teardown as before.\n *\n * It's also possible to _disable_ a ref (and its behaviour) by simply not\n * passing the ref.\n *\n * ```jsx\n * const ref = useCallback( ( node ) => {\n * node.addEventListener( ... );\n * return () => {\n * node.removeEventListener( ... );\n * };\n * }, [ ...dependencies ] );\n * const otherRef = useRef();\n * const mergedRefs = useMergeRefs( [\n * enabled && ref,\n * otherRef,\n * ] );\n * return <div ref={ mergedRefs } />;\n * ```\n *\n * @param refs The refs to be merged.\n * @return The merged ref callback.\n */\nexport default function useMergeRefs< T >(\n\trefs: Ref< T >[]\n): RefCallback< T > {\n\tconst elementRef = useRef< T | null >( null );\n\tconst isAttachedRef = useRef( false );\n\tconst didElementChangeRef = useRef( false );\n\tconst previousRefsRef = useRef< Ref< T >[] >( [] );\n\tconst currentRefsRef = useRef( refs );\n\t// Position-indexed cleanups returned by inner ref callbacks. A slot is\n\t// `undefined` when the ref at that position did not return a cleanup (or\n\t// is an object ref / disabled).\n\tconst cleanupsRef = useRef< Array< ( () => void ) | undefined > >( [] );\n\n\t// Update on render before the ref callback is called, so the ref callback\n\t// always has access to the current refs.\n\tcurrentRefsRef.current = refs;\n\n\t// If any of the refs change, call the previous ref with `null` and the new\n\t// ref with the node, except when the element changes in the same cycle, in\n\t// which case the ref callbacks will already have been called.\n\tuseLayoutEffect( () => {\n\t\tif (\n\t\t\tdidElementChangeRef.current === false &&\n\t\t\tisAttachedRef.current === true\n\t\t) {\n\t\t\trefs.forEach( ( ref, index ) => {\n\t\t\t\tconst previousRef = previousRefsRef.current[ index ];\n\t\t\t\tif ( ref !== previousRef ) {\n\t\t\t\t\tdetachRef( previousRef, index, cleanupsRef.current );\n\t\t\t\t\tcleanupsRef.current[ index ] = assignRef(\n\t\t\t\t\t\tref,\n\t\t\t\t\t\telementRef.current as T\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\tpreviousRefsRef.current = refs;\n\t}, refs );\n\n\t// No dependencies, must be reset after every render so ref callbacks are\n\t// correctly called after a ref change.\n\tuseLayoutEffect( () => {\n\t\tdidElementChangeRef.current = false;\n\t} );\n\n\t// There should be no dependencies so that `callback` is only called when\n\t// the node changes.\n\treturn useCallback( ( value: T | null ) => {\n\t\t// Update the element so it can be used when calling ref callbacks on a\n\t\t// dependency change.\n\t\telementRef.current = value;\n\n\t\tdidElementChangeRef.current = true;\n\t\tisAttachedRef.current = value !== null;\n\n\t\t// When an element changes, the current ref callback should be called\n\t\t// with the new element and the previous one with `null`.\n\t\tif ( value === null ) {\n\t\t\tpreviousRefsRef.current.forEach( ( ref, index ) => {\n\t\t\t\tdetachRef( ref, index, cleanupsRef.current );\n\t\t\t} );\n\t\t} else {\n\t\t\tcurrentRefsRef.current.forEach( ( ref, index ) => {\n\t\t\t\tcleanupsRef.current[ index ] = assignRef( ref, value );\n\t\t\t} );\n\t\t}\n\t}, [] );\n}\n"],
5
+ "mappings": ";AAGA,SAAS,QAAQ,aAAa,uBAAuB;AAMrD,SAAS,UAAgB,KAAe,OAAuC;AAC9E,MAAK,OAAO,QAAQ,YAAa;AAChC,UAAM,WAAW,IAAK,KAAM;AAC5B,WAAO,OAAO,aAAa,aAAa,WAAW;AAAA,EACpD,WAAY,OAAO,IAAI,eAAgB,SAAU,GAAI;AACpD,IAAE,IAA+B,UAAU;AAAA,EAC5C;AACA,SAAO;AACR;AAIA,SAAS,UACR,KACA,OACA,UACO;AACP,QAAM,UAAU,SAAU,KAAM;AAChC,MAAK,SAAU;AACd,aAAU,KAAM,IAAI;AACpB,YAAQ;AAAA,EACT,OAAO;AACN,cAAW,KAAK,IAAK;AAAA,EACtB;AACD;AA6Ce,SAAR,aACN,MACmB;AACnB,QAAM,aAAa,OAAoB,IAAK;AAC5C,QAAM,gBAAgB,OAAQ,KAAM;AACpC,QAAM,sBAAsB,OAAQ,KAAM;AAC1C,QAAM,kBAAkB,OAAsB,CAAC,CAAE;AACjD,QAAM,iBAAiB,OAAQ,IAAK;AAIpC,QAAM,cAAc,OAA+C,CAAC,CAAE;AAItE,iBAAe,UAAU;AAKzB,kBAAiB,MAAM;AACtB,QACC,oBAAoB,YAAY,SAChC,cAAc,YAAY,MACzB;AACD,WAAK,QAAS,CAAE,KAAK,UAAW;AAC/B,cAAM,cAAc,gBAAgB,QAAS,KAAM;AACnD,YAAK,QAAQ,aAAc;AAC1B,oBAAW,aAAa,OAAO,YAAY,OAAQ;AACnD,sBAAY,QAAS,KAAM,IAAI;AAAA,YAC9B;AAAA,YACA,WAAW;AAAA,UACZ;AAAA,QACD;AAAA,MACD,CAAE;AAAA,IACH;AAEA,oBAAgB,UAAU;AAAA,EAC3B,GAAG,IAAK;AAIR,kBAAiB,MAAM;AACtB,wBAAoB,UAAU;AAAA,EAC/B,CAAE;AAIF,SAAO,YAAa,CAAE,UAAqB;AAG1C,eAAW,UAAU;AAErB,wBAAoB,UAAU;AAC9B,kBAAc,UAAU,UAAU;AAIlC,QAAK,UAAU,MAAO;AACrB,sBAAgB,QAAQ,QAAS,CAAE,KAAK,UAAW;AAClD,kBAAW,KAAK,OAAO,YAAY,OAAQ;AAAA,MAC5C,CAAE;AAAA,IACH,OAAO;AACN,qBAAe,QAAQ,QAAS,CAAE,KAAK,UAAW;AACjD,oBAAY,QAAS,KAAM,IAAI,UAAW,KAAK,KAAM;AAAA,MACtD,CAAE;AAAA,IACH;AAAA,EACD,GAAG,CAAC,CAAE;AACP;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/hooks/use-resize-observer/use-resize-observer.ts"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useRef } from '@wordpress/element';\n/**\n * Internal dependencies\n */\nimport useEvent from '../use-event';\n\n// This is the current implementation of `useResizeObserver`.\n//\n// The legacy implementation is still supported for backwards compatibility.\n// This is achieved by overloading the exported function with both signatures,\n// and detecting which API is being used at runtime.\nexport function useResizeObserver< T extends HTMLElement >(\n\tcallback: ResizeObserverCallback,\n\tresizeObserverOptions: ResizeObserverOptions = {}\n): ( element?: T | null ) => void {\n\tconst callbackEvent = useEvent( callback );\n\n\tconst observedElementRef = useRef< T >( null );\n\tconst resizeObserverRef = useRef< ResizeObserver >( undefined );\n\treturn useEvent( ( element?: T | null ) => {\n\t\tif ( element === observedElementRef.current ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Set up `ResizeObserver`.\n\t\tresizeObserverRef.current ??= new ResizeObserver( callbackEvent );\n\t\tconst { current: resizeObserver } = resizeObserverRef;\n\n\t\t// Unobserve previous element.\n\t\tif ( observedElementRef.current ) {\n\t\t\tresizeObserver.unobserve( observedElementRef.current );\n\t\t}\n\n\t\t// Observe new element.\n\t\tobservedElementRef.current = element ?? null;\n\t\tif ( element ) {\n\t\t\tresizeObserver.observe( element, resizeObserverOptions );\n\t\t}\n\t} );\n}\n"],
5
- "mappings": ";AAGA,SAAS,cAAc;AAIvB,OAAO,cAAc;AAOd,SAAS,kBACf,UACA,wBAA+C,CAAC,GACf;AACjC,QAAM,gBAAgB,SAAU,QAAS;AAEzC,QAAM,qBAAqB,OAAa,IAAK;AAC7C,QAAM,oBAAoB,OAA0B,MAAU;AAC9D,SAAO,SAAU,CAAE,YAAwB;AAC1C,QAAK,YAAY,mBAAmB,SAAU;AAC7C;AAAA,IACD;AAGA,sBAAkB,YAAY,IAAI,eAAgB,aAAc;AAChE,UAAM,EAAE,SAAS,eAAe,IAAI;AAGpC,QAAK,mBAAmB,SAAU;AACjC,qBAAe,UAAW,mBAAmB,OAAQ;AAAA,IACtD;AAGA,uBAAmB,UAAU,WAAW;AACxC,QAAK,SAAU;AACd,qBAAe,QAAS,SAAS,qBAAsB;AAAA,IACxD;AAAA,EACD,CAAE;AACH;",
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useRef } from '@wordpress/element';\n/**\n * Internal dependencies\n */\nimport useEvent from '../use-event';\n\n// This is the current implementation of `useResizeObserver`.\n//\n// The legacy implementation is still supported for backwards compatibility.\n// This is achieved by overloading the exported function with both signatures,\n// and detecting which API is being used at runtime.\nexport function useResizeObserver< T extends HTMLElement >(\n\tcallback: ResizeObserverCallback,\n\tresizeObserverOptions: ResizeObserverOptions = {}\n): ( element?: T | null ) => void {\n\tconst callbackEvent = useEvent( callback );\n\n\tconst observedElementRef = useRef< T | null >( null );\n\tconst resizeObserverRef = useRef< ResizeObserver >( undefined );\n\treturn useEvent( ( element?: T | null ) => {\n\t\tif ( element === observedElementRef.current ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Set up `ResizeObserver`.\n\t\tresizeObserverRef.current ??= new ResizeObserver( callbackEvent );\n\t\tconst { current: resizeObserver } = resizeObserverRef;\n\n\t\t// Unobserve previous element.\n\t\tif ( observedElementRef.current ) {\n\t\t\tresizeObserver.unobserve( observedElementRef.current );\n\t\t}\n\n\t\t// Observe new element.\n\t\tobservedElementRef.current = element ?? null;\n\t\tif ( element ) {\n\t\t\tresizeObserver.observe( element, resizeObserverOptions );\n\t\t}\n\t} );\n}\n"],
5
+ "mappings": ";AAGA,SAAS,cAAc;AAIvB,OAAO,cAAc;AAOd,SAAS,kBACf,UACA,wBAA+C,CAAC,GACf;AACjC,QAAM,gBAAgB,SAAU,QAAS;AAEzC,QAAM,qBAAqB,OAAoB,IAAK;AACpD,QAAM,oBAAoB,OAA0B,MAAU;AAC9D,SAAO,SAAU,CAAE,YAAwB;AAC1C,QAAK,YAAY,mBAAmB,SAAU;AAC7C;AAAA,IACD;AAGA,sBAAkB,YAAY,IAAI,eAAgB,aAAc;AAChE,UAAM,EAAE,SAAS,eAAe,IAAI;AAGpC,QAAK,mBAAmB,SAAU;AACjC,qBAAe,UAAW,mBAAmB,OAAQ;AAAA,IACtD;AAGA,uBAAmB,UAAU,WAAW;AACxC,QAAK,SAAU;AACd,qBAAe,QAAS,SAAS,qBAAsB;AAAA,IACxD;AAAA,EACD,CAAE;AACH;",
6
6
  "names": []
7
7
  }
@@ -24,7 +24,7 @@ var ViewportMatchWidthContext = createContext(
24
24
  null
25
25
  );
26
26
  ViewportMatchWidthContext.displayName = "ViewportMatchWidthContext";
27
- var useViewportMatch = (breakpoint, operator = ">=", view = window) => {
27
+ var useViewportMatch = (breakpoint, operator = ">=", view = typeof window !== "undefined" ? window : void 0) => {
28
28
  const simulatedWidth = useContext(ViewportMatchWidthContext);
29
29
  const mediaQuery = !simulatedWidth && `(${CONDITIONS[operator]}: ${BREAKPOINTS[breakpoint]}px)`;
30
30
  const mediaQueryResult = useMediaQuery(mediaQuery || void 0, view);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/hooks/use-viewport-match/index.js"],
4
- "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { createContext, useContext } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport useMediaQuery from '../use-media-query';\n\n/**\n * @typedef {\"xhuge\" | \"huge\" | \"wide\" | \"xlarge\" | \"large\" | \"medium\" | \"small\" | \"mobile\"} WPBreakpoint\n */\n\n/**\n * Hash of breakpoint names with pixel width at which it becomes effective.\n *\n * @see _breakpoints.scss\n *\n * @type {Record<WPBreakpoint, number>}\n */\nconst BREAKPOINTS = {\n\txhuge: 1920,\n\thuge: 1440,\n\twide: 1280,\n\txlarge: 1080,\n\tlarge: 960,\n\tmedium: 782,\n\tsmall: 600,\n\tmobile: 480,\n};\n\n/**\n * @typedef {\">=\" | \"<\"} WPViewportOperator\n */\n\n/**\n * Object mapping media query operators to the condition to be used.\n *\n * @type {Record<WPViewportOperator, string>}\n */\nconst CONDITIONS = {\n\t'>=': 'min-width',\n\t'<': 'max-width',\n};\n\n/**\n * Object mapping media query operators to a function that given a breakpointValue and a width evaluates if the operator matches the values.\n *\n * @type {Record<WPViewportOperator, (breakpointValue: number, width: number) => boolean>}\n */\nconst OPERATOR_EVALUATORS = {\n\t'>=': ( breakpointValue, width ) => width >= breakpointValue,\n\t'<': ( breakpointValue, width ) => width < breakpointValue,\n};\n\nconst ViewportMatchWidthContext = createContext(\n\t/** @type {null | number} */ ( null )\n);\nViewportMatchWidthContext.displayName = 'ViewportMatchWidthContext';\n\n/**\n * Returns true if the viewport matches the given query, or false otherwise.\n *\n * @param {WPBreakpoint} breakpoint Breakpoint size name.\n * @param {WPViewportOperator} [operator=\">=\"] Viewport operator.\n * @param {Window} [view=window] Window instance in which to perform viewport matching.\n *\n * @example\n *\n * ```js\n * useViewportMatch( 'huge', '<' );\n * useViewportMatch( 'medium' );\n * ```\n *\n * @return {boolean} Whether viewport matches query.\n */\nconst useViewportMatch = ( breakpoint, operator = '>=', view = window ) => {\n\tconst simulatedWidth = useContext( ViewportMatchWidthContext );\n\tconst mediaQuery =\n\t\t! simulatedWidth &&\n\t\t`(${ CONDITIONS[ operator ] }: ${ BREAKPOINTS[ breakpoint ] }px)`;\n\tconst mediaQueryResult = useMediaQuery( mediaQuery || undefined, view );\n\tif ( simulatedWidth ) {\n\t\treturn OPERATOR_EVALUATORS[ operator ](\n\t\t\tBREAKPOINTS[ breakpoint ],\n\t\t\tsimulatedWidth\n\t\t);\n\t}\n\treturn mediaQueryResult;\n};\n\nuseViewportMatch.__experimentalWidthProvider =\n\tViewportMatchWidthContext.Provider;\n\nexport default useViewportMatch;\n"],
5
- "mappings": ";AAGA,SAAS,eAAe,kBAAkB;AAK1C,OAAO,mBAAmB;AAa1B,IAAM,cAAc;AAAA,EACnB,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AACT;AAWA,IAAM,aAAa;AAAA,EAClB,MAAM;AAAA,EACN,KAAK;AACN;AAOA,IAAM,sBAAsB;AAAA,EAC3B,MAAM,CAAE,iBAAiB,UAAW,SAAS;AAAA,EAC7C,KAAK,CAAE,iBAAiB,UAAW,QAAQ;AAC5C;AAEA,IAAM,4BAA4B;AAAA;AAAA,EACF;AAChC;AACA,0BAA0B,cAAc;AAkBxC,IAAM,mBAAmB,CAAE,YAAY,WAAW,MAAM,OAAO,WAAY;AAC1E,QAAM,iBAAiB,WAAY,yBAA0B;AAC7D,QAAM,aACL,CAAE,kBACF,IAAK,WAAY,QAAS,CAAE,KAAM,YAAa,UAAW,CAAE;AAC7D,QAAM,mBAAmB,cAAe,cAAc,QAAW,IAAK;AACtE,MAAK,gBAAiB;AACrB,WAAO,oBAAqB,QAAS;AAAA,MACpC,YAAa,UAAW;AAAA,MACxB;AAAA,IACD;AAAA,EACD;AACA,SAAO;AACR;AAEA,iBAAiB,8BAChB,0BAA0B;AAE3B,IAAO,6BAAQ;",
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { createContext, useContext } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport useMediaQuery from '../use-media-query';\n\n/**\n * @typedef {\"xhuge\" | \"huge\" | \"wide\" | \"xlarge\" | \"large\" | \"medium\" | \"small\" | \"mobile\"} WPBreakpoint\n */\n\n/**\n * Hash of breakpoint names with pixel width at which it becomes effective.\n *\n * @see _breakpoints.scss\n *\n * @type {Record<WPBreakpoint, number>}\n */\nconst BREAKPOINTS = {\n\txhuge: 1920,\n\thuge: 1440,\n\twide: 1280,\n\txlarge: 1080,\n\tlarge: 960,\n\tmedium: 782,\n\tsmall: 600,\n\tmobile: 480,\n};\n\n/**\n * @typedef {\">=\" | \"<\"} WPViewportOperator\n */\n\n/**\n * Object mapping media query operators to the condition to be used.\n *\n * @type {Record<WPViewportOperator, string>}\n */\nconst CONDITIONS = {\n\t'>=': 'min-width',\n\t'<': 'max-width',\n};\n\n/**\n * Object mapping media query operators to a function that given a breakpointValue and a width evaluates if the operator matches the values.\n *\n * @type {Record<WPViewportOperator, (breakpointValue: number, width: number) => boolean>}\n */\nconst OPERATOR_EVALUATORS = {\n\t'>=': ( breakpointValue, width ) => width >= breakpointValue,\n\t'<': ( breakpointValue, width ) => width < breakpointValue,\n};\n\nconst ViewportMatchWidthContext = createContext(\n\t/** @type {null | number} */ ( null )\n);\nViewportMatchWidthContext.displayName = 'ViewportMatchWidthContext';\n\n/**\n * Returns true if the viewport matches the given query, or false otherwise.\n *\n * @param {WPBreakpoint} breakpoint Breakpoint size name.\n * @param {WPViewportOperator} [operator=\">=\"] Viewport operator.\n * @param {Window|undefined} [view=window] Window instance in which to perform viewport matching.\n *\n * @example\n *\n * ```js\n * useViewportMatch( 'huge', '<' );\n * useViewportMatch( 'medium' );\n * ```\n *\n * @return {boolean} Whether viewport matches query.\n */\nconst useViewportMatch = (\n\tbreakpoint,\n\toperator = '>=',\n\t// Resolve the default lazily so SSR (where `window` is undeclared) does not\n\t// throw a ReferenceError when this default expression is evaluated.\n\tview = typeof window !== 'undefined' ? window : undefined\n) => {\n\tconst simulatedWidth = useContext( ViewportMatchWidthContext );\n\tconst mediaQuery =\n\t\t! simulatedWidth &&\n\t\t`(${ CONDITIONS[ operator ] }: ${ BREAKPOINTS[ breakpoint ] }px)`;\n\tconst mediaQueryResult = useMediaQuery( mediaQuery || undefined, view );\n\tif ( simulatedWidth ) {\n\t\treturn OPERATOR_EVALUATORS[ operator ](\n\t\t\tBREAKPOINTS[ breakpoint ],\n\t\t\tsimulatedWidth\n\t\t);\n\t}\n\treturn mediaQueryResult;\n};\n\nuseViewportMatch.__experimentalWidthProvider =\n\tViewportMatchWidthContext.Provider;\n\nexport default useViewportMatch;\n"],
5
+ "mappings": ";AAGA,SAAS,eAAe,kBAAkB;AAK1C,OAAO,mBAAmB;AAa1B,IAAM,cAAc;AAAA,EACnB,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AACT;AAWA,IAAM,aAAa;AAAA,EAClB,MAAM;AAAA,EACN,KAAK;AACN;AAOA,IAAM,sBAAsB;AAAA,EAC3B,MAAM,CAAE,iBAAiB,UAAW,SAAS;AAAA,EAC7C,KAAK,CAAE,iBAAiB,UAAW,QAAQ;AAC5C;AAEA,IAAM,4BAA4B;AAAA;AAAA,EACF;AAChC;AACA,0BAA0B,cAAc;AAkBxC,IAAM,mBAAmB,CACxB,YACA,WAAW,MAGX,OAAO,OAAO,WAAW,cAAc,SAAS,WAC5C;AACJ,QAAM,iBAAiB,WAAY,yBAA0B;AAC7D,QAAM,aACL,CAAE,kBACF,IAAK,WAAY,QAAS,CAAE,KAAM,YAAa,UAAW,CAAE;AAC7D,QAAM,mBAAmB,cAAe,cAAc,QAAW,IAAK;AACtE,MAAK,gBAAiB;AACrB,WAAO,oBAAqB,QAAS;AAAA,MACpC,YAAa,UAAW;AAAA,MACxB;AAAA,IACD;AAAA,EACD;AACA,SAAO;AACR;AAEA,iBAAiB,8BAChB,0BAA0B;AAE3B,IAAO,6BAAQ;",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/higher-order/pure/index.tsx"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,OAAO,CAAC;AAa3D;;;;;GAKG;AACH,QAAA,MAAM,IAAI,GAA0C,KAAK,SAAS,EAAE,sDAuBzD,CAAC;eAEG,IAAI"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/higher-order/pure/index.tsx"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,OAAO,CAAC;AAc3D;;;;;GAKG;AACH,QAAA,MAAM,IAAI,GAA0C,KAAK,SAAS,EAAE,sDA4BzD,CAAC;eAEG,IAAI"}
@@ -30,6 +30,9 @@ declare const withSafeTimeout: <C extends WithInjectedProps<C, TimeoutProps>>(In
30
30
  forceUpdate(callback?: (() => void) | undefined): void;
31
31
  readonly props: Readonly<WithoutInjectedProps<C, TimeoutProps>>;
32
32
  state: Readonly<{}>;
33
+ refs: {
34
+ [key: string]: import("react").ReactInstance;
35
+ };
33
36
  componentDidMount?(): void;
34
37
  shouldComponentUpdate?(nextProps: Readonly<WithoutInjectedProps<C, TimeoutProps>>, nextState: Readonly<{}>, nextContext: any): boolean;
35
38
  componentDidCatch?(error: Error, errorInfo: import("react").ErrorInfo): void;
@@ -43,7 +46,6 @@ declare const withSafeTimeout: <C extends WithInjectedProps<C, TimeoutProps>>(In
43
46
  UNSAFE_componentWillUpdate?(nextProps: Readonly<WithoutInjectedProps<C, TimeoutProps>>, nextState: Readonly<{}>, nextContext: any): void;
44
47
  };
45
48
  contextType?: import("react").Context<any> | undefined;
46
- propTypes?: any;
47
49
  };
48
50
  export default withSafeTimeout;
49
51
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/higher-order/with-safe-timeout/index.tsx"],"names":[],"mappings":"AAKA;;GAEG;AACH,OAAO,KAAK,EACX,iBAAiB,EACjB,oBAAoB,EACpB,MAAM,2CAA2C,CAAC;AAGnD;;;;;;;GAOG;AACH,UAAU,YAAY;IACrB,UAAU,EAAE,CAAE,EAAE,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,MAAM,KAAM,MAAM,CAAC;IACxD,YAAY,EAAE,CAAE,EAAE,EAAE,MAAM,KAAM,IAAI,CAAC;CACrC;AAED;;;GAGG;AACH,QAAA,MAAM,eAAe,GAClB,CAAC,SAAS,iBAAiB,CAAE,CAAC,EAAE,YAAY,CAAE;;kBAKpC,MAAM,EAAE;;uBAaF,MAAM,IAAI,SAAS,MAAM;yBASvB,MAAM;;;;;;;;;;;;;;;;;;;;;CAoB1B,CAAC;eAEa,eAAe"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/higher-order/with-safe-timeout/index.tsx"],"names":[],"mappings":"AAKA;;GAEG;AACH,OAAO,KAAK,EACX,iBAAiB,EACjB,oBAAoB,EACpB,MAAM,2CAA2C,CAAC;AAGnD;;;;;;;GAOG;AACH,UAAU,YAAY;IACrB,UAAU,EAAE,CAAE,EAAE,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,MAAM,KAAM,MAAM,CAAC;IACxD,YAAY,EAAE,CAAE,EAAE,EAAE,MAAM,KAAM,IAAI,CAAC;CACrC;AAED;;;GAGG;AACH,QAAA,MAAM,eAAe,GAClB,CAAC,SAAS,iBAAiB,CAAE,CAAC,EAAE,YAAY,CAAE;;kBAKpC,MAAM,EAAE;;uBAaF,MAAM,IAAI,SAAS,MAAM;yBASvB,MAAM;;;;;;;;;;;;;;;;;;;;;;;CAoB1B,CAAC;eAEa,eAAe"}
@@ -5,5 +5,5 @@
5
5
  * @param [view] Window instance, else default to global window
6
6
  * @return return value of the media query.
7
7
  */
8
- export default function useMediaQuery(query?: string, view?: Window): boolean;
8
+ export default function useMediaQuery(query?: string, view?: Window | undefined): boolean;
9
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-media-query/index.ts"],"names":[],"mappings":"AAoEA;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,aAAa,CACpC,KAAK,CAAC,EAAE,MAAM,EACd,IAAI,GAAE,MAAe,GACnB,OAAO,CAQT"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-media-query/index.ts"],"names":[],"mappings":"AAuEA;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,aAAa,CACpC,KAAK,CAAC,EAAE,MAAM,EAGd,IAAI,GAAE,MAAM,GAAG,SAEH,GACV,OAAO,CAQT"}
@@ -15,22 +15,24 @@ import type { Ref, RefCallback } from 'react';
15
15
  * old ref callback will be called with `null` and the new ref callback will be
16
16
  * called with the same value.
17
17
  *
18
- * To make ref callbacks easier to use, you can also pass the result of
19
- * `useRefEffect`, which makes cleanup easier by allowing you to return a
20
- * cleanup function instead of handling `null`.
18
+ * Inner ref callbacks may return a cleanup function (React 19's ref callback
19
+ * cleanup pattern). When a ref callback returns a function, that function is
20
+ * invoked at teardown (node change, dependency change, or unmount) **instead
21
+ * of** the callback being called with `null`. Callbacks that do not return a
22
+ * cleanup continue to receive `null` on teardown as before.
21
23
  *
22
24
  * It's also possible to _disable_ a ref (and its behaviour) by simply not
23
25
  * passing the ref.
24
26
  *
25
27
  * ```jsx
26
- * const ref = useRefEffect( ( node ) => {
28
+ * const ref = useCallback( ( node ) => {
27
29
  * node.addEventListener( ... );
28
30
  * return () => {
29
31
  * node.removeEventListener( ... );
30
32
  * };
31
33
  * }, [ ...dependencies ] );
32
34
  * const otherRef = useRef();
33
- * const mergedRefs useMergeRefs( [
35
+ * const mergedRefs = useMergeRefs( [
34
36
  * enabled && ref,
35
37
  * otherRef,
36
38
  * ] );
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-merge-refs/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAU9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,MAAM,CAAC,OAAO,UAAU,YAAY,CAAE,CAAC,EACtC,IAAI,EAAE,GAAG,CAAE,CAAC,CAAE,EAAE,GACd,WAAW,CAAE,CAAC,CAAE,CA0DlB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-merge-refs/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAoB,GAAG,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AA+BhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,MAAM,CAAC,OAAO,UAAU,YAAY,CAAE,CAAC,EACtC,IAAI,EAAE,GAAG,CAAE,CAAC,CAAE,EAAE,GACd,WAAW,CAAE,CAAC,CAAE,CAkElB"}
@@ -1,6 +1,6 @@
1
1
  export type WPBreakpoint = "xhuge" | "huge" | "wide" | "xlarge" | "large" | "medium" | "small" | "mobile";
2
2
  export type WPViewportOperator = ">=" | "<";
3
- declare function useViewportMatch(breakpoint: WPBreakpoint, operator?: WPViewportOperator, view?: Window): boolean;
3
+ declare function useViewportMatch(breakpoint: WPBreakpoint, operator?: WPViewportOperator, view?: Window | undefined): boolean;
4
4
  declare namespace useViewportMatch {
5
5
  var __experimentalWidthProvider: import("react").Provider<number | null>;
6
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-viewport-match/index.js"],"names":[],"mappings":"AAWG,YAA0F,YAAY,GAA5F,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAc;AAsBtG,YAAsB,kBAAkB,GAA9B,IAAI,GAAG,GAAG,CAAoB;kCA4ChB,UAAU,EAb1B,YAa0B,EAAE,QAAQ,GAZpC,kBAY2C,EAAE,IAAI,GAXjD,MAW0D,GAFzD,OAAO;;;;eAoBJ,gBAAgB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/use-viewport-match/index.js"],"names":[],"mappings":"AAWG,YAA0F,YAAY,GAA5F,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAc;AAsBtG,YAAsB,kBAAkB,GAA9B,IAAI,GAAG,GAAG,CAAoB;kCA6C1C,UAAU,EAdA,YAcA,EACV,QAAQ,GAdE,kBAcK,EAGf,IAAI,GAhBM,MAAM,GAAC,SAgBwC,GAP9C,OAAO;;;;eA0BJ,gBAAgB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/compose",
3
- "version": "8.0.0",
3
+ "version": "8.1.1",
4
4
  "description": "WordPress higher-order components (HOCs).",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -41,32 +41,36 @@
41
41
  },
42
42
  "./package.json": "./package.json"
43
43
  },
44
- "react-native": "src/index",
45
44
  "wpScript": true,
46
45
  "types": "build-types",
47
46
  "sideEffects": false,
48
47
  "dependencies": {
49
48
  "@types/mousetrap": "^1.6.8",
50
- "@wordpress/deprecated": "^4.47.0",
51
- "@wordpress/dom": "^4.47.0",
52
- "@wordpress/element": "^7.0.0",
53
- "@wordpress/is-shallow-equal": "^5.47.0",
54
- "@wordpress/keycodes": "^4.47.0",
55
- "@wordpress/priority-queue": "^3.47.0",
56
- "@wordpress/private-apis": "^1.47.0",
57
- "@wordpress/undo-manager": "^1.47.0",
49
+ "@types/react": "^18.3.27",
50
+ "@wordpress/deprecated": "^4.48.1",
51
+ "@wordpress/dom": "^4.48.1",
52
+ "@wordpress/element": "^8.0.1",
53
+ "@wordpress/is-shallow-equal": "^5.48.1",
54
+ "@wordpress/keycodes": "^4.48.1",
55
+ "@wordpress/priority-queue": "^3.48.1",
56
+ "@wordpress/private-apis": "^1.48.1",
57
+ "@wordpress/undo-manager": "^1.48.1",
58
58
  "change-case": "^4.1.2",
59
59
  "mousetrap": "^1.6.5",
60
60
  "use-memo-one": "^1.1.1"
61
61
  },
62
62
  "devDependencies": {
63
- "mock-match-media": "0.4.2"
63
+ "@testing-library/dom": "^10.4.1",
64
+ "@testing-library/react": "^16.3.2",
65
+ "@testing-library/user-event": "^14.6.1",
66
+ "mock-match-media": "^0.4.2",
67
+ "react-dom": "^18.3.1"
64
68
  },
65
69
  "peerDependencies": {
66
- "react": "^19.2.4"
70
+ "react": "^18.0.0"
67
71
  },
68
72
  "publishConfig": {
69
73
  "access": "public"
70
74
  },
71
- "gitHead": "d653c5fd6161571a0c2ebde28553d6e25624eacc"
75
+ "gitHead": "99df7432c5c7cb83ba41146fd1f57f3c19004305"
72
76
  }
@@ -8,6 +8,7 @@ import type { ComponentType, ComponentClass } from 'react';
8
8
  */
9
9
  import { isShallowEqual } from '@wordpress/is-shallow-equal';
10
10
  import { Component } from '@wordpress/element';
11
+ import deprecated from '@wordpress/deprecated';
11
12
 
12
13
  /**
13
14
  * Internal dependencies
@@ -23,6 +24,11 @@ import { createHigherOrderComponent } from '../../utils/create-higher-order-comp
23
24
  const pure = createHigherOrderComponent( function < Props extends {} >(
24
25
  WrappedComponent: ComponentType< Props >
25
26
  ): ComponentType< Props > {
27
+ deprecated( 'wp.compose.pure', {
28
+ since: '7.1',
29
+ alternative: 'Use `memo` or `PureComponent` instead',
30
+ } );
31
+
26
32
  if ( WrappedComponent.prototype instanceof Component ) {
27
33
  return class extends ( WrappedComponent as ComponentClass< Props > ) {
28
34
  shouldComponentUpdate( nextProps: Props, nextState: any ) {
@@ -2,12 +2,11 @@
2
2
  * External dependencies
3
3
  */
4
4
  import { render, screen } from '@testing-library/react';
5
- import userEvent from '@testing-library/user-event';
6
5
 
7
6
  /**
8
7
  * WordPress dependencies
9
8
  */
10
- import { Component } from '@wordpress/element';
9
+ import { logged } from '@wordpress/deprecated';
11
10
 
12
11
  /**
13
12
  * Internal dependencies
@@ -15,88 +14,22 @@ import { Component } from '@wordpress/element';
15
14
  import pure from '../';
16
15
 
17
16
  describe( 'pure', () => {
18
- it( 'functional component should rerender only when props change', () => {
19
- let i = 0;
20
- const MyComp = pure( () => {
21
- return <p data-testid="counter">{ ++i }</p>;
22
- } );
23
- const { rerender } = render( <MyComp /> );
24
-
25
- // Updating with same props doesn't rerender.
26
- rerender( <MyComp /> );
27
- expect( screen.getByTestId( 'counter' ) ).toHaveTextContent( '1' );
28
-
29
- // New prop should trigger a rerender.
30
- rerender( <MyComp { ...{ prop: 'a' } } /> );
31
- expect( screen.getByTestId( 'counter' ) ).toHaveTextContent( '2' );
32
-
33
- // Keeping the same prop value should not rerender.
34
- rerender( <MyComp { ...{ prop: 'a' } } /> );
35
- expect( screen.getByTestId( 'counter' ) ).toHaveTextContent( '2' );
36
-
37
- // Changing the prop value should rerender.
38
- rerender( <MyComp { ...{ prop: 'b' } } /> );
39
- expect( screen.getByTestId( 'counter' ) ).toHaveTextContent( '3' );
17
+ afterEach( () => {
18
+ for ( const key in logged ) {
19
+ delete logged[ key ];
20
+ }
40
21
  } );
41
22
 
42
- it( 'class component should rerender if the props or state change', async () => {
43
- const user = userEvent.setup();
44
- let i = 0;
45
- const MyComp = pure(
46
- class extends Component {
47
- constructor() {
48
- super( ...arguments );
49
- this.state = {
50
- val: '',
51
- };
52
- }
53
- render() {
54
- return (
55
- <>
56
- <p data-testid="counter">{ ++i }</p>
57
- <input
58
- type="text"
59
- value={ this.state.val }
60
- onChange={ ( e ) =>
61
- this.setState( { val: e.target.value } )
62
- }
63
- />
64
- <input
65
- type="button"
66
- onClick={ () =>
67
- this.setState( { val: this.state.val } )
68
- }
69
- />
70
- </>
71
- );
72
- }
73
- }
74
- );
75
-
76
- const { rerender } = render( <MyComp /> );
23
+ it( 'wraps a component and logs a deprecation warning', () => {
24
+ const MyComp = pure( () => <p data-testid="content">content</p> );
77
25
 
78
- // Updating with same props doesn't rerender.
79
- rerender( <MyComp /> );
80
- expect( screen.getByTestId( 'counter' ) ).toHaveTextContent( '1' );
26
+ render( <MyComp /> );
81
27
 
82
- // New prop should trigger a rerender.
83
- rerender( <MyComp { ...{ prop: 'a' } } /> );
84
- expect( screen.getByTestId( 'counter' ) ).toHaveTextContent( '2' );
85
-
86
- // Keeping the same prop value should not rerender.
87
- rerender( <MyComp { ...{ prop: 'a' } } /> );
88
- expect( screen.getByTestId( 'counter' ) ).toHaveTextContent( '2' );
89
-
90
- // Changing the prop value should rerender.
91
- rerender( <MyComp { ...{ prop: 'b' } } /> );
92
- expect( screen.getByTestId( 'counter' ) ).toHaveTextContent( '3' );
93
-
94
- // New state value should trigger a rerender.
95
- await user.type( screen.getByRole( 'textbox' ), 'a' );
96
- expect( screen.getByTestId( 'counter' ) ).toHaveTextContent( '4' );
97
-
98
- // Keeping the same state value should not trigger a rerender.
99
- await user.click( screen.getByRole( 'button' ) );
100
- expect( screen.getByTestId( 'counter' ) ).toHaveTextContent( '4' );
28
+ expect( console ).toHaveWarnedWith(
29
+ 'wp.compose.pure is deprecated since version 7.1. Please use Use `memo` or `PureComponent` instead instead.'
30
+ );
31
+ expect( screen.getByTestId( 'content' ) ).toHaveTextContent(
32
+ 'content'
33
+ );
101
34
  } );
102
35
  } );
@@ -45,14 +45,14 @@ export default function useDisabled( {
45
45
  }
46
46
 
47
47
  /** A variable keeping track of the previous updates in order to restore them. */
48
- const updates: ( () => void )[] = [];
48
+ const updates: Function[] = [];
49
49
  const disable = () => {
50
50
  node.childNodes.forEach( ( child ) => {
51
51
  if ( ! ( child instanceof defaultView.HTMLElement ) ) {
52
52
  return;
53
53
  }
54
- if ( ! child.hasAttribute( 'inert' ) ) {
55
- child.setAttribute( 'inert', '' );
54
+ if ( ! child.getAttribute( 'inert' ) ) {
55
+ child.setAttribute( 'inert', 'true' );
56
56
  updates.push( () => {
57
57
  child.removeAttribute( 'inert' );
58
58
  } );
@@ -37,9 +37,9 @@ describe( 'useDisabled', () => {
37
37
  const link = screen.getByRole( 'link' );
38
38
  const p = screen.getByRole( 'document' );
39
39
 
40
- expect( input ).toHaveAttribute( 'inert' );
41
- expect( link ).toHaveAttribute( 'inert' );
42
- expect( p ).toHaveAttribute( 'inert' );
40
+ expect( input ).toHaveAttribute( 'inert', 'true' );
41
+ expect( link ).toHaveAttribute( 'inert', 'true' );
42
+ expect( p ).toHaveAttribute( 'inert', 'true' );
43
43
  } );
44
44
 
45
45
  it( 'will disable an element rendered in an update to the component', async () => {
@@ -52,7 +52,7 @@ describe( 'useDisabled', () => {
52
52
 
53
53
  const button = screen.getByText( 'Button' );
54
54
  await waitFor( () => {
55
- expect( button ).toHaveAttribute( 'inert' );
55
+ expect( button ).toHaveAttribute( 'inert', 'true' );
56
56
  } );
57
57
  } );
58
58
  } );
@@ -2,7 +2,7 @@
2
2
 
3
3
  A hook to facilitate drag and drop handling within a designated drop zone area. An optional `dropZoneElement` can be provided, however by default the drop zone is bound by the area where the returned `ref` is assigned.
4
4
 
5
- When using a `dropZoneElement`, it is expected that the `ref` will be attached to a node that is a descendent of the `dropZoneElement`. Additionally, the element passed to `dropZoneElement` should be stored in state rather than a plain ref to ensure reactive updating when it changes.
5
+ When using a `dropZoneElement`, it is expected that the `ref` will be attached to a node that is a descendant of the `dropZoneElement`. Additionally, the element passed to `dropZoneElement` should be stored in state rather than a plain ref to ensure reactive updating when it changes.
6
6
 
7
7
  ## Usage
8
8
 
@@ -29,9 +29,9 @@ let origin = null;
29
29
  * ```
30
30
  */
31
31
  function useFocusReturn( onFocusReturn ) {
32
- /** @type {React.RefObject<HTMLElement| null>} */
32
+ /** @type {React.MutableRefObject<null | HTMLElement>} */
33
33
  const ref = useRef( null );
34
- /** @type {React.RefObject<Element | null>} */
34
+ /** @type {React.MutableRefObject<null | Element>} */
35
35
  const focusedBeforeMount = useRef( null );
36
36
  const onFocusReturnRef = useRef( onFocusReturn );
37
37
  useEffect( () => {
@@ -19,8 +19,11 @@ const EMPTY_SUBSCRIBER: MQLSubscriber = {
19
19
  getValue: () => false,
20
20
  };
21
21
 
22
- function getMQLSubscriber( view: Window, query?: string ): MQLSubscriber {
23
- if ( ! query || typeof view?.matchMedia !== 'function' ) {
22
+ function getMQLSubscriber(
23
+ view: Window | undefined,
24
+ query?: string
25
+ ): MQLSubscriber {
26
+ if ( ! view || ! query || typeof view.matchMedia !== 'function' ) {
24
27
  return EMPTY_SUBSCRIBER;
25
28
  }
26
29
 
@@ -75,7 +78,11 @@ function getMQLSubscriber( view: Window, query?: string ): MQLSubscriber {
75
78
  */
76
79
  export default function useMediaQuery(
77
80
  query?: string,
78
- view: Window = window
81
+ // Resolve the default lazily so SSR (where `window` is undeclared) does not
82
+ // throw a ReferenceError when this default expression is evaluated.
83
+ view: Window | undefined = typeof window !== 'undefined'
84
+ ? window
85
+ : undefined
79
86
  ): boolean {
80
87
  const source = getMQLSubscriber( view, query );
81
88
 
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @jest-environment node
3
+ */
4
+
5
+ /**
6
+ * External dependencies
7
+ */
8
+ import { renderToString } from 'react-dom/server';
9
+
10
+ /**
11
+ * Internal dependencies
12
+ */
13
+ import useMediaQuery from '../';
14
+ import useViewportMatch from '../../use-viewport-match';
15
+
16
+ const MediaQueryComponent = ( { query } ) => {
17
+ const result = useMediaQuery( query );
18
+ return `useMediaQuery: ${ result }`;
19
+ };
20
+
21
+ const ViewportMatchComponent = ( { breakpoint, operator } ) => {
22
+ const result = useViewportMatch( breakpoint, operator );
23
+ return `useViewportMatch: ${ result }`;
24
+ };
25
+
26
+ describe( 'compose hooks in a server (no-window) environment', () => {
27
+ it( 'useMediaQuery renders to false without throwing when window is undefined', () => {
28
+ expect( typeof window ).toBe( 'undefined' );
29
+ expect(
30
+ renderToString( <MediaQueryComponent query="(min-width: 782px)" /> )
31
+ ).toBe( 'useMediaQuery: false' );
32
+ } );
33
+
34
+ it( 'useMediaQuery renders to false when no query is provided', () => {
35
+ expect( renderToString( <MediaQueryComponent /> ) ).toBe(
36
+ 'useMediaQuery: false'
37
+ );
38
+ } );
39
+
40
+ it( 'useViewportMatch renders to false without throwing when window is undefined', () => {
41
+ expect(
42
+ renderToString(
43
+ <ViewportMatchComponent breakpoint="small" operator=">=" />
44
+ )
45
+ ).toBe( 'useViewportMatch: false' );
46
+ } );
47
+ } );