@wordpress/compose 5.5.0 → 5.8.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.
Files changed (56) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +35 -9
  3. package/build/hooks/use-copy-to-clipboard/index.js +1 -1
  4. package/build/hooks/use-copy-to-clipboard/index.js.map +1 -1
  5. package/build/hooks/use-disabled/index.js +114 -42
  6. package/build/hooks/use-disabled/index.js.map +1 -1
  7. package/build/hooks/use-focus-on-mount/index.js +6 -1
  8. package/build/hooks/use-focus-on-mount/index.js.map +1 -1
  9. package/build/hooks/use-ref-effect/index.js.map +1 -1
  10. package/build/hooks/use-resize-observer/index.js +224 -13
  11. package/build/hooks/use-resize-observer/index.js.map +1 -1
  12. package/build/hooks/use-resize-observer/index.native.js +0 -2
  13. package/build/hooks/use-resize-observer/index.native.js.map +1 -1
  14. package/build/index.js +6 -6
  15. package/build/index.js.map +1 -1
  16. package/build/index.native.js +8 -0
  17. package/build/index.native.js.map +1 -1
  18. package/build-module/hooks/use-copy-to-clipboard/index.js +1 -1
  19. package/build-module/hooks/use-copy-to-clipboard/index.js.map +1 -1
  20. package/build-module/hooks/use-disabled/index.js +110 -40
  21. package/build-module/hooks/use-disabled/index.js.map +1 -1
  22. package/build-module/hooks/use-focus-on-mount/index.js +6 -1
  23. package/build-module/hooks/use-focus-on-mount/index.js.map +1 -1
  24. package/build-module/hooks/use-ref-effect/index.js.map +1 -1
  25. package/build-module/hooks/use-resize-observer/index.js +226 -9
  26. package/build-module/hooks/use-resize-observer/index.js.map +1 -1
  27. package/build-module/hooks/use-resize-observer/index.native.js +0 -2
  28. package/build-module/hooks/use-resize-observer/index.native.js.map +1 -1
  29. package/build-module/index.js +1 -1
  30. package/build-module/index.js.map +1 -1
  31. package/build-module/index.native.js +1 -0
  32. package/build-module/index.native.js.map +1 -1
  33. package/build-types/higher-order/if-condition/index.d.ts +0 -1
  34. package/build-types/higher-order/if-condition/index.d.ts.map +1 -1
  35. package/build-types/higher-order/with-instance-id/index.d.ts +0 -1
  36. package/build-types/higher-order/with-instance-id/index.d.ts.map +1 -1
  37. package/build-types/hooks/use-disabled/index.d.ts +7 -3
  38. package/build-types/hooks/use-disabled/index.d.ts.map +1 -1
  39. package/build-types/hooks/use-focus-on-mount/index.d.ts.map +1 -1
  40. package/build-types/hooks/use-ref-effect/index.d.ts +1 -1
  41. package/build-types/hooks/use-ref-effect/index.d.ts.map +1 -1
  42. package/build-types/hooks/use-resize-observer/index.d.ts +32 -2
  43. package/build-types/hooks/use-resize-observer/index.d.ts.map +1 -1
  44. package/build-types/index.d.ts +1 -1
  45. package/package.json +8 -9
  46. package/src/hooks/use-copy-to-clipboard/index.js +1 -1
  47. package/src/hooks/use-disabled/index.js +141 -51
  48. package/src/hooks/use-focus-on-mount/index.js +6 -1
  49. package/src/hooks/use-ref-effect/index.ts +2 -2
  50. package/src/hooks/use-resize-observer/index.native.js +0 -2
  51. package/src/hooks/use-resize-observer/index.tsx +362 -0
  52. package/src/index.js +1 -1
  53. package/src/index.native.js +1 -0
  54. package/tsconfig.json +2 -4
  55. package/tsconfig.tsbuildinfo +1 -1
  56. package/src/hooks/use-resize-observer/index.js +0 -31
package/CHANGELOG.md CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 5.8.0 (2022-06-01)
6
+
7
+ ## 5.7.0 (2022-05-18)
8
+
9
+ ### Bug Fix
10
+
11
+ - `useRefEffect`: Allow `void` as a valid callback return type ([#40798](https://github.com/WordPress/gutenberg/pull/40798)).
12
+
13
+ ### New Features
14
+
15
+ - Add `useDisabled` hook.
16
+
17
+ ### Internal
18
+
19
+ - Update the implementation of useResizeObserver to rely on the ResizableObserver API.
20
+
21
+ ## 5.6.0 (2022-05-04)
22
+
5
23
  ## 5.5.0 (2022-04-21)
6
24
 
7
25
  ## 5.4.0 (2022-04-08)
package/README.md CHANGED
@@ -205,6 +205,39 @@ _Returns_
205
205
 
206
206
  - `import('lodash').DebouncedFunc<TFunc>`: Debounced function.
207
207
 
208
+ ### useDisabled
209
+
210
+ In some circumstances, such as block previews, all focusable DOM elements
211
+ (input fields, links, buttons, etc.) need to be disabled. This hook adds the
212
+ behavior to disable nested DOM elements to the returned ref.
213
+
214
+ _Usage_
215
+
216
+ ```js
217
+ import { useDisabled } from '@wordpress/compose';
218
+ const DisabledExample = () => {
219
+ const disabledRef = useDisabled();
220
+ return (
221
+ <div ref={ disabledRef }>
222
+ <a href="#">This link will have tabindex set to -1</a>
223
+ <input
224
+ placeholder="This input will have the disabled attribute added to it."
225
+ type="text"
226
+ />
227
+ </div>
228
+ );
229
+ };
230
+ ```
231
+
232
+ _Parameters_
233
+
234
+ - _config_ `Object`: Configuration object.
235
+ - _config.isDisabled_ `boolean=`: Whether the element should be disabled.
236
+
237
+ _Returns_
238
+
239
+ - `import('react').RefCallback<HTMLElement>`: Element Ref.
240
+
208
241
  ### useFocusableIframe
209
242
 
210
243
  Dispatches a bubbling focus event when the iframe receives focus. Use
@@ -404,7 +437,7 @@ callback will be called multiple times for the same node.
404
437
 
405
438
  _Parameters_
406
439
 
407
- - _callback_ `( node: TElement ) => ( () => void ) | undefined`: Callback with ref as argument.
440
+ - _callback_ `( node: TElement ) => ( () => void ) | void`: Callback with ref as argument.
408
441
  - _dependencies_ `DependencyList`: Dependencies of the callback.
409
442
 
410
443
  _Returns_
@@ -414,14 +447,7 @@ _Returns_
414
447
  ### useResizeObserver
415
448
 
416
449
  Hook which allows to listen the resize event of any target element when it changes sizes.
417
- _Note: `useResizeObserver` will report `null` until after first render_
418
-
419
- Simply a re-export of `react-resize-aware` so refer to its documentation <https://github.com/FezVrasta/react-resize-aware>
420
- for more details.
421
-
422
- _Related_
423
-
424
- - <https://github.com/FezVrasta/react-resize-aware>
450
+ \_Note: `useResizeObserver` will report `null` until after first render.
425
451
 
426
452
  _Usage_
427
453
 
@@ -48,7 +48,7 @@ function useUpdatedRef(value) {
48
48
 
49
49
 
50
50
  function useCopyToClipboard(text, onSuccess) {
51
- // Store the dependencies as refs and continuesly update them so they're
51
+ // Store the dependencies as refs and continuously update them so they're
52
52
  // fresh when the callback is called.
53
53
  const textRef = useUpdatedRef(text);
54
54
  const onSuccessRef = useUpdatedRef(onSuccess);
@@ -1 +1 @@
1
- {"version":3,"sources":["@wordpress/compose/src/hooks/use-copy-to-clipboard/index.js"],"names":["useUpdatedRef","value","ref","current","useCopyToClipboard","text","onSuccess","textRef","onSuccessRef","node","clipboard","Clipboard","on","clearSelection","focus","destroy"],"mappings":";;;;;;;;;AAGA;;AAKA;;AAKA;;AAbA;AACA;AACA;;AAGA;AACA;AACA;;AAGA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA,SAASA,aAAT,CAAwBC,KAAxB,EAAgC;AAC/B,QAAMC,GAAG,GAAG,qBAAQD,KAAR,CAAZ;AACAC,EAAAA,GAAG,CAACC,OAAJ,GAAcF,KAAd;AACA,SAAOC,GAAP;AACA;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACe,SAASE,kBAAT,CAA6BC,IAA7B,EAAmCC,SAAnC,EAA+C;AAC7D;AACA;AACA,QAAMC,OAAO,GAAGP,aAAa,CAAEK,IAAF,CAA7B;AACA,QAAMG,YAAY,GAAGR,aAAa,CAAEM,SAAF,CAAlC;AACA,SAAO,2BAAgBG,IAAF,IAAY;AAChC;AACA,UAAMC,SAAS,GAAG,IAAIC,kBAAJ,CAAeF,IAAf,EAAqB;AACtCJ,MAAAA,IAAI,GAAG;AACN,eAAO,OAAOE,OAAO,CAACJ,OAAf,KAA2B,UAA3B,GACJI,OAAO,CAACJ,OAAR,EADI,GAEJI,OAAO,CAACJ,OAAR,IAAmB,EAFtB;AAGA;;AALqC,KAArB,CAAlB;AAQAO,IAAAA,SAAS,CAACE,EAAV,CAAc,SAAd,EAAyB,QAA0B;AAAA,UAAxB;AAAEC,QAAAA;AAAF,OAAwB;AAClD;AACA;AACA;AACAA,MAAAA,cAAc,GAJoC,CAKlD;AACA;;AACAJ,MAAAA,IAAI,CAACK,KAAL;;AAEA,UAAKN,YAAY,CAACL,OAAlB,EAA4B;AAC3BK,QAAAA,YAAY,CAACL,OAAb;AACA;AACD,KAZD;AAcA,WAAO,MAAM;AACZO,MAAAA,SAAS,CAACK,OAAV;AACA,KAFD;AAGA,GA3BM,EA2BJ,EA3BI,CAAP;AA4BA","sourcesContent":["/**\n * External dependencies\n */\nimport Clipboard from 'clipboard';\n\n/**\n * WordPress dependencies\n */\nimport { useRef } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport useRefEffect from '../use-ref-effect';\n\n/**\n * @template T\n * @param {T} value\n * @return {import('react').RefObject<T>} The updated ref\n */\nfunction useUpdatedRef( value ) {\n\tconst ref = useRef( value );\n\tref.current = value;\n\treturn ref;\n}\n\n/**\n * Copies the given text to the clipboard when the element is clicked.\n *\n * @template {HTMLElement} TElementType\n * @param {string | (() => string)} text The text to copy. Use a function if not\n * already available and expensive to compute.\n * @param {Function} onSuccess Called when to text is copied.\n *\n * @return {import('react').Ref<TElementType>} A ref to assign to the target element.\n */\nexport default function useCopyToClipboard( text, onSuccess ) {\n\t// Store the dependencies as refs and continuesly update them so they're\n\t// fresh when the callback is called.\n\tconst textRef = useUpdatedRef( text );\n\tconst onSuccessRef = useUpdatedRef( onSuccess );\n\treturn useRefEffect( ( node ) => {\n\t\t// Clipboard listens to click events.\n\t\tconst clipboard = new Clipboard( node, {\n\t\t\ttext() {\n\t\t\t\treturn typeof textRef.current === 'function'\n\t\t\t\t\t? textRef.current()\n\t\t\t\t\t: textRef.current || '';\n\t\t\t},\n\t\t} );\n\n\t\tclipboard.on( 'success', ( { clearSelection } ) => {\n\t\t\t// Clearing selection will move focus back to the triggering\n\t\t\t// button, ensuring that it is not reset to the body, and\n\t\t\t// further that it is kept within the rendered node.\n\t\t\tclearSelection();\n\t\t\t// Handle ClipboardJS focus bug, see\n\t\t\t// https://github.com/zenorocha/clipboard.js/issues/680\n\t\t\tnode.focus();\n\n\t\t\tif ( onSuccessRef.current ) {\n\t\t\t\tonSuccessRef.current();\n\t\t\t}\n\t\t} );\n\n\t\treturn () => {\n\t\t\tclipboard.destroy();\n\t\t};\n\t}, [] );\n}\n"]}
1
+ {"version":3,"sources":["@wordpress/compose/src/hooks/use-copy-to-clipboard/index.js"],"names":["useUpdatedRef","value","ref","current","useCopyToClipboard","text","onSuccess","textRef","onSuccessRef","node","clipboard","Clipboard","on","clearSelection","focus","destroy"],"mappings":";;;;;;;;;AAGA;;AAKA;;AAKA;;AAbA;AACA;AACA;;AAGA;AACA;AACA;;AAGA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA,SAASA,aAAT,CAAwBC,KAAxB,EAAgC;AAC/B,QAAMC,GAAG,GAAG,qBAAQD,KAAR,CAAZ;AACAC,EAAAA,GAAG,CAACC,OAAJ,GAAcF,KAAd;AACA,SAAOC,GAAP;AACA;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACe,SAASE,kBAAT,CAA6BC,IAA7B,EAAmCC,SAAnC,EAA+C;AAC7D;AACA;AACA,QAAMC,OAAO,GAAGP,aAAa,CAAEK,IAAF,CAA7B;AACA,QAAMG,YAAY,GAAGR,aAAa,CAAEM,SAAF,CAAlC;AACA,SAAO,2BAAgBG,IAAF,IAAY;AAChC;AACA,UAAMC,SAAS,GAAG,IAAIC,kBAAJ,CAAeF,IAAf,EAAqB;AACtCJ,MAAAA,IAAI,GAAG;AACN,eAAO,OAAOE,OAAO,CAACJ,OAAf,KAA2B,UAA3B,GACJI,OAAO,CAACJ,OAAR,EADI,GAEJI,OAAO,CAACJ,OAAR,IAAmB,EAFtB;AAGA;;AALqC,KAArB,CAAlB;AAQAO,IAAAA,SAAS,CAACE,EAAV,CAAc,SAAd,EAAyB,QAA0B;AAAA,UAAxB;AAAEC,QAAAA;AAAF,OAAwB;AAClD;AACA;AACA;AACAA,MAAAA,cAAc,GAJoC,CAKlD;AACA;;AACAJ,MAAAA,IAAI,CAACK,KAAL;;AAEA,UAAKN,YAAY,CAACL,OAAlB,EAA4B;AAC3BK,QAAAA,YAAY,CAACL,OAAb;AACA;AACD,KAZD;AAcA,WAAO,MAAM;AACZO,MAAAA,SAAS,CAACK,OAAV;AACA,KAFD;AAGA,GA3BM,EA2BJ,EA3BI,CAAP;AA4BA","sourcesContent":["/**\n * External dependencies\n */\nimport Clipboard from 'clipboard';\n\n/**\n * WordPress dependencies\n */\nimport { useRef } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport useRefEffect from '../use-ref-effect';\n\n/**\n * @template T\n * @param {T} value\n * @return {import('react').RefObject<T>} The updated ref\n */\nfunction useUpdatedRef( value ) {\n\tconst ref = useRef( value );\n\tref.current = value;\n\treturn ref;\n}\n\n/**\n * Copies the given text to the clipboard when the element is clicked.\n *\n * @template {HTMLElement} TElementType\n * @param {string | (() => string)} text The text to copy. Use a function if not\n * already available and expensive to compute.\n * @param {Function} onSuccess Called when to text is copied.\n *\n * @return {import('react').Ref<TElementType>} A ref to assign to the target element.\n */\nexport default function useCopyToClipboard( text, onSuccess ) {\n\t// Store the dependencies as refs and continuously update them so they're\n\t// fresh when the callback is called.\n\tconst textRef = useUpdatedRef( text );\n\tconst onSuccessRef = useUpdatedRef( onSuccess );\n\treturn useRefEffect( ( node ) => {\n\t\t// Clipboard listens to click events.\n\t\tconst clipboard = new Clipboard( node, {\n\t\t\ttext() {\n\t\t\t\treturn typeof textRef.current === 'function'\n\t\t\t\t\t? textRef.current()\n\t\t\t\t\t: textRef.current || '';\n\t\t\t},\n\t\t} );\n\n\t\tclipboard.on( 'success', ( { clearSelection } ) => {\n\t\t\t// Clearing selection will move focus back to the triggering\n\t\t\t// button, ensuring that it is not reset to the body, and\n\t\t\t// further that it is kept within the rendered node.\n\t\t\tclearSelection();\n\t\t\t// Handle ClipboardJS focus bug, see\n\t\t\t// https://github.com/zenorocha/clipboard.js/issues/680\n\t\t\tnode.focus();\n\n\t\t\tif ( onSuccessRef.current ) {\n\t\t\t\tonSuccessRef.current();\n\t\t\t}\n\t\t} );\n\n\t\treturn () => {\n\t\t\tclipboard.destroy();\n\t\t};\n\t}, [] );\n}\n"]}
@@ -1,5 +1,7 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
3
5
  Object.defineProperty(exports, "__esModule", {
4
6
  value: true
5
7
  });
@@ -7,10 +9,10 @@ exports.default = useDisabled;
7
9
 
8
10
  var _lodash = require("lodash");
9
11
 
10
- var _element = require("@wordpress/element");
11
-
12
12
  var _dom = require("@wordpress/dom");
13
13
 
14
+ var _useRefEffect = _interopRequireDefault(require("../use-ref-effect"));
15
+
14
16
  /**
15
17
  * External dependencies
16
18
  */
@@ -19,6 +21,10 @@ var _dom = require("@wordpress/dom");
19
21
  * WordPress dependencies
20
22
  */
21
23
 
24
+ /**
25
+ * Internal dependencies
26
+ */
27
+
22
28
  /**
23
29
  * Names of control nodes which qualify for disabled behavior.
24
30
  *
@@ -34,11 +40,13 @@ const DISABLED_ELIGIBLE_NODE_NAMES = ['BUTTON', 'FIELDSET', 'INPUT', 'OPTGROUP',
34
40
  * (input fields, links, buttons, etc.) need to be disabled. This hook adds the
35
41
  * behavior to disable nested DOM elements to the returned ref.
36
42
  *
37
- * @return {import('react').RefObject<HTMLElement>} Element Ref.
43
+ * @param {Object} config Configuration object.
44
+ * @param {boolean=} config.isDisabled Whether the element should be disabled.
45
+ * @return {import('react').RefCallback<HTMLElement>} Element Ref.
38
46
  *
39
47
  * @example
40
48
  * ```js
41
- * import { __experimentalUseDisabled as useDisabled } from '@wordpress/compose';
49
+ * import { useDisabled } from '@wordpress/compose';
42
50
  * const DisabledExample = () => {
43
51
  * const disabledRef = useDisabled();
44
52
  * return (
@@ -52,63 +60,127 @@ const DISABLED_ELIGIBLE_NODE_NAMES = ['BUTTON', 'FIELDSET', 'INPUT', 'OPTGROUP',
52
60
  */
53
61
 
54
62
  function useDisabled() {
55
- /** @type {import('react').RefObject<HTMLElement>} */
56
- const node = (0, _element.useRef)(null);
57
-
58
- const disable = () => {
59
- if (!node.current) {
63
+ let {
64
+ isDisabled: isDisabledProp = false
65
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
66
+ return (0, _useRefEffect.default)(node => {
67
+ if (isDisabledProp) {
60
68
  return;
61
69
  }
70
+ /** A variable keeping track of the previous updates in order to restore them. */
62
71
 
63
- _dom.focus.focusable.find(node.current).forEach(focusable => {
64
- if ((0, _lodash.includes)(DISABLED_ELIGIBLE_NODE_NAMES, focusable.nodeName)) {
65
- focusable.setAttribute('disabled', '');
66
- }
72
+ /** @type {Function[]} */
67
73
 
68
- if (focusable.nodeName === 'A') {
69
- focusable.setAttribute('tabindex', '-1');
70
- }
71
74
 
72
- const tabIndex = focusable.getAttribute('tabindex');
75
+ const updates = [];
73
76
 
74
- if (tabIndex !== null && tabIndex !== '-1') {
75
- focusable.removeAttribute('tabindex');
76
- }
77
+ const disable = () => {
78
+ if (node.style.getPropertyValue('user-select') !== 'none') {
79
+ const previousValue = node.style.getPropertyValue('user-select');
80
+ node.style.setProperty('user-select', 'none');
81
+ node.style.setProperty('-webkit-user-select', 'none');
82
+ updates.push(() => {
83
+ if (!node.isConnected) {
84
+ return;
85
+ }
77
86
 
78
- if (focusable.hasAttribute('contenteditable')) {
79
- focusable.setAttribute('contenteditable', 'false');
87
+ node.style.setProperty('user-select', previousValue);
88
+ node.style.setProperty('-webkit-user-select', previousValue);
89
+ });
80
90
  }
81
- });
82
- }; // Debounce re-disable since disabling process itself will incur
83
- // additional mutations which should be ignored.
91
+
92
+ _dom.focus.focusable.find(node).forEach(focusable => {
93
+ var _node$ownerDocument$d;
94
+
95
+ if ((0, _lodash.includes)(DISABLED_ELIGIBLE_NODE_NAMES, focusable.nodeName) && // @ts-ignore
96
+ !focusable.disabled) {
97
+ focusable.setAttribute('disabled', '');
98
+ updates.push(() => {
99
+ if (!focusable.isConnected) {
100
+ return;
101
+ } // @ts-ignore
102
+
103
+
104
+ focusable.disabled = false;
105
+ });
106
+ }
107
+
108
+ if (focusable.nodeName === 'A' && focusable.getAttribute('tabindex') !== '-1') {
109
+ const previousValue = focusable.getAttribute('tabindex');
110
+ focusable.setAttribute('tabindex', '-1');
111
+ updates.push(() => {
112
+ if (!focusable.isConnected) {
113
+ return;
114
+ }
115
+
116
+ if (!previousValue) {
117
+ focusable.removeAttribute('tabindex');
118
+ } else {
119
+ focusable.setAttribute('tabindex', previousValue);
120
+ }
121
+ });
122
+ }
123
+
124
+ const tabIndex = focusable.getAttribute('tabindex');
125
+
126
+ if (tabIndex !== null && tabIndex !== '-1') {
127
+ focusable.removeAttribute('tabindex');
128
+ updates.push(() => {
129
+ if (!focusable.isConnected) {
130
+ return;
131
+ }
132
+
133
+ focusable.setAttribute('tabindex', tabIndex);
134
+ });
135
+ }
136
+
137
+ if (focusable.hasAttribute('contenteditable') && focusable.getAttribute('contenteditable') !== 'false') {
138
+ focusable.setAttribute('contenteditable', 'false');
139
+ updates.push(() => {
140
+ if (!focusable.isConnected) {
141
+ return;
142
+ }
143
+
144
+ focusable.setAttribute('contenteditable', 'true');
145
+ });
146
+ }
147
+
148
+ if ((_node$ownerDocument$d = node.ownerDocument.defaultView) !== null && _node$ownerDocument$d !== void 0 && _node$ownerDocument$d.HTMLElement && focusable instanceof node.ownerDocument.defaultView.HTMLElement) {
149
+ const previousValue = focusable.style.getPropertyValue('pointer-events');
150
+ focusable.style.setProperty('pointer-events', 'none');
151
+ updates.push(() => {
152
+ if (!focusable.isConnected) {
153
+ return;
154
+ }
155
+
156
+ focusable.style.setProperty('pointer-events', previousValue);
157
+ });
158
+ }
159
+ });
160
+ }; // Debounce re-disable since disabling process itself will incur
161
+ // additional mutations which should be ignored.
84
162
 
85
163
 
86
- const debouncedDisable = (0, _element.useCallback)((0, _lodash.debounce)(disable, undefined, {
87
- leading: true
88
- }), []);
89
- (0, _element.useLayoutEffect)(() => {
164
+ const debouncedDisable = (0, _lodash.debounce)(disable, undefined, {
165
+ leading: true
166
+ });
90
167
  disable();
91
168
  /** @type {MutationObserver | undefined} */
92
169
 
93
- let observer;
94
-
95
- if (node.current) {
96
- observer = new window.MutationObserver(debouncedDisable);
97
- observer.observe(node.current, {
98
- childList: true,
99
- attributes: true,
100
- subtree: true
101
- });
102
- }
103
-
170
+ const observer = new window.MutationObserver(debouncedDisable);
171
+ observer.observe(node, {
172
+ childList: true,
173
+ attributes: true,
174
+ subtree: true
175
+ });
104
176
  return () => {
105
177
  if (observer) {
106
178
  observer.disconnect();
107
179
  }
108
180
 
109
181
  debouncedDisable.cancel();
182
+ updates.forEach(update => update());
110
183
  };
111
- }, []);
112
- return node;
184
+ }, [isDisabledProp]);
113
185
  }
114
186
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["@wordpress/compose/src/hooks/use-disabled/index.js"],"names":["DISABLED_ELIGIBLE_NODE_NAMES","useDisabled","node","disable","current","focus","focusable","find","forEach","nodeName","setAttribute","tabIndex","getAttribute","removeAttribute","hasAttribute","debouncedDisable","undefined","leading","observer","window","MutationObserver","observe","childList","attributes","subtree","disconnect","cancel"],"mappings":";;;;;;;AAGA;;AAKA;;AACA;;AATA;AACA;AACA;;AAGA;AACA;AACA;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMA,4BAA4B,GAAG,CACpC,QADoC,EAEpC,UAFoC,EAGpC,OAHoC,EAIpC,UAJoC,EAKpC,QALoC,EAMpC,QANoC,EAOpC,UAPoC,CAArC;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACe,SAASC,WAAT,GAAuB;AACrC;AACA,QAAMC,IAAI,GAAG,qBAAQ,IAAR,CAAb;;AAEA,QAAMC,OAAO,GAAG,MAAM;AACrB,QAAK,CAAED,IAAI,CAACE,OAAZ,EAAsB;AACrB;AACA;;AAEDC,eAAMC,SAAN,CAAgBC,IAAhB,CAAsBL,IAAI,CAACE,OAA3B,EAAqCI,OAArC,CAAgDF,SAAF,IAAiB;AAC9D,UACC,sBAAUN,4BAAV,EAAwCM,SAAS,CAACG,QAAlD,CADD,EAEE;AACDH,QAAAA,SAAS,CAACI,YAAV,CAAwB,UAAxB,EAAoC,EAApC;AACA;;AAED,UAAKJ,SAAS,CAACG,QAAV,KAAuB,GAA5B,EAAkC;AACjCH,QAAAA,SAAS,CAACI,YAAV,CAAwB,UAAxB,EAAoC,IAApC;AACA;;AAED,YAAMC,QAAQ,GAAGL,SAAS,CAACM,YAAV,CAAwB,UAAxB,CAAjB;;AACA,UAAKD,QAAQ,KAAK,IAAb,IAAqBA,QAAQ,KAAK,IAAvC,EAA8C;AAC7CL,QAAAA,SAAS,CAACO,eAAV,CAA2B,UAA3B;AACA;;AAED,UAAKP,SAAS,CAACQ,YAAV,CAAwB,iBAAxB,CAAL,EAAmD;AAClDR,QAAAA,SAAS,CAACI,YAAV,CAAwB,iBAAxB,EAA2C,OAA3C;AACA;AACD,KAnBD;AAoBA,GAzBD,CAJqC,CA+BrC;AACA;;;AACA,QAAMK,gBAAgB,GAAG,0BACxB,sBAAUZ,OAAV,EAAmBa,SAAnB,EAA8B;AAAEC,IAAAA,OAAO,EAAE;AAAX,GAA9B,CADwB,EAExB,EAFwB,CAAzB;AAKA,gCAAiB,MAAM;AACtBd,IAAAA,OAAO;AAEP;;AACA,QAAIe,QAAJ;;AACA,QAAKhB,IAAI,CAACE,OAAV,EAAoB;AACnBc,MAAAA,QAAQ,GAAG,IAAIC,MAAM,CAACC,gBAAX,CAA6BL,gBAA7B,CAAX;AACAG,MAAAA,QAAQ,CAACG,OAAT,CAAkBnB,IAAI,CAACE,OAAvB,EAAgC;AAC/BkB,QAAAA,SAAS,EAAE,IADoB;AAE/BC,QAAAA,UAAU,EAAE,IAFmB;AAG/BC,QAAAA,OAAO,EAAE;AAHsB,OAAhC;AAKA;;AAED,WAAO,MAAM;AACZ,UAAKN,QAAL,EAAgB;AACfA,QAAAA,QAAQ,CAACO,UAAT;AACA;;AACDV,MAAAA,gBAAgB,CAACW,MAAjB;AACA,KALD;AAMA,GApBD,EAoBG,EApBH;AAsBA,SAAOxB,IAAP;AACA","sourcesContent":["/**\n * External dependencies\n */\nimport { includes, debounce } from 'lodash';\n\n/**\n * WordPress dependencies\n */\nimport { useCallback, useLayoutEffect, useRef } from '@wordpress/element';\nimport { focus } from '@wordpress/dom';\n\n/**\n * Names of control nodes which qualify for disabled behavior.\n *\n * See WHATWG HTML Standard: 4.10.18.5: \"Enabling and disabling form controls: the disabled attribute\".\n *\n * @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#enabling-and-disabling-form-controls:-the-disabled-attribute\n *\n * @type {string[]}\n */\nconst DISABLED_ELIGIBLE_NODE_NAMES = [\n\t'BUTTON',\n\t'FIELDSET',\n\t'INPUT',\n\t'OPTGROUP',\n\t'OPTION',\n\t'SELECT',\n\t'TEXTAREA',\n];\n\n/**\n * In some circumstances, such as block previews, all focusable DOM elements\n * (input fields, links, buttons, etc.) need to be disabled. This hook adds the\n * behavior to disable nested DOM elements to the returned ref.\n *\n * @return {import('react').RefObject<HTMLElement>} Element Ref.\n *\n * @example\n * ```js\n * import { __experimentalUseDisabled as useDisabled } from '@wordpress/compose';\n * const DisabledExample = () => {\n * \tconst disabledRef = useDisabled();\n *\treturn (\n *\t\t<div ref={ disabledRef }>\n *\t\t\t<a href=\"#\">This link will have tabindex set to -1</a>\n *\t\t\t<input placeholder=\"This input will have the disabled attribute added to it.\" type=\"text\" />\n *\t\t</div>\n *\t);\n * };\n * ```\n */\nexport default function useDisabled() {\n\t/** @type {import('react').RefObject<HTMLElement>} */\n\tconst node = useRef( null );\n\n\tconst disable = () => {\n\t\tif ( ! node.current ) {\n\t\t\treturn;\n\t\t}\n\n\t\tfocus.focusable.find( node.current ).forEach( ( focusable ) => {\n\t\t\tif (\n\t\t\t\tincludes( DISABLED_ELIGIBLE_NODE_NAMES, focusable.nodeName )\n\t\t\t) {\n\t\t\t\tfocusable.setAttribute( 'disabled', '' );\n\t\t\t}\n\n\t\t\tif ( focusable.nodeName === 'A' ) {\n\t\t\t\tfocusable.setAttribute( 'tabindex', '-1' );\n\t\t\t}\n\n\t\t\tconst tabIndex = focusable.getAttribute( 'tabindex' );\n\t\t\tif ( tabIndex !== null && tabIndex !== '-1' ) {\n\t\t\t\tfocusable.removeAttribute( 'tabindex' );\n\t\t\t}\n\n\t\t\tif ( focusable.hasAttribute( 'contenteditable' ) ) {\n\t\t\t\tfocusable.setAttribute( 'contenteditable', 'false' );\n\t\t\t}\n\t\t} );\n\t};\n\n\t// Debounce re-disable since disabling process itself will incur\n\t// additional mutations which should be ignored.\n\tconst debouncedDisable = useCallback(\n\t\tdebounce( disable, undefined, { leading: true } ),\n\t\t[]\n\t);\n\n\tuseLayoutEffect( () => {\n\t\tdisable();\n\n\t\t/** @type {MutationObserver | undefined} */\n\t\tlet observer;\n\t\tif ( node.current ) {\n\t\t\tobserver = new window.MutationObserver( debouncedDisable );\n\t\t\tobserver.observe( node.current, {\n\t\t\t\tchildList: true,\n\t\t\t\tattributes: true,\n\t\t\t\tsubtree: true,\n\t\t\t} );\n\t\t}\n\n\t\treturn () => {\n\t\t\tif ( observer ) {\n\t\t\t\tobserver.disconnect();\n\t\t\t}\n\t\t\tdebouncedDisable.cancel();\n\t\t};\n\t}, [] );\n\n\treturn node;\n}\n"]}
1
+ {"version":3,"sources":["@wordpress/compose/src/hooks/use-disabled/index.js"],"names":["DISABLED_ELIGIBLE_NODE_NAMES","useDisabled","isDisabled","isDisabledProp","node","updates","disable","style","getPropertyValue","previousValue","setProperty","push","isConnected","focus","focusable","find","forEach","nodeName","disabled","setAttribute","getAttribute","removeAttribute","tabIndex","hasAttribute","ownerDocument","defaultView","HTMLElement","debouncedDisable","undefined","leading","observer","window","MutationObserver","observe","childList","attributes","subtree","disconnect","cancel","update"],"mappings":"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","sourcesContent":["/**\n * External dependencies\n */\nimport { includes, debounce } from 'lodash';\n\n/**\n * WordPress dependencies\n */\nimport { focus } from '@wordpress/dom';\n\n/**\n * Internal dependencies\n */\nimport useRefEffect from '../use-ref-effect';\n\n/**\n * Names of control nodes which qualify for disabled behavior.\n *\n * See WHATWG HTML Standard: 4.10.18.5: \"Enabling and disabling form controls: the disabled attribute\".\n *\n * @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#enabling-and-disabling-form-controls:-the-disabled-attribute\n *\n * @type {string[]}\n */\nconst DISABLED_ELIGIBLE_NODE_NAMES = [\n\t'BUTTON',\n\t'FIELDSET',\n\t'INPUT',\n\t'OPTGROUP',\n\t'OPTION',\n\t'SELECT',\n\t'TEXTAREA',\n];\n\n/**\n * In some circumstances, such as block previews, all focusable DOM elements\n * (input fields, links, buttons, etc.) need to be disabled. This hook adds the\n * behavior to disable nested DOM elements to the returned ref.\n *\n * @param {Object} config Configuration object.\n * @param {boolean=} config.isDisabled Whether the element should be disabled.\n * @return {import('react').RefCallback<HTMLElement>} Element Ref.\n *\n * @example\n * ```js\n * import { useDisabled } from '@wordpress/compose';\n * const DisabledExample = () => {\n * \tconst disabledRef = useDisabled();\n *\treturn (\n *\t\t<div ref={ disabledRef }>\n *\t\t\t<a href=\"#\">This link will have tabindex set to -1</a>\n *\t\t\t<input placeholder=\"This input will have the disabled attribute added to it.\" type=\"text\" />\n *\t\t</div>\n *\t);\n * };\n * ```\n */\nexport default function useDisabled( {\n\tisDisabled: isDisabledProp = false,\n} = {} ) {\n\treturn useRefEffect(\n\t\t( node ) => {\n\t\t\tif ( isDisabledProp ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t/** A variable keeping track of the previous updates in order to restore them. */\n\t\t\t/** @type {Function[]} */\n\t\t\tconst updates = [];\n\n\t\t\tconst disable = () => {\n\t\t\t\tif ( node.style.getPropertyValue( 'user-select' ) !== 'none' ) {\n\t\t\t\t\tconst previousValue = node.style.getPropertyValue(\n\t\t\t\t\t\t'user-select'\n\t\t\t\t\t);\n\t\t\t\t\tnode.style.setProperty( 'user-select', 'none' );\n\t\t\t\t\tnode.style.setProperty( '-webkit-user-select', 'none' );\n\t\t\t\t\tupdates.push( () => {\n\t\t\t\t\t\tif ( ! node.isConnected ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnode.style.setProperty( 'user-select', previousValue );\n\t\t\t\t\t\tnode.style.setProperty(\n\t\t\t\t\t\t\t'-webkit-user-select',\n\t\t\t\t\t\t\tpreviousValue\n\t\t\t\t\t\t);\n\t\t\t\t\t} );\n\t\t\t\t}\n\n\t\t\t\tfocus.focusable.find( node ).forEach( ( focusable ) => {\n\t\t\t\t\tif (\n\t\t\t\t\t\tincludes(\n\t\t\t\t\t\t\tDISABLED_ELIGIBLE_NODE_NAMES,\n\t\t\t\t\t\t\tfocusable.nodeName\n\t\t\t\t\t\t) &&\n\t\t\t\t\t\t// @ts-ignore\n\t\t\t\t\t\t! focusable.disabled\n\t\t\t\t\t) {\n\t\t\t\t\t\tfocusable.setAttribute( 'disabled', '' );\n\t\t\t\t\t\tupdates.push( () => {\n\t\t\t\t\t\t\tif ( ! focusable.isConnected ) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// @ts-ignore\n\t\t\t\t\t\t\tfocusable.disabled = false;\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\n\t\t\t\t\tif (\n\t\t\t\t\t\tfocusable.nodeName === 'A' &&\n\t\t\t\t\t\tfocusable.getAttribute( 'tabindex' ) !== '-1'\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst previousValue = focusable.getAttribute(\n\t\t\t\t\t\t\t'tabindex'\n\t\t\t\t\t\t);\n\t\t\t\t\t\tfocusable.setAttribute( 'tabindex', '-1' );\n\t\t\t\t\t\tupdates.push( () => {\n\t\t\t\t\t\t\tif ( ! focusable.isConnected ) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ( ! previousValue ) {\n\t\t\t\t\t\t\t\tfocusable.removeAttribute( 'tabindex' );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfocusable.setAttribute(\n\t\t\t\t\t\t\t\t\t'tabindex',\n\t\t\t\t\t\t\t\t\tpreviousValue\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\n\t\t\t\t\tconst tabIndex = focusable.getAttribute( 'tabindex' );\n\t\t\t\t\tif ( tabIndex !== null && tabIndex !== '-1' ) {\n\t\t\t\t\t\tfocusable.removeAttribute( 'tabindex' );\n\t\t\t\t\t\tupdates.push( () => {\n\t\t\t\t\t\t\tif ( ! focusable.isConnected ) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfocusable.setAttribute( 'tabindex', tabIndex );\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\n\t\t\t\t\tif (\n\t\t\t\t\t\tfocusable.hasAttribute( 'contenteditable' ) &&\n\t\t\t\t\t\tfocusable.getAttribute( 'contenteditable' ) !== 'false'\n\t\t\t\t\t) {\n\t\t\t\t\t\tfocusable.setAttribute( 'contenteditable', 'false' );\n\t\t\t\t\t\tupdates.push( () => {\n\t\t\t\t\t\t\tif ( ! focusable.isConnected ) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfocusable.setAttribute( 'contenteditable', 'true' );\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\n\t\t\t\t\tif (\n\t\t\t\t\t\tnode.ownerDocument.defaultView?.HTMLElement &&\n\t\t\t\t\t\tfocusable instanceof\n\t\t\t\t\t\t\tnode.ownerDocument.defaultView.HTMLElement\n\t\t\t\t\t) {\n\t\t\t\t\t\tconst previousValue = focusable.style.getPropertyValue(\n\t\t\t\t\t\t\t'pointer-events'\n\t\t\t\t\t\t);\n\t\t\t\t\t\tfocusable.style.setProperty( 'pointer-events', 'none' );\n\t\t\t\t\t\tupdates.push( () => {\n\t\t\t\t\t\t\tif ( ! focusable.isConnected ) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfocusable.style.setProperty(\n\t\t\t\t\t\t\t\t'pointer-events',\n\t\t\t\t\t\t\t\tpreviousValue\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t};\n\n\t\t\t// Debounce re-disable since disabling process itself will incur\n\t\t\t// additional mutations which should be ignored.\n\t\t\tconst debouncedDisable = debounce( disable, undefined, {\n\t\t\t\tleading: true,\n\t\t\t} );\n\t\t\tdisable();\n\n\t\t\t/** @type {MutationObserver | undefined} */\n\t\t\tconst observer = new window.MutationObserver( debouncedDisable );\n\t\t\tobserver.observe( node, {\n\t\t\t\tchildList: true,\n\t\t\t\tattributes: true,\n\t\t\t\tsubtree: true,\n\t\t\t} );\n\n\t\t\treturn () => {\n\t\t\t\tif ( observer ) {\n\t\t\t\t\tobserver.disconnect();\n\t\t\t\t}\n\t\t\t\tdebouncedDisable.cancel();\n\t\t\t\tupdates.forEach( ( update ) => update() );\n\t\t\t};\n\t\t},\n\t\t[ isDisabledProp ]\n\t);\n}\n"]}
@@ -63,7 +63,12 @@ function useFocusOnMount() {
63
63
  }
64
64
  }
65
65
 
66
- target.focus();
66
+ target.focus({
67
+ // When focusing newly mounted dialogs,
68
+ // the position of the popover is often not right on the first render
69
+ // This prevents the layout shifts when focusing the dialogs.
70
+ preventScroll: true
71
+ });
67
72
  }, []);
68
73
  }
69
74
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["@wordpress/compose/src/hooks/use-focus-on-mount/index.js"],"names":["useFocusOnMount","focusOnMount","focusOnMountRef","current","node","contains","ownerDocument","activeElement","target","firstTabbable","focus","tabbable","find"],"mappings":";;;;;;;AAGA;;AACA;;AAJA;AACA;AACA;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,SAASA,eAAT,GAA0D;AAAA,MAAhCC,YAAgC,uEAAjB,cAAiB;AACxE,QAAMC,eAAe,GAAG,qBAAQD,YAAR,CAAxB;AACA,0BAAW,MAAM;AAChBC,IAAAA,eAAe,CAACC,OAAhB,GAA0BF,YAA1B;AACA,GAFD,EAEG,CAAEA,YAAF,CAFH;AAIA,SAAO,0BAAeG,IAAF,IAAY;AAAA;;AAC/B,QAAK,CAAEA,IAAF,IAAUF,eAAe,CAACC,OAAhB,KAA4B,KAA3C,EAAmD;AAClD;AACA;;AAED,QAAKC,IAAI,CAACC,QAAL,iDAAeD,IAAI,CAACE,aAApB,wDAAe,oBAAoBC,aAAnC,yEAAoD,IAApD,CAAL,EAAkE;AACjE;AACA;;AAED,QAAIC,MAAM,GAAGJ,IAAb;;AAEA,QAAKF,eAAe,CAACC,OAAhB,KAA4B,cAAjC,EAAkD;AACjD,YAAMM,aAAa,GAAGC,WAAMC,QAAN,CAAeC,IAAf,CAAqBR,IAArB,EAA6B,CAA7B,CAAtB;;AAEA,UAAKK,aAAL,EAAqB;AACpBD,QAAAA,MAAM;AAAG;AAA6BC,QAAAA,aAAtC;AACA;AACD;;AAEDD,IAAAA,MAAM,CAACE,KAAP;AACA,GApBM,EAoBJ,EApBI,CAAP;AAqBA","sourcesContent":["/**\n * WordPress dependencies\n */\nimport { useRef, useEffect, useCallback } from '@wordpress/element';\nimport { focus } from '@wordpress/dom';\n\n/**\n * Hook used to focus the first tabbable element on mount.\n *\n * @param {boolean | 'firstElement'} focusOnMount Focus on mount mode.\n * @return {import('react').RefCallback<HTMLElement>} Ref callback.\n *\n * @example\n * ```js\n * import { useFocusOnMount } from '@wordpress/compose';\n *\n * const WithFocusOnMount = () => {\n * const ref = useFocusOnMount()\n * return (\n * <div ref={ ref }>\n * <Button />\n * <Button />\n * </div>\n * );\n * }\n * ```\n */\nexport default function useFocusOnMount( focusOnMount = 'firstElement' ) {\n\tconst focusOnMountRef = useRef( focusOnMount );\n\tuseEffect( () => {\n\t\tfocusOnMountRef.current = focusOnMount;\n\t}, [ focusOnMount ] );\n\n\treturn useCallback( ( node ) => {\n\t\tif ( ! node || focusOnMountRef.current === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( node.contains( node.ownerDocument?.activeElement ?? null ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet target = node;\n\n\t\tif ( focusOnMountRef.current === 'firstElement' ) {\n\t\t\tconst firstTabbable = focus.tabbable.find( node )[ 0 ];\n\n\t\t\tif ( firstTabbable ) {\n\t\t\t\ttarget = /** @type {HTMLElement} */ ( firstTabbable );\n\t\t\t}\n\t\t}\n\n\t\ttarget.focus();\n\t}, [] );\n}\n"]}
1
+ {"version":3,"sources":["@wordpress/compose/src/hooks/use-focus-on-mount/index.js"],"names":["useFocusOnMount","focusOnMount","focusOnMountRef","current","node","contains","ownerDocument","activeElement","target","firstTabbable","focus","tabbable","find","preventScroll"],"mappings":";;;;;;;AAGA;;AACA;;AAJA;AACA;AACA;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,SAASA,eAAT,GAA0D;AAAA,MAAhCC,YAAgC,uEAAjB,cAAiB;AACxE,QAAMC,eAAe,GAAG,qBAAQD,YAAR,CAAxB;AACA,0BAAW,MAAM;AAChBC,IAAAA,eAAe,CAACC,OAAhB,GAA0BF,YAA1B;AACA,GAFD,EAEG,CAAEA,YAAF,CAFH;AAIA,SAAO,0BAAeG,IAAF,IAAY;AAAA;;AAC/B,QAAK,CAAEA,IAAF,IAAUF,eAAe,CAACC,OAAhB,KAA4B,KAA3C,EAAmD;AAClD;AACA;;AAED,QAAKC,IAAI,CAACC,QAAL,iDAAeD,IAAI,CAACE,aAApB,wDAAe,oBAAoBC,aAAnC,yEAAoD,IAApD,CAAL,EAAkE;AACjE;AACA;;AAED,QAAIC,MAAM,GAAGJ,IAAb;;AAEA,QAAKF,eAAe,CAACC,OAAhB,KAA4B,cAAjC,EAAkD;AACjD,YAAMM,aAAa,GAAGC,WAAMC,QAAN,CAAeC,IAAf,CAAqBR,IAArB,EAA6B,CAA7B,CAAtB;;AAEA,UAAKK,aAAL,EAAqB;AACpBD,QAAAA,MAAM;AAAG;AAA6BC,QAAAA,aAAtC;AACA;AACD;;AAEDD,IAAAA,MAAM,CAACE,KAAP,CAAc;AACb;AACA;AACA;AACAG,MAAAA,aAAa,EAAE;AAJF,KAAd;AAMA,GAzBM,EAyBJ,EAzBI,CAAP;AA0BA","sourcesContent":["/**\n * WordPress dependencies\n */\nimport { useRef, useEffect, useCallback } from '@wordpress/element';\nimport { focus } from '@wordpress/dom';\n\n/**\n * Hook used to focus the first tabbable element on mount.\n *\n * @param {boolean | 'firstElement'} focusOnMount Focus on mount mode.\n * @return {import('react').RefCallback<HTMLElement>} Ref callback.\n *\n * @example\n * ```js\n * import { useFocusOnMount } from '@wordpress/compose';\n *\n * const WithFocusOnMount = () => {\n * const ref = useFocusOnMount()\n * return (\n * <div ref={ ref }>\n * <Button />\n * <Button />\n * </div>\n * );\n * }\n * ```\n */\nexport default function useFocusOnMount( focusOnMount = 'firstElement' ) {\n\tconst focusOnMountRef = useRef( focusOnMount );\n\tuseEffect( () => {\n\t\tfocusOnMountRef.current = focusOnMount;\n\t}, [ focusOnMount ] );\n\n\treturn useCallback( ( node ) => {\n\t\tif ( ! node || focusOnMountRef.current === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( node.contains( node.ownerDocument?.activeElement ?? null ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tlet target = node;\n\n\t\tif ( focusOnMountRef.current === 'firstElement' ) {\n\t\t\tconst firstTabbable = focus.tabbable.find( node )[ 0 ];\n\n\t\t\tif ( firstTabbable ) {\n\t\t\t\ttarget = /** @type {HTMLElement} */ ( firstTabbable );\n\t\t\t}\n\t\t}\n\n\t\ttarget.focus( {\n\t\t\t// When focusing newly mounted dialogs,\n\t\t\t// the position of the popover is often not right on the first render\n\t\t\t// This prevents the layout shifts when focusing the dialogs.\n\t\t\tpreventScroll: true,\n\t\t} );\n\t}, [] );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["@wordpress/compose/src/hooks/use-ref-effect/index.ts"],"names":["useRefEffect","callback","dependencies","cleanup","node","current"],"mappings":";;;;;;;AAQA;;AARA;AACA;AACA;;AAGA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,SAASA,YAAT,CACdC,QADc,EAEdC,YAFc,EAGmB;AACjC,QAAMC,OAAO,GAAG,sBAAhB;AACA,SAAO,0BAAeC,IAAF,IAA6B;AAChD,QAAKA,IAAL,EAAY;AACXD,MAAAA,OAAO,CAACE,OAAR,GAAkBJ,QAAQ,CAAEG,IAAF,CAA1B;AACA,KAFD,MAEO,IAAKD,OAAO,CAACE,OAAb,EAAuB;AAC7BF,MAAAA,OAAO,CAACE,OAAR;AACA;AACD,GANM,EAMJH,YANI,CAAP;AAOA","sourcesContent":["/**\n * External dependencies\n */\nimport type { DependencyList, RefCallback } from 'react';\n\n/**\n * WordPress dependencies\n */\nimport { useCallback, useRef } from '@wordpress/element';\n\n/**\n * Effect-like ref callback. Just like with `useEffect`, this allows you to\n * return a cleanup function to be run if the ref changes or one of the\n * dependencies changes. The ref is provided as an argument to the callback\n * functions. The main difference between this and `useEffect` is that\n * the `useEffect` callback is not called when the ref changes, but this is.\n * Pass the returned ref callback as the component's ref and merge multiple refs\n * with `useMergeRefs`.\n *\n * It's worth noting that if the dependencies array is empty, there's not\n * strictly a need to clean up event handlers for example, because the node is\n * to be removed. It *is* necessary if you add dependencies because the ref\n * callback will be called multiple times for the same node.\n *\n * @param callback Callback with ref as argument.\n * @param dependencies Dependencies of the callback.\n *\n * @return Ref callback.\n */\nexport default function useRefEffect< TElement = Node >(\n\tcallback: ( node: TElement ) => ( () => void ) | undefined,\n\tdependencies: DependencyList\n): RefCallback< TElement | null > {\n\tconst cleanup = useRef< ( () => void ) | undefined >();\n\treturn useCallback( ( node: TElement | null ) => {\n\t\tif ( node ) {\n\t\t\tcleanup.current = callback( node );\n\t\t} else if ( cleanup.current ) {\n\t\t\tcleanup.current();\n\t\t}\n\t}, dependencies );\n}\n"]}
1
+ {"version":3,"sources":["@wordpress/compose/src/hooks/use-ref-effect/index.ts"],"names":["useRefEffect","callback","dependencies","cleanup","node","current"],"mappings":";;;;;;;AAQA;;AARA;AACA;AACA;;AAGA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACe,SAASA,YAAT,CACdC,QADc,EAEdC,YAFc,EAGmB;AACjC,QAAMC,OAAO,GAAG,sBAAhB;AACA,SAAO,0BAAeC,IAAF,IAA6B;AAChD,QAAKA,IAAL,EAAY;AACXD,MAAAA,OAAO,CAACE,OAAR,GAAkBJ,QAAQ,CAAEG,IAAF,CAA1B;AACA,KAFD,MAEO,IAAKD,OAAO,CAACE,OAAb,EAAuB;AAC7BF,MAAAA,OAAO,CAACE,OAAR;AACA;AACD,GANM,EAMJH,YANI,CAAP;AAOA","sourcesContent":["/**\n * External dependencies\n */\nimport type { DependencyList, RefCallback } from 'react';\n\n/**\n * WordPress dependencies\n */\nimport { useCallback, useRef } from '@wordpress/element';\n\n/**\n * Effect-like ref callback. Just like with `useEffect`, this allows you to\n * return a cleanup function to be run if the ref changes or one of the\n * dependencies changes. The ref is provided as an argument to the callback\n * functions. The main difference between this and `useEffect` is that\n * the `useEffect` callback is not called when the ref changes, but this is.\n * Pass the returned ref callback as the component's ref and merge multiple refs\n * with `useMergeRefs`.\n *\n * It's worth noting that if the dependencies array is empty, there's not\n * strictly a need to clean up event handlers for example, because the node is\n * to be removed. It *is* necessary if you add dependencies because the ref\n * callback will be called multiple times for the same node.\n *\n * @param callback Callback with ref as argument.\n * @param dependencies Dependencies of the callback.\n *\n * @return Ref callback.\n */\nexport default function useRefEffect< TElement = Node >(\n\tcallback: ( node: TElement ) => ( () => void ) | void,\n\tdependencies: DependencyList\n): RefCallback< TElement | null > {\n\tconst cleanup = useRef< ( () => void ) | void >();\n\treturn useCallback( ( node: TElement | null ) => {\n\t\tif ( node ) {\n\t\t\tcleanup.current = callback( node );\n\t\t} else if ( cleanup.current ) {\n\t\t\tcleanup.current();\n\t\t}\n\t}, dependencies );\n}\n"]}