@wordpress/compose 7.32.0 → 7.32.1-next.47f435fc9.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/build/higher-order/compose.js +25 -20
- package/build/higher-order/compose.js.map +7 -1
- package/build/higher-order/if-condition/index.js +35 -41
- package/build/higher-order/if-condition/index.js.map +7 -1
- package/build/higher-order/pipe.js +32 -66
- package/build/higher-order/pipe.js.map +7 -1
- package/build/higher-order/pure/index.js +44 -37
- package/build/higher-order/pure/index.js.map +7 -1
- package/build/higher-order/with-global-events/index.js +64 -73
- package/build/higher-order/with-global-events/index.js.map +7 -1
- package/build/higher-order/with-global-events/listener.js +34 -21
- package/build/higher-order/with-global-events/listener.js.map +7 -1
- package/build/higher-order/with-instance-id/index.js +45 -27
- package/build/higher-order/with-instance-id/index.js.map +7 -1
- package/build/higher-order/with-safe-timeout/index.js +70 -66
- package/build/higher-order/with-safe-timeout/index.js.map +7 -1
- package/build/higher-order/with-state/index.js +52 -40
- package/build/higher-order/with-state/index.js.map +7 -1
- package/build/hooks/use-async-list/index.js +38 -42
- package/build/hooks/use-async-list/index.js.map +7 -1
- package/build/hooks/use-constrained-tabbing/index.js +54 -75
- package/build/hooks/use-constrained-tabbing/index.js.map +7 -1
- package/build/hooks/use-copy-on-click/index.js +46 -56
- package/build/hooks/use-copy-on-click/index.js.map +7 -1
- package/build/hooks/use-copy-to-clipboard/index.js +41 -51
- package/build/hooks/use-copy-to-clipboard/index.js.map +7 -1
- package/build/hooks/use-debounce/index.js +30 -37
- package/build/hooks/use-debounce/index.js.map +7 -1
- package/build/hooks/use-debounced-input/index.js +39 -27
- package/build/hooks/use-debounced-input/index.js.map +7 -1
- package/build/hooks/use-dialog/index.js +63 -55
- package/build/hooks/use-dialog/index.js.map +7 -1
- package/build/hooks/use-disabled/index.js +74 -82
- package/build/hooks/use-disabled/index.js.map +7 -1
- package/build/hooks/use-dragging/index.js +51 -48
- package/build/hooks/use-dragging/index.js.map +7 -1
- package/build/hooks/use-drop-zone/index.js +133 -168
- package/build/hooks/use-drop-zone/index.js.map +7 -1
- package/build/hooks/use-event/index.js +33 -45
- package/build/hooks/use-event/index.js.map +7 -1
- package/build/hooks/use-fixed-window-list/index.js +109 -97
- package/build/hooks/use-fixed-window-list/index.js.map +7 -1
- package/build/hooks/use-focus-on-mount/index.js +44 -57
- package/build/hooks/use-focus-on-mount/index.js.map +7 -1
- package/build/hooks/use-focus-outside/index.js +44 -102
- package/build/hooks/use-focus-outside/index.js.map +7 -1
- package/build/hooks/use-focus-return/index.js +35 -56
- package/build/hooks/use-focus-return/index.js.map +7 -1
- package/build/hooks/use-focusable-iframe/index.js +38 -35
- package/build/hooks/use-focusable-iframe/index.js.map +7 -1
- package/build/hooks/use-instance-id/index.js +26 -42
- package/build/hooks/use-instance-id/index.js.map +7 -1
- package/build/hooks/use-isomorphic-layout-effect/index.js +25 -17
- package/build/hooks/use-isomorphic-layout-effect/index.js.map +7 -1
- package/build/hooks/use-keyboard-shortcut/index.js +72 -69
- package/build/hooks/use-keyboard-shortcut/index.js.map +7 -1
- package/build/hooks/use-media-query/index.js +39 -35
- package/build/hooks/use-media-query/index.js.map +7 -1
- package/build/hooks/use-merge-refs/index.js +34 -102
- package/build/hooks/use-merge-refs/index.js.map +7 -1
- package/build/hooks/use-observable-value/index.js +31 -28
- package/build/hooks/use-observable-value/index.js.map +7 -1
- package/build/hooks/use-preferred-color-scheme/index.android.js +31 -23
- package/build/hooks/use-preferred-color-scheme/index.android.js.map +7 -1
- package/build/hooks/use-preferred-color-scheme/index.ios.js +25 -17
- package/build/hooks/use-preferred-color-scheme/index.ios.js.map +7 -1
- package/build/hooks/use-previous/index.js +26 -25
- package/build/hooks/use-previous/index.js.map +7 -1
- package/build/hooks/use-reduced-motion/index.js +35 -18
- package/build/hooks/use-reduced-motion/index.js.map +7 -1
- package/build/hooks/use-ref-effect/index.js +25 -35
- package/build/hooks/use-ref-effect/index.js.map +7 -1
- package/build/hooks/use-resize-observer/index.js +35 -67
- package/build/hooks/use-resize-observer/index.js.map +7 -1
- package/build/hooks/use-resize-observer/legacy/index.js +47 -103
- package/build/hooks/use-resize-observer/legacy/index.js.map +7 -1
- package/build/hooks/use-resize-observer/use-resize-observer.js +44 -36
- package/build/hooks/use-resize-observer/use-resize-observer.js.map +7 -1
- package/build/hooks/use-state-with-history/index.js +68 -63
- package/build/hooks/use-state-with-history/index.js.map +7 -1
- package/build/hooks/use-throttle/index.js +30 -37
- package/build/hooks/use-throttle/index.js.map +7 -1
- package/build/hooks/use-viewport-match/index.js +51 -70
- package/build/hooks/use-viewport-match/index.js.map +7 -1
- package/build/hooks/use-warn-on-change/index.js +50 -40
- package/build/hooks/use-warn-on-change/index.js.map +7 -1
- package/build/index.js +156 -358
- package/build/index.js.map +7 -1
- package/build/utils/create-higher-order-component/index.js +30 -34
- package/build/utils/create-higher-order-component/index.js.map +7 -1
- package/build/utils/debounce/index.js +38 -99
- package/build/utils/debounce/index.js.map +7 -1
- package/build/utils/observable-map/index.js +29 -19
- package/build/utils/observable-map/index.js.map +7 -1
- package/build/utils/throttle/index.js +30 -81
- package/build/utils/throttle/index.js.map +7 -1
- package/build-module/higher-order/compose.js +6 -15
- package/build-module/higher-order/compose.js.map +7 -1
- package/build-module/higher-order/if-condition/index.js +16 -37
- package/build-module/higher-order/if-condition/index.js.map +7 -1
- package/build-module/higher-order/pipe.js +10 -62
- package/build-module/higher-order/pipe.js.map +7 -1
- package/build-module/higher-order/pure/index.js +12 -29
- package/build-module/higher-order/pure/index.js.map +7 -1
- package/build-module/higher-order/with-global-events/index.js +34 -67
- package/build-module/higher-order/with-global-events/index.js.map +7 -1
- package/build-module/higher-order/with-global-events/listener.js +16 -17
- package/build-module/higher-order/with-global-events/listener.js.map +7 -1
- package/build-module/higher-order/with-instance-id/index.js +17 -22
- package/build-module/higher-order/with-instance-id/index.js.map +7 -1
- package/build-module/higher-order/with-safe-timeout/index.js +52 -62
- package/build-module/higher-order/with-safe-timeout/index.js.map +7 -1
- package/build-module/higher-order/with-state/index.js +23 -35
- package/build-module/higher-order/with-state/index.js.map +7 -1
- package/build-module/hooks/use-async-list/index.js +16 -33
- package/build-module/hooks/use-async-list/index.js.map +7 -1
- package/build-module/hooks/use-constrained-tabbing/index.js +26 -70
- package/build-module/hooks/use-constrained-tabbing/index.js.map +7 -1
- package/build-module/hooks/use-copy-on-click/index.js +14 -47
- package/build-module/hooks/use-copy-on-click/index.js.map +7 -1
- package/build-module/hooks/use-copy-to-clipboard/index.js +11 -44
- package/build-module/hooks/use-copy-to-clipboard/index.js.map +7 -1
- package/build-module/hooks/use-debounce/index.js +12 -33
- package/build-module/hooks/use-debounce/index.js.map +7 -1
- package/build-module/hooks/use-debounced-input/index.js +7 -18
- package/build-module/hooks/use-debounced-input/index.js.map +7 -1
- package/build-module/hooks/use-dialog/index.js +29 -43
- package/build-module/hooks/use-dialog/index.js.map +7 -1
- package/build-module/hooks/use-disabled/index.js +47 -78
- package/build-module/hooks/use-disabled/index.js.map +7 -1
- package/build-module/hooks/use-dragging/index.js +19 -39
- package/build-module/hooks/use-dragging/index.js.map +7 -1
- package/build-module/hooks/use-drop-zone/index.js +100 -158
- package/build-module/hooks/use-drop-zone/index.js.map +7 -1
- package/build-module/hooks/use-event/index.js +13 -39
- package/build-module/hooks/use-event/index.js.map +7 -1
- package/build-module/hooks/use-fixed-window-list/index.js +86 -87
- package/build-module/hooks/use-fixed-window-list/index.js.map +7 -1
- package/build-module/hooks/use-focus-on-mount/index.js +12 -48
- package/build-module/hooks/use-focus-on-mount/index.js.map +7 -1
- package/build-module/hooks/use-focus-outside/index.js +21 -93
- package/build-module/hooks/use-focus-outside/index.js.map +7 -1
- package/build-module/hooks/use-focus-return/index.js +13 -48
- package/build-module/hooks/use-focus-return/index.js.map +7 -1
- package/build-module/hooks/use-focusable-iframe/index.js +11 -31
- package/build-module/hooks/use-focusable-iframe/index.js.map +7 -1
- package/build-module/hooks/use-instance-id/index.js +7 -36
- package/build-module/hooks/use-instance-id/index.js.map +7 -1
- package/build-module/hooks/use-isomorphic-layout-effect/index.js +7 -13
- package/build-module/hooks/use-isomorphic-layout-effect/index.js.map +7 -1
- package/build-module/hooks/use-keyboard-shortcut/index.js +40 -60
- package/build-module/hooks/use-keyboard-shortcut/index.js.map +7 -1
- package/build-module/hooks/use-media-query/index.js +21 -30
- package/build-module/hooks/use-media-query/index.js.map +7 -1
- package/build-module/hooks/use-merge-refs/index.js +10 -92
- package/build-module/hooks/use-merge-refs/index.js.map +7 -1
- package/build-module/hooks/use-observable-value/index.js +13 -24
- package/build-module/hooks/use-observable-value/index.js.map +7 -1
- package/build-module/hooks/use-preferred-color-scheme/index.android.js +15 -18
- package/build-module/hooks/use-preferred-color-scheme/index.android.js.map +7 -1
- package/build-module/hooks/use-preferred-color-scheme/index.ios.js +6 -12
- package/build-module/hooks/use-preferred-color-scheme/index.ios.js.map +7 -1
- package/build-module/hooks/use-previous/index.js +7 -20
- package/build-module/hooks/use-previous/index.js.map +7 -1
- package/build-module/hooks/use-reduced-motion/index.js +7 -13
- package/build-module/hooks/use-reduced-motion/index.js.map +7 -1
- package/build-module/hooks/use-ref-effect/index.js +7 -31
- package/build-module/hooks/use-ref-effect/index.js.map +7 -1
- package/build-module/hooks/use-resize-observer/index.js +7 -61
- package/build-module/hooks/use-resize-observer/index.js.map +7 -1
- package/build-module/hooks/use-resize-observer/legacy/index.js +28 -96
- package/build-module/hooks/use-resize-observer/legacy/index.js.map +7 -1
- package/build-module/hooks/use-resize-observer/use-resize-observer.js +10 -28
- package/build-module/hooks/use-resize-observer/use-resize-observer.js.map +7 -1
- package/build-module/hooks/use-state-with-history/index.js +47 -55
- package/build-module/hooks/use-state-with-history/index.js.map +7 -1
- package/build-module/hooks/use-throttle/index.js +12 -33
- package/build-module/hooks/use-throttle/index.js.map +7 -1
- package/build-module/hooks/use-viewport-match/index.js +22 -64
- package/build-module/hooks/use-viewport-match/index.js.map +7 -1
- package/build-module/hooks/use-warn-on-change/index.js +21 -34
- package/build-module/hooks/use-warn-on-change/index.js.map +7 -1
- package/build-module/index.js +83 -53
- package/build-module/index.js.map +7 -1
- package/build-module/utils/create-higher-order-component/index.js +9 -30
- package/build-module/utils/create-higher-order-component/index.js.map +7 -1
- package/build-module/utils/debounce/index.js +17 -95
- package/build-module/utils/debounce/index.js.map +7 -1
- package/build-module/utils/observable-map/index.js +8 -16
- package/build-module/utils/observable-map/index.js.map +7 -1
- package/build-module/utils/throttle/index.js +8 -75
- package/build-module/utils/throttle/index.js.map +7 -1
- package/package.json +17 -10
- package/src/hooks/use-debounce/index.js +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/build/higher-order/with-network-connectivity/index.native.js +0 -27
- package/build/higher-order/with-network-connectivity/index.native.js.map +0 -1
- package/build/higher-order/with-preferred-color-scheme/index.native.js +0 -37
- package/build/higher-order/with-preferred-color-scheme/index.native.js.map +0 -1
- package/build/hooks/use-constrained-tabbing/index.native.js +0 -20
- package/build/hooks/use-constrained-tabbing/index.native.js.map +0 -1
- package/build/hooks/use-focus-outside/index.native.js +0 -175
- package/build/hooks/use-focus-outside/index.native.js.map +0 -1
- package/build/hooks/use-keyboard-shortcut/index.native.js +0 -9
- package/build/hooks/use-keyboard-shortcut/index.native.js.map +0 -1
- package/build/hooks/use-network-connectivity/index.native.js +0 -58
- package/build/hooks/use-network-connectivity/index.native.js.map +0 -1
- package/build/hooks/use-preferred-color-scheme-style/index.native.js +0 -42
- package/build/hooks/use-preferred-color-scheme-style/index.native.js.map +0 -1
- package/build/hooks/use-resize-observer/index.native.js +0 -14
- package/build/hooks/use-resize-observer/index.native.js.map +0 -1
- package/build/hooks/use-resize-observer/legacy/index.native.js +0 -62
- package/build/hooks/use-resize-observer/legacy/index.native.js.map +0 -1
- package/build/index.native.js +0 -297
- package/build/index.native.js.map +0 -1
- package/build-module/higher-order/with-network-connectivity/index.native.js +0 -19
- package/build-module/higher-order/with-network-connectivity/index.native.js.map +0 -1
- package/build-module/higher-order/with-preferred-color-scheme/index.native.js +0 -29
- package/build-module/higher-order/with-preferred-color-scheme/index.native.js.map +0 -1
- package/build-module/hooks/use-constrained-tabbing/index.native.js +0 -13
- package/build-module/hooks/use-constrained-tabbing/index.native.js.map +0 -1
- package/build-module/hooks/use-focus-outside/index.native.js +0 -169
- package/build-module/hooks/use-focus-outside/index.native.js.map +0 -1
- package/build-module/hooks/use-keyboard-shortcut/index.native.js +0 -3
- package/build-module/hooks/use-keyboard-shortcut/index.native.js.map +0 -1
- package/build-module/hooks/use-network-connectivity/index.native.js +0 -52
- package/build-module/hooks/use-network-connectivity/index.native.js.map +0 -1
- package/build-module/hooks/use-preferred-color-scheme-style/index.native.js +0 -35
- package/build-module/hooks/use-preferred-color-scheme-style/index.native.js.map +0 -1
- package/build-module/hooks/use-resize-observer/index.native.js +0 -2
- package/build-module/hooks/use-resize-observer/index.native.js.map +0 -1
- package/build-module/hooks/use-resize-observer/legacy/index.native.js +0 -56
- package/build-module/hooks/use-resize-observer/legacy/index.native.js.map +0 -1
- package/build-module/index.native.js +0 -45
- package/build-module/index.native.js.map +0 -1
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{"version":3,"names":["useState","useLayoutEffect","getScrollContainer","PAGEUP","PAGEDOWN","HOME","END","debounce","DEFAULT_INIT_WINDOW_SIZE","useFixedWindowList","elementRef","itemHeight","totalItems","options","_options$initWindowSi","_options$useWindowing","initWindowSize","useWindowing","fixedListWindow","setFixedListWindow","visibleItems","start","end","itemInView","index","scrollContainer","current","measureWindow","initRender","_options$windowOversc","Math","ceil","clientHeight","windowOverscan","firstViewableIndex","floor","scrollTop","max","min","lastWindow","nextWindow","debounceMeasureList","addEventListener","ownerDocument","defaultView","removeEventListener","expandedState","handleKeyDown","event","keyCode","scrollTo","top"],"sources":["@wordpress/compose/src/hooks/use-fixed-window-list/index.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { useState, useLayoutEffect } from '@wordpress/element';\nimport { getScrollContainer } from '@wordpress/dom';\nimport { PAGEUP, PAGEDOWN, HOME, END } from '@wordpress/keycodes';\n\n/**\n * Internal dependencies\n */\nimport { debounce } from '../../utils/debounce';\n\nconst DEFAULT_INIT_WINDOW_SIZE = 30;\n\n/**\n * @typedef {Object} WPFixedWindowList\n *\n * @property {number} visibleItems Items visible in the current viewport\n * @property {number} start Start index of the window\n * @property {number} end End index of the window\n * @property {(index:number)=>boolean} itemInView Returns true if item is in the window\n */\n\n/**\n * @typedef {Object} WPFixedWindowListOptions\n *\n * @property {number} [windowOverscan] Renders windowOverscan number of items before and after the calculated visible window.\n * @property {boolean} [useWindowing] When false avoids calculating the window size\n * @property {number} [initWindowSize] Initial window size to use on first render before we can calculate the window size.\n * @property {any} [expandedState] Used to recalculate the window size when the expanded state of a list changes.\n */\n\n/**\n *\n * @param {import('react').RefObject<HTMLElement>} elementRef Used to find the closest scroll container that contains element.\n * @param { number } itemHeight Fixed item height in pixels\n * @param { number } totalItems Total items in list\n * @param { WPFixedWindowListOptions } [options] Options object\n * @return {[ WPFixedWindowList, setFixedListWindow:(nextWindow:WPFixedWindowList)=>void]} Array with the fixed window list and setter\n */\nexport default function useFixedWindowList(\n\telementRef,\n\titemHeight,\n\ttotalItems,\n\toptions\n) {\n\tconst initWindowSize = options?.initWindowSize ?? DEFAULT_INIT_WINDOW_SIZE;\n\tconst useWindowing = options?.useWindowing ?? true;\n\n\tconst [ fixedListWindow, setFixedListWindow ] = useState( {\n\t\tvisibleItems: initWindowSize,\n\t\tstart: 0,\n\t\tend: initWindowSize,\n\t\titemInView: ( /** @type {number} */ index ) => {\n\t\t\treturn index >= 0 && index <= initWindowSize;\n\t\t},\n\t} );\n\n\tuseLayoutEffect( () => {\n\t\tif ( ! useWindowing ) {\n\t\t\treturn;\n\t\t}\n\t\tconst scrollContainer = getScrollContainer( elementRef.current );\n\t\tconst measureWindow = (\n\t\t\t/** @type {boolean | undefined} */ initRender\n\t\t) => {\n\t\t\tif ( ! scrollContainer ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst visibleItems = Math.ceil(\n\t\t\t\tscrollContainer.clientHeight / itemHeight\n\t\t\t);\n\t\t\t// Aim to keep opening list view fast, afterward we can optimize for scrolling.\n\t\t\tconst windowOverscan = initRender\n\t\t\t\t? visibleItems\n\t\t\t\t: options?.windowOverscan ?? visibleItems;\n\t\t\tconst firstViewableIndex = Math.floor(\n\t\t\t\tscrollContainer.scrollTop / itemHeight\n\t\t\t);\n\t\t\tconst start = Math.max( 0, firstViewableIndex - windowOverscan );\n\t\t\tconst end = Math.min(\n\t\t\t\ttotalItems - 1,\n\t\t\t\tfirstViewableIndex + visibleItems + windowOverscan\n\t\t\t);\n\t\t\tsetFixedListWindow( ( lastWindow ) => {\n\t\t\t\tconst nextWindow = {\n\t\t\t\t\tvisibleItems,\n\t\t\t\t\tstart,\n\t\t\t\t\tend,\n\t\t\t\t\titemInView: ( /** @type {number} */ index ) => {\n\t\t\t\t\t\treturn start <= index && index <= end;\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\tif (\n\t\t\t\t\tlastWindow.start !== nextWindow.start ||\n\t\t\t\t\tlastWindow.end !== nextWindow.end ||\n\t\t\t\t\tlastWindow.visibleItems !== nextWindow.visibleItems\n\t\t\t\t) {\n\t\t\t\t\treturn nextWindow;\n\t\t\t\t}\n\t\t\t\treturn lastWindow;\n\t\t\t} );\n\t\t};\n\n\t\tmeasureWindow( true );\n\t\tconst debounceMeasureList = debounce( () => {\n\t\t\tmeasureWindow();\n\t\t}, 16 );\n\t\tscrollContainer?.addEventListener( 'scroll', debounceMeasureList );\n\t\tscrollContainer?.ownerDocument?.defaultView?.addEventListener(\n\t\t\t'resize',\n\t\t\tdebounceMeasureList\n\t\t);\n\t\tscrollContainer?.ownerDocument?.defaultView?.addEventListener(\n\t\t\t'resize',\n\t\t\tdebounceMeasureList\n\t\t);\n\n\t\treturn () => {\n\t\t\tscrollContainer?.removeEventListener(\n\t\t\t\t'scroll',\n\t\t\t\tdebounceMeasureList\n\t\t\t);\n\t\t\tscrollContainer?.ownerDocument?.defaultView?.removeEventListener(\n\t\t\t\t'resize',\n\t\t\t\tdebounceMeasureList\n\t\t\t);\n\t\t};\n\t}, [\n\t\titemHeight,\n\t\telementRef,\n\t\ttotalItems,\n\t\toptions?.expandedState,\n\t\toptions?.windowOverscan,\n\t\tuseWindowing,\n\t] );\n\n\tuseLayoutEffect( () => {\n\t\tif ( ! useWindowing ) {\n\t\t\treturn;\n\t\t}\n\t\tconst scrollContainer = getScrollContainer( elementRef.current );\n\t\tconst handleKeyDown = ( /** @type {KeyboardEvent} */ event ) => {\n\t\t\tswitch ( event.keyCode ) {\n\t\t\t\tcase HOME: {\n\t\t\t\t\treturn scrollContainer?.scrollTo( { top: 0 } );\n\t\t\t\t}\n\t\t\t\tcase END: {\n\t\t\t\t\treturn scrollContainer?.scrollTo( {\n\t\t\t\t\t\ttop: totalItems * itemHeight,\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t\tcase PAGEUP: {\n\t\t\t\t\treturn scrollContainer?.scrollTo( {\n\t\t\t\t\t\ttop:\n\t\t\t\t\t\t\tscrollContainer.scrollTop -\n\t\t\t\t\t\t\tfixedListWindow.visibleItems * itemHeight,\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t\tcase PAGEDOWN: {\n\t\t\t\t\treturn scrollContainer?.scrollTo( {\n\t\t\t\t\t\ttop:\n\t\t\t\t\t\t\tscrollContainer.scrollTop +\n\t\t\t\t\t\t\tfixedListWindow.visibleItems * itemHeight,\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tscrollContainer?.ownerDocument?.defaultView?.addEventListener(\n\t\t\t'keydown',\n\t\t\thandleKeyDown\n\t\t);\n\t\treturn () => {\n\t\t\tscrollContainer?.ownerDocument?.defaultView?.removeEventListener(\n\t\t\t\t'keydown',\n\t\t\t\thandleKeyDown\n\t\t\t);\n\t\t};\n\t}, [\n\t\ttotalItems,\n\t\titemHeight,\n\t\telementRef,\n\t\tfixedListWindow.visibleItems,\n\t\tuseWindowing,\n\t\toptions?.expandedState,\n\t] );\n\n\treturn [ fixedListWindow, setFixedListWindow ];\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/hooks/use-fixed-window-list/index.js"],
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useState, useLayoutEffect } from '@wordpress/element';\nimport { getScrollContainer } from '@wordpress/dom';\nimport { PAGEUP, PAGEDOWN, HOME, END } from '@wordpress/keycodes';\n\n/**\n * Internal dependencies\n */\nimport { debounce } from '../../utils/debounce';\n\nconst DEFAULT_INIT_WINDOW_SIZE = 30;\n\n/**\n * @typedef {Object} WPFixedWindowList\n *\n * @property {number} visibleItems Items visible in the current viewport\n * @property {number} start Start index of the window\n * @property {number} end End index of the window\n * @property {(index:number)=>boolean} itemInView Returns true if item is in the window\n */\n\n/**\n * @typedef {Object} WPFixedWindowListOptions\n *\n * @property {number} [windowOverscan] Renders windowOverscan number of items before and after the calculated visible window.\n * @property {boolean} [useWindowing] When false avoids calculating the window size\n * @property {number} [initWindowSize] Initial window size to use on first render before we can calculate the window size.\n * @property {any} [expandedState] Used to recalculate the window size when the expanded state of a list changes.\n */\n\n/**\n *\n * @param {import('react').RefObject<HTMLElement>} elementRef Used to find the closest scroll container that contains element.\n * @param { number } itemHeight Fixed item height in pixels\n * @param { number } totalItems Total items in list\n * @param { WPFixedWindowListOptions } [options] Options object\n * @return {[ WPFixedWindowList, setFixedListWindow:(nextWindow:WPFixedWindowList)=>void]} Array with the fixed window list and setter\n */\nexport default function useFixedWindowList(\n\telementRef,\n\titemHeight,\n\ttotalItems,\n\toptions\n) {\n\tconst initWindowSize = options?.initWindowSize ?? DEFAULT_INIT_WINDOW_SIZE;\n\tconst useWindowing = options?.useWindowing ?? true;\n\n\tconst [ fixedListWindow, setFixedListWindow ] = useState( {\n\t\tvisibleItems: initWindowSize,\n\t\tstart: 0,\n\t\tend: initWindowSize,\n\t\titemInView: ( /** @type {number} */ index ) => {\n\t\t\treturn index >= 0 && index <= initWindowSize;\n\t\t},\n\t} );\n\n\tuseLayoutEffect( () => {\n\t\tif ( ! useWindowing ) {\n\t\t\treturn;\n\t\t}\n\t\tconst scrollContainer = getScrollContainer( elementRef.current );\n\t\tconst measureWindow = (\n\t\t\t/** @type {boolean | undefined} */ initRender\n\t\t) => {\n\t\t\tif ( ! scrollContainer ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst visibleItems = Math.ceil(\n\t\t\t\tscrollContainer.clientHeight / itemHeight\n\t\t\t);\n\t\t\t// Aim to keep opening list view fast, afterward we can optimize for scrolling.\n\t\t\tconst windowOverscan = initRender\n\t\t\t\t? visibleItems\n\t\t\t\t: options?.windowOverscan ?? visibleItems;\n\t\t\tconst firstViewableIndex = Math.floor(\n\t\t\t\tscrollContainer.scrollTop / itemHeight\n\t\t\t);\n\t\t\tconst start = Math.max( 0, firstViewableIndex - windowOverscan );\n\t\t\tconst end = Math.min(\n\t\t\t\ttotalItems - 1,\n\t\t\t\tfirstViewableIndex + visibleItems + windowOverscan\n\t\t\t);\n\t\t\tsetFixedListWindow( ( lastWindow ) => {\n\t\t\t\tconst nextWindow = {\n\t\t\t\t\tvisibleItems,\n\t\t\t\t\tstart,\n\t\t\t\t\tend,\n\t\t\t\t\titemInView: ( /** @type {number} */ index ) => {\n\t\t\t\t\t\treturn start <= index && index <= end;\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\tif (\n\t\t\t\t\tlastWindow.start !== nextWindow.start ||\n\t\t\t\t\tlastWindow.end !== nextWindow.end ||\n\t\t\t\t\tlastWindow.visibleItems !== nextWindow.visibleItems\n\t\t\t\t) {\n\t\t\t\t\treturn nextWindow;\n\t\t\t\t}\n\t\t\t\treturn lastWindow;\n\t\t\t} );\n\t\t};\n\n\t\tmeasureWindow( true );\n\t\tconst debounceMeasureList = debounce( () => {\n\t\t\tmeasureWindow();\n\t\t}, 16 );\n\t\tscrollContainer?.addEventListener( 'scroll', debounceMeasureList );\n\t\tscrollContainer?.ownerDocument?.defaultView?.addEventListener(\n\t\t\t'resize',\n\t\t\tdebounceMeasureList\n\t\t);\n\t\tscrollContainer?.ownerDocument?.defaultView?.addEventListener(\n\t\t\t'resize',\n\t\t\tdebounceMeasureList\n\t\t);\n\n\t\treturn () => {\n\t\t\tscrollContainer?.removeEventListener(\n\t\t\t\t'scroll',\n\t\t\t\tdebounceMeasureList\n\t\t\t);\n\t\t\tscrollContainer?.ownerDocument?.defaultView?.removeEventListener(\n\t\t\t\t'resize',\n\t\t\t\tdebounceMeasureList\n\t\t\t);\n\t\t};\n\t}, [\n\t\titemHeight,\n\t\telementRef,\n\t\ttotalItems,\n\t\toptions?.expandedState,\n\t\toptions?.windowOverscan,\n\t\tuseWindowing,\n\t] );\n\n\tuseLayoutEffect( () => {\n\t\tif ( ! useWindowing ) {\n\t\t\treturn;\n\t\t}\n\t\tconst scrollContainer = getScrollContainer( elementRef.current );\n\t\tconst handleKeyDown = ( /** @type {KeyboardEvent} */ event ) => {\n\t\t\tswitch ( event.keyCode ) {\n\t\t\t\tcase HOME: {\n\t\t\t\t\treturn scrollContainer?.scrollTo( { top: 0 } );\n\t\t\t\t}\n\t\t\t\tcase END: {\n\t\t\t\t\treturn scrollContainer?.scrollTo( {\n\t\t\t\t\t\ttop: totalItems * itemHeight,\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t\tcase PAGEUP: {\n\t\t\t\t\treturn scrollContainer?.scrollTo( {\n\t\t\t\t\t\ttop:\n\t\t\t\t\t\t\tscrollContainer.scrollTop -\n\t\t\t\t\t\t\tfixedListWindow.visibleItems * itemHeight,\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t\tcase PAGEDOWN: {\n\t\t\t\t\treturn scrollContainer?.scrollTo( {\n\t\t\t\t\t\ttop:\n\t\t\t\t\t\t\tscrollContainer.scrollTop +\n\t\t\t\t\t\t\tfixedListWindow.visibleItems * itemHeight,\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tscrollContainer?.ownerDocument?.defaultView?.addEventListener(\n\t\t\t'keydown',\n\t\t\thandleKeyDown\n\t\t);\n\t\treturn () => {\n\t\t\tscrollContainer?.ownerDocument?.defaultView?.removeEventListener(\n\t\t\t\t'keydown',\n\t\t\t\thandleKeyDown\n\t\t\t);\n\t\t};\n\t}, [\n\t\ttotalItems,\n\t\titemHeight,\n\t\telementRef,\n\t\tfixedListWindow.visibleItems,\n\t\tuseWindowing,\n\t\toptions?.expandedState,\n\t] );\n\n\treturn [ fixedListWindow, setFixedListWindow ];\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,45 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import { focus } from '@wordpress/dom';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Internal dependencies
|
|
9
|
-
*/
|
|
10
|
-
import useRefEffect from '../use-ref-effect';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Hook used to focus the first tabbable element on mount.
|
|
14
|
-
*
|
|
15
|
-
* @param {boolean | 'firstElement'} focusOnMount Focus on mount mode.
|
|
16
|
-
* @return {import('react').RefCallback<HTMLElement>} Ref callback.
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* ```js
|
|
20
|
-
* import { useFocusOnMount } from '@wordpress/compose';
|
|
21
|
-
*
|
|
22
|
-
* const WithFocusOnMount = () => {
|
|
23
|
-
* const ref = useFocusOnMount()
|
|
24
|
-
* return (
|
|
25
|
-
* <div ref={ ref }>
|
|
26
|
-
* <Button />
|
|
27
|
-
* <Button />
|
|
28
|
-
* </div>
|
|
29
|
-
* );
|
|
30
|
-
* }
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
export default function useFocusOnMount(focusOnMount = 'firstElement') {
|
|
1
|
+
import { useRef, useEffect } from "@wordpress/element";
|
|
2
|
+
import { focus } from "@wordpress/dom";
|
|
3
|
+
import useRefEffect from "../use-ref-effect";
|
|
4
|
+
function useFocusOnMount(focusOnMount = "firstElement") {
|
|
34
5
|
const focusOnMountRef = useRef(focusOnMount);
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Sets focus on a DOM element.
|
|
38
|
-
*
|
|
39
|
-
* @param {HTMLElement} target The DOM element to set focus to.
|
|
40
|
-
* @return {void}
|
|
41
|
-
*/
|
|
42
|
-
const setFocus = target => {
|
|
6
|
+
const setFocus = (target) => {
|
|
43
7
|
target.focus({
|
|
44
8
|
// When focusing newly mounted dialogs,
|
|
45
9
|
// the position of the popover is often not right on the first render
|
|
@@ -47,21 +11,18 @@ export default function useFocusOnMount(focusOnMount = 'firstElement') {
|
|
|
47
11
|
preventScroll: true
|
|
48
12
|
});
|
|
49
13
|
};
|
|
50
|
-
|
|
51
|
-
/** @type {import('react').MutableRefObject<ReturnType<setTimeout> | undefined>} */
|
|
52
14
|
const timerIdRef = useRef();
|
|
53
15
|
useEffect(() => {
|
|
54
16
|
focusOnMountRef.current = focusOnMount;
|
|
55
17
|
}, [focusOnMount]);
|
|
56
|
-
return useRefEffect(node => {
|
|
57
|
-
var _node$ownerDocument$a;
|
|
18
|
+
return useRefEffect((node) => {
|
|
58
19
|
if (!node || focusOnMountRef.current === false) {
|
|
59
20
|
return;
|
|
60
21
|
}
|
|
61
|
-
if (node.contains(
|
|
22
|
+
if (node.contains(node.ownerDocument?.activeElement ?? null)) {
|
|
62
23
|
return;
|
|
63
24
|
}
|
|
64
|
-
if (focusOnMountRef.current !==
|
|
25
|
+
if (focusOnMountRef.current !== "firstElement") {
|
|
65
26
|
setFocus(node);
|
|
66
27
|
return;
|
|
67
28
|
}
|
|
@@ -78,4 +39,7 @@ export default function useFocusOnMount(focusOnMount = 'firstElement') {
|
|
|
78
39
|
};
|
|
79
40
|
}, []);
|
|
80
41
|
}
|
|
81
|
-
|
|
42
|
+
export {
|
|
43
|
+
useFocusOnMount as default
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/hooks/use-focus-on-mount/index.js"],
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useRef, useEffect } from '@wordpress/element';\nimport { focus } from '@wordpress/dom';\n\n/**\n * Internal dependencies\n */\nimport useRefEffect from '../use-ref-effect';\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\n\t/**\n\t * Sets focus on a DOM element.\n\t *\n\t * @param {HTMLElement} target The DOM element to set focus to.\n\t * @return {void}\n\t */\n\tconst setFocus = ( target ) => {\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\t/** @type {import('react').MutableRefObject<ReturnType<setTimeout> | undefined>} */\n\tconst timerIdRef = useRef();\n\n\tuseEffect( () => {\n\t\tfocusOnMountRef.current = focusOnMount;\n\t}, [ focusOnMount ] );\n\n\treturn useRefEffect( ( 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\tif ( focusOnMountRef.current !== 'firstElement' ) {\n\t\t\tsetFocus( node );\n\t\t\treturn;\n\t\t}\n\n\t\ttimerIdRef.current = setTimeout( () => {\n\t\t\tconst firstTabbable = focus.tabbable.find( node )[ 0 ];\n\t\t\tif ( firstTabbable ) {\n\t\t\t\tsetFocus( firstTabbable );\n\t\t\t}\n\t\t}, 0 );\n\n\t\treturn () => {\n\t\t\tif ( timerIdRef.current ) {\n\t\t\t\tclearTimeout( timerIdRef.current );\n\t\t\t}\n\t\t};\n\t}, [] );\n}\n"],
|
|
5
|
+
"mappings": "AAGA,SAAS,QAAQ,iBAAiB;AAClC,SAAS,aAAa;AAKtB,OAAO,kBAAkB;AAuBV,SAAR,gBAAkC,eAAe,gBAAiB;AACxE,QAAM,kBAAkB,OAAQ,YAAa;AAQ7C,QAAM,WAAW,CAAE,WAAY;AAC9B,WAAO,MAAO;AAAA;AAAA;AAAA;AAAA,MAIb,eAAe;AAAA,IAChB,CAAE;AAAA,EACH;AAGA,QAAM,aAAa,OAAO;AAE1B,YAAW,MAAM;AAChB,oBAAgB,UAAU;AAAA,EAC3B,GAAG,CAAE,YAAa,CAAE;AAEpB,SAAO,aAAc,CAAE,SAAU;AAChC,QAAK,CAAE,QAAQ,gBAAgB,YAAY,OAAQ;AAClD;AAAA,IACD;AAEA,QAAK,KAAK,SAAU,KAAK,eAAe,iBAAiB,IAAK,GAAI;AACjE;AAAA,IACD;AAEA,QAAK,gBAAgB,YAAY,gBAAiB;AACjD,eAAU,IAAK;AACf;AAAA,IACD;AAEA,eAAW,UAAU,WAAY,MAAM;AACtC,YAAM,gBAAgB,MAAM,SAAS,KAAM,IAAK,EAAG,CAAE;AACrD,UAAK,eAAgB;AACpB,iBAAU,aAAc;AAAA,MACzB;AAAA,IACD,GAAG,CAAE;AAEL,WAAO,MAAM;AACZ,UAAK,WAAW,SAAU;AACzB,qBAAc,WAAW,OAAQ;AAAA,MAClC;AAAA,IACD;AAAA,EACD,GAAG,CAAC,CAAE;AACP;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,136 +1,61 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*/
|
|
4
|
-
import { useCallback, useEffect, useRef } from '@wordpress/element';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Input types which are classified as button types, for use in considering
|
|
8
|
-
* whether element is a (focus-normalized) button.
|
|
9
|
-
*/
|
|
10
|
-
const INPUT_BUTTON_TYPES = ['button', 'submit'];
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* List of HTML button elements subject to focus normalization
|
|
14
|
-
*
|
|
15
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Returns true if the given element is a button element subject to focus
|
|
20
|
-
* normalization, or false otherwise.
|
|
21
|
-
*
|
|
22
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus
|
|
23
|
-
*
|
|
24
|
-
* @param eventTarget The target from a mouse or touch event.
|
|
25
|
-
*
|
|
26
|
-
* @return Whether the element is a button element subject to focus normalization.
|
|
27
|
-
*/
|
|
1
|
+
import { useCallback, useEffect, useRef } from "@wordpress/element";
|
|
2
|
+
const INPUT_BUTTON_TYPES = ["button", "submit"];
|
|
28
3
|
function isFocusNormalizedButton(eventTarget) {
|
|
29
4
|
if (!(eventTarget instanceof window.HTMLElement)) {
|
|
30
5
|
return false;
|
|
31
6
|
}
|
|
32
7
|
switch (eventTarget.nodeName) {
|
|
33
|
-
case
|
|
34
|
-
case
|
|
8
|
+
case "A":
|
|
9
|
+
case "BUTTON":
|
|
35
10
|
return true;
|
|
36
|
-
case
|
|
37
|
-
return INPUT_BUTTON_TYPES.includes(
|
|
11
|
+
case "INPUT":
|
|
12
|
+
return INPUT_BUTTON_TYPES.includes(
|
|
13
|
+
eventTarget.type
|
|
14
|
+
);
|
|
38
15
|
}
|
|
39
16
|
return false;
|
|
40
17
|
}
|
|
41
|
-
|
|
42
|
-
* A react hook that can be used to check whether focus has moved outside the
|
|
43
|
-
* element the event handlers are bound to.
|
|
44
|
-
*
|
|
45
|
-
* @param onFocusOutside A callback triggered when focus moves outside
|
|
46
|
-
* the element the event handlers are bound to.
|
|
47
|
-
*
|
|
48
|
-
* @return An object containing event handlers. Bind the event handlers to a
|
|
49
|
-
* wrapping element element to capture when focus moves outside that element.
|
|
50
|
-
*/
|
|
51
|
-
export default function useFocusOutside(onFocusOutside) {
|
|
18
|
+
function useFocusOutside(onFocusOutside) {
|
|
52
19
|
const currentOnFocusOutsideRef = useRef(onFocusOutside);
|
|
53
20
|
useEffect(() => {
|
|
54
21
|
currentOnFocusOutsideRef.current = onFocusOutside;
|
|
55
22
|
}, [onFocusOutside]);
|
|
56
23
|
const preventBlurCheckRef = useRef(false);
|
|
57
24
|
const blurCheckTimeoutIdRef = useRef();
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Cancel a blur check timeout.
|
|
61
|
-
*/
|
|
62
25
|
const cancelBlurCheck = useCallback(() => {
|
|
63
26
|
clearTimeout(blurCheckTimeoutIdRef.current);
|
|
64
27
|
}, []);
|
|
65
|
-
|
|
66
|
-
// Cancel a blur check if the callback or ref is no longer provided.
|
|
67
28
|
useEffect(() => {
|
|
68
29
|
if (!onFocusOutside) {
|
|
69
30
|
cancelBlurCheck();
|
|
70
31
|
}
|
|
71
32
|
}, [onFocusOutside, cancelBlurCheck]);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
* unassign a flag for preventing blur check on button elements. Some
|
|
76
|
-
* browsers, namely Firefox and Safari, do not emit a focus event on
|
|
77
|
-
* button elements when clicked, while others do. The logic here
|
|
78
|
-
* intends to normalize this as treating click on buttons as focus.
|
|
79
|
-
*
|
|
80
|
-
* @param event
|
|
81
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus
|
|
82
|
-
*/
|
|
83
|
-
const normalizeButtonFocus = useCallback(event => {
|
|
84
|
-
const {
|
|
85
|
-
type,
|
|
86
|
-
target
|
|
87
|
-
} = event;
|
|
88
|
-
const isInteractionEnd = ['mouseup', 'touchend'].includes(type);
|
|
33
|
+
const normalizeButtonFocus = useCallback((event) => {
|
|
34
|
+
const { type, target } = event;
|
|
35
|
+
const isInteractionEnd = ["mouseup", "touchend"].includes(type);
|
|
89
36
|
if (isInteractionEnd) {
|
|
90
37
|
preventBlurCheckRef.current = false;
|
|
91
38
|
} else if (isFocusNormalizedButton(target)) {
|
|
92
39
|
preventBlurCheckRef.current = true;
|
|
93
40
|
}
|
|
94
41
|
}, []);
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* A callback triggered when a blur event occurs on the element the handler
|
|
98
|
-
* is bound to.
|
|
99
|
-
*
|
|
100
|
-
* Calls the `onFocusOutside` callback in an immediate timeout if focus has
|
|
101
|
-
* move outside the bound element and is still within the document.
|
|
102
|
-
*/
|
|
103
|
-
const queueBlurCheck = useCallback(event => {
|
|
104
|
-
// React does not allow using an event reference asynchronously
|
|
105
|
-
// due to recycling behavior, except when explicitly persisted.
|
|
42
|
+
const queueBlurCheck = useCallback((event) => {
|
|
106
43
|
event.persist();
|
|
107
|
-
|
|
108
|
-
// Skip blur check if clicking button. See `normalizeButtonFocus`.
|
|
109
44
|
if (preventBlurCheckRef.current) {
|
|
110
45
|
return;
|
|
111
46
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
// therefore don't exist in the React tree. An example is opening
|
|
116
|
-
// the Media Library modal from another dialog.
|
|
117
|
-
// This attribute should contain a selector of the related target
|
|
118
|
-
// we want to ignore, because we still need to trigger the blur event
|
|
119
|
-
// on all other cases.
|
|
120
|
-
const ignoreForRelatedTarget = event.target.getAttribute('data-unstable-ignore-focus-outside-for-relatedtarget');
|
|
47
|
+
const ignoreForRelatedTarget = event.target.getAttribute(
|
|
48
|
+
"data-unstable-ignore-focus-outside-for-relatedtarget"
|
|
49
|
+
);
|
|
121
50
|
if (ignoreForRelatedTarget && event.relatedTarget?.closest(ignoreForRelatedTarget)) {
|
|
122
51
|
return;
|
|
123
52
|
}
|
|
124
53
|
blurCheckTimeoutIdRef.current = setTimeout(() => {
|
|
125
|
-
// If document is not focused then focus should remain
|
|
126
|
-
// inside the wrapped component and therefore we cancel
|
|
127
|
-
// this blur event thereby leaving focus in place.
|
|
128
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/Document/hasFocus.
|
|
129
54
|
if (!document.hasFocus()) {
|
|
130
55
|
event.preventDefault();
|
|
131
56
|
return;
|
|
132
57
|
}
|
|
133
|
-
if (
|
|
58
|
+
if ("function" === typeof currentOnFocusOutsideRef.current) {
|
|
134
59
|
currentOnFocusOutsideRef.current(event);
|
|
135
60
|
}
|
|
136
61
|
}, 0);
|
|
@@ -144,4 +69,7 @@ export default function useFocusOutside(onFocusOutside) {
|
|
|
144
69
|
onBlur: queueBlurCheck
|
|
145
70
|
};
|
|
146
71
|
}
|
|
147
|
-
|
|
72
|
+
export {
|
|
73
|
+
useFocusOutside as default
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/hooks/use-focus-outside/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useCallback, useEffect, useRef } from '@wordpress/element';\n\n/**\n * Input types which are classified as button types, for use in considering\n * whether element is a (focus-normalized) button.\n */\nconst INPUT_BUTTON_TYPES = [ 'button', 'submit' ];\n\n/**\n * List of HTML button elements subject to focus normalization\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus\n */\ntype FocusNormalizedButton =\n\t| HTMLButtonElement\n\t| HTMLLinkElement\n\t| HTMLInputElement;\n\n/**\n * Returns true if the given element is a button element subject to focus\n * normalization, or false otherwise.\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus\n *\n * @param eventTarget The target from a mouse or touch event.\n *\n * @return Whether the element is a button element subject to focus normalization.\n */\nfunction isFocusNormalizedButton(\n\teventTarget: EventTarget\n): eventTarget is FocusNormalizedButton {\n\tif ( ! ( eventTarget instanceof window.HTMLElement ) ) {\n\t\treturn false;\n\t}\n\tswitch ( eventTarget.nodeName ) {\n\t\tcase 'A':\n\t\tcase 'BUTTON':\n\t\t\treturn true;\n\n\t\tcase 'INPUT':\n\t\t\treturn INPUT_BUTTON_TYPES.includes(\n\t\t\t\t( eventTarget as HTMLInputElement ).type\n\t\t\t);\n\t}\n\n\treturn false;\n}\n\ntype UseFocusOutsideReturn = {\n\tonFocus: React.FocusEventHandler;\n\tonMouseDown: React.MouseEventHandler;\n\tonMouseUp: React.MouseEventHandler;\n\tonTouchStart: React.TouchEventHandler;\n\tonTouchEnd: React.TouchEventHandler;\n\tonBlur: React.FocusEventHandler;\n};\n\n/**\n * A react hook that can be used to check whether focus has moved outside the\n * element the event handlers are bound to.\n *\n * @param onFocusOutside A callback triggered when focus moves outside\n * the element the event handlers are bound to.\n *\n * @return An object containing event handlers. Bind the event handlers to a\n * wrapping element element to capture when focus moves outside that element.\n */\nexport default function useFocusOutside(\n\tonFocusOutside: ( ( event: React.FocusEvent ) => void ) | undefined\n): UseFocusOutsideReturn {\n\tconst currentOnFocusOutsideRef = useRef( onFocusOutside );\n\tuseEffect( () => {\n\t\tcurrentOnFocusOutsideRef.current = onFocusOutside;\n\t}, [ onFocusOutside ] );\n\n\tconst preventBlurCheckRef = useRef( false );\n\n\tconst blurCheckTimeoutIdRef = useRef< number | undefined >();\n\n\t/**\n\t * Cancel a blur check timeout.\n\t */\n\tconst cancelBlurCheck = useCallback( () => {\n\t\tclearTimeout( blurCheckTimeoutIdRef.current );\n\t}, [] );\n\n\t// Cancel a blur check if the callback or ref is no longer provided.\n\tuseEffect( () => {\n\t\tif ( ! onFocusOutside ) {\n\t\t\tcancelBlurCheck();\n\t\t}\n\t}, [ onFocusOutside, cancelBlurCheck ] );\n\n\t/**\n\t * Handles a mousedown or mouseup event to respectively assign and\n\t * unassign a flag for preventing blur check on button elements. Some\n\t * browsers, namely Firefox and Safari, do not emit a focus event on\n\t * button elements when clicked, while others do. The logic here\n\t * intends to normalize this as treating click on buttons as focus.\n\t *\n\t * @param event\n\t * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus\n\t */\n\tconst normalizeButtonFocus: React.EventHandler<\n\t\tReact.MouseEvent | React.TouchEvent\n\t> = useCallback( ( event ) => {\n\t\tconst { type, target } = event;\n\t\tconst isInteractionEnd = [ 'mouseup', 'touchend' ].includes( type );\n\n\t\tif ( isInteractionEnd ) {\n\t\t\tpreventBlurCheckRef.current = false;\n\t\t} else if ( isFocusNormalizedButton( target ) ) {\n\t\t\tpreventBlurCheckRef.current = true;\n\t\t}\n\t}, [] );\n\n\t/**\n\t * A callback triggered when a blur event occurs on the element the handler\n\t * is bound to.\n\t *\n\t * Calls the `onFocusOutside` callback in an immediate timeout if focus has\n\t * move outside the bound element and is still within the document.\n\t */\n\tconst queueBlurCheck: React.FocusEventHandler = useCallback( ( event ) => {\n\t\t// React does not allow using an event reference asynchronously\n\t\t// due to recycling behavior, except when explicitly persisted.\n\t\tevent.persist();\n\n\t\t// Skip blur check if clicking button. See `normalizeButtonFocus`.\n\t\tif ( preventBlurCheckRef.current ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// The usage of this attribute should be avoided. The only use case\n\t\t// would be when we load modals that are not React components and\n\t\t// therefore don't exist in the React tree. An example is opening\n\t\t// the Media Library modal from another dialog.\n\t\t// This attribute should contain a selector of the related target\n\t\t// we want to ignore, because we still need to trigger the blur event\n\t\t// on all other cases.\n\t\tconst ignoreForRelatedTarget = event.target.getAttribute(\n\t\t\t'data-unstable-ignore-focus-outside-for-relatedtarget'\n\t\t);\n\t\tif (\n\t\t\tignoreForRelatedTarget &&\n\t\t\tevent.relatedTarget?.closest( ignoreForRelatedTarget )\n\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\tblurCheckTimeoutIdRef.current = setTimeout( () => {\n\t\t\t// If document is not focused then focus should remain\n\t\t\t// inside the wrapped component and therefore we cancel\n\t\t\t// this blur event thereby leaving focus in place.\n\t\t\t// https://developer.mozilla.org/en-US/docs/Web/API/Document/hasFocus.\n\t\t\tif ( ! document.hasFocus() ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( 'function' === typeof currentOnFocusOutsideRef.current ) {\n\t\t\t\tcurrentOnFocusOutsideRef.current( event );\n\t\t\t}\n\t\t}, 0 );\n\t}, [] );\n\n\treturn {\n\t\tonFocus: cancelBlurCheck,\n\t\tonMouseDown: normalizeButtonFocus,\n\t\tonMouseUp: normalizeButtonFocus,\n\t\tonTouchStart: normalizeButtonFocus,\n\t\tonTouchEnd: normalizeButtonFocus,\n\t\tonBlur: queueBlurCheck,\n\t};\n}\n"],
|
|
5
|
+
"mappings": "AAGA,SAAS,aAAa,WAAW,cAAc;AAM/C,MAAM,qBAAqB,CAAE,UAAU,QAAS;AAsBhD,SAAS,wBACR,aACuC;AACvC,MAAK,EAAI,uBAAuB,OAAO,cAAgB;AACtD,WAAO;AAAA,EACR;AACA,UAAS,YAAY,UAAW;AAAA,IAC/B,KAAK;AAAA,IACL,KAAK;AACJ,aAAO;AAAA,IAER,KAAK;AACJ,aAAO,mBAAmB;AAAA,QACvB,YAAkC;AAAA,MACrC;AAAA,EACF;AAEA,SAAO;AACR;AAqBe,SAAR,gBACN,gBACwB;AACxB,QAAM,2BAA2B,OAAQ,cAAe;AACxD,YAAW,MAAM;AAChB,6BAAyB,UAAU;AAAA,EACpC,GAAG,CAAE,cAAe,CAAE;AAEtB,QAAM,sBAAsB,OAAQ,KAAM;AAE1C,QAAM,wBAAwB,OAA6B;AAK3D,QAAM,kBAAkB,YAAa,MAAM;AAC1C,iBAAc,sBAAsB,OAAQ;AAAA,EAC7C,GAAG,CAAC,CAAE;AAGN,YAAW,MAAM;AAChB,QAAK,CAAE,gBAAiB;AACvB,sBAAgB;AAAA,IACjB;AAAA,EACD,GAAG,CAAE,gBAAgB,eAAgB,CAAE;AAYvC,QAAM,uBAEF,YAAa,CAAE,UAAW;AAC7B,UAAM,EAAE,MAAM,OAAO,IAAI;AACzB,UAAM,mBAAmB,CAAE,WAAW,UAAW,EAAE,SAAU,IAAK;AAElE,QAAK,kBAAmB;AACvB,0BAAoB,UAAU;AAAA,IAC/B,WAAY,wBAAyB,MAAO,GAAI;AAC/C,0BAAoB,UAAU;AAAA,IAC/B;AAAA,EACD,GAAG,CAAC,CAAE;AASN,QAAM,iBAA0C,YAAa,CAAE,UAAW;AAGzE,UAAM,QAAQ;AAGd,QAAK,oBAAoB,SAAU;AAClC;AAAA,IACD;AASA,UAAM,yBAAyB,MAAM,OAAO;AAAA,MAC3C;AAAA,IACD;AACA,QACC,0BACA,MAAM,eAAe,QAAS,sBAAuB,GACpD;AACD;AAAA,IACD;AAEA,0BAAsB,UAAU,WAAY,MAAM;AAKjD,UAAK,CAAE,SAAS,SAAS,GAAI;AAC5B,cAAM,eAAe;AACrB;AAAA,MACD;AAEA,UAAK,eAAe,OAAO,yBAAyB,SAAU;AAC7D,iCAAyB,QAAS,KAAM;AAAA,MACzC;AAAA,IACD,GAAG,CAAE;AAAA,EACN,GAAG,CAAC,CAAE;AAEN,SAAO;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,IACb,WAAW;AAAA,IACX,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,QAAQ;AAAA,EACT;AACD;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,74 +1,39 @@
|
|
|
1
|
-
|
|
2
|
-
* WordPress dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { useRef, useEffect, useCallback } from '@wordpress/element';
|
|
5
|
-
|
|
6
|
-
/** @type {Element|null} */
|
|
1
|
+
import { useRef, useEffect, useCallback } from "@wordpress/element";
|
|
7
2
|
let origin = null;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Adds the unmount behavior of returning focus to the element which had it
|
|
11
|
-
* previously as is expected for roles like menus or dialogs.
|
|
12
|
-
*
|
|
13
|
-
* @param {() => void} [onFocusReturn] Overrides the default return behavior.
|
|
14
|
-
* @return {import('react').RefCallback<HTMLElement>} Element Ref.
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ```js
|
|
18
|
-
* import { useFocusReturn } from '@wordpress/compose';
|
|
19
|
-
*
|
|
20
|
-
* const WithFocusReturn = () => {
|
|
21
|
-
* const ref = useFocusReturn()
|
|
22
|
-
* return (
|
|
23
|
-
* <div ref={ ref }>
|
|
24
|
-
* <Button />
|
|
25
|
-
* <Button />
|
|
26
|
-
* </div>
|
|
27
|
-
* );
|
|
28
|
-
* }
|
|
29
|
-
* ```
|
|
30
|
-
*/
|
|
31
3
|
function useFocusReturn(onFocusReturn) {
|
|
32
|
-
/** @type {import('react').MutableRefObject<null | HTMLElement>} */
|
|
33
4
|
const ref = useRef(null);
|
|
34
|
-
/** @type {import('react').MutableRefObject<null | Element>} */
|
|
35
5
|
const focusedBeforeMount = useRef(null);
|
|
36
6
|
const onFocusReturnRef = useRef(onFocusReturn);
|
|
37
7
|
useEffect(() => {
|
|
38
8
|
onFocusReturnRef.current = onFocusReturn;
|
|
39
9
|
}, [onFocusReturn]);
|
|
40
|
-
return useCallback(node => {
|
|
10
|
+
return useCallback((node) => {
|
|
41
11
|
if (node) {
|
|
42
|
-
var _activeDocument$activ;
|
|
43
|
-
// Set ref to be used when unmounting.
|
|
44
12
|
ref.current = node;
|
|
45
|
-
|
|
46
|
-
// Only set when the node mounts.
|
|
47
13
|
if (focusedBeforeMount.current) {
|
|
48
14
|
return;
|
|
49
15
|
}
|
|
50
16
|
const activeDocument = node.ownerDocument.activeElement instanceof window.HTMLIFrameElement ? node.ownerDocument.activeElement.contentDocument : node.ownerDocument;
|
|
51
|
-
focusedBeforeMount.current =
|
|
17
|
+
focusedBeforeMount.current = activeDocument?.activeElement ?? null;
|
|
52
18
|
} else if (focusedBeforeMount.current) {
|
|
53
|
-
const isFocused = ref.current?.contains(
|
|
19
|
+
const isFocused = ref.current?.contains(
|
|
20
|
+
ref.current?.ownerDocument.activeElement
|
|
21
|
+
);
|
|
54
22
|
if (ref.current?.isConnected && !isFocused) {
|
|
55
|
-
|
|
56
|
-
(_origin = origin) !== null && _origin !== void 0 ? _origin : origin = focusedBeforeMount.current;
|
|
23
|
+
origin ??= focusedBeforeMount.current;
|
|
57
24
|
return;
|
|
58
25
|
}
|
|
59
|
-
|
|
60
|
-
// Defer to the component's own explicit focus return behavior, if
|
|
61
|
-
// specified. This allows for support that the `onFocusReturn`
|
|
62
|
-
// decides to allow the default behavior to occur under some
|
|
63
|
-
// conditions.
|
|
64
26
|
if (onFocusReturnRef.current) {
|
|
65
27
|
onFocusReturnRef.current();
|
|
66
28
|
} else {
|
|
67
|
-
|
|
29
|
+
(!focusedBeforeMount.current.isConnected ? origin : focusedBeforeMount.current)?.focus();
|
|
68
30
|
}
|
|
69
31
|
origin = null;
|
|
70
32
|
}
|
|
71
33
|
}, []);
|
|
72
34
|
}
|
|
73
|
-
|
|
74
|
-
|
|
35
|
+
var use_focus_return_default = useFocusReturn;
|
|
36
|
+
export {
|
|
37
|
+
use_focus_return_default as default
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/hooks/use-focus-return/index.js"],
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useRef, useEffect, useCallback } from '@wordpress/element';\n\n/** @type {Element|null} */\nlet origin = null;\n\n/**\n * Adds the unmount behavior of returning focus to the element which had it\n * previously as is expected for roles like menus or dialogs.\n *\n * @param {() => void} [onFocusReturn] Overrides the default return behavior.\n * @return {import('react').RefCallback<HTMLElement>} Element Ref.\n *\n * @example\n * ```js\n * import { useFocusReturn } from '@wordpress/compose';\n *\n * const WithFocusReturn = () => {\n * const ref = useFocusReturn()\n * return (\n * <div ref={ ref }>\n * <Button />\n * <Button />\n * </div>\n * );\n * }\n * ```\n */\nfunction useFocusReturn( onFocusReturn ) {\n\t/** @type {import('react').MutableRefObject<null | HTMLElement>} */\n\tconst ref = useRef( null );\n\t/** @type {import('react').MutableRefObject<null | Element>} */\n\tconst focusedBeforeMount = useRef( null );\n\tconst onFocusReturnRef = useRef( onFocusReturn );\n\tuseEffect( () => {\n\t\tonFocusReturnRef.current = onFocusReturn;\n\t}, [ onFocusReturn ] );\n\n\treturn useCallback( ( node ) => {\n\t\tif ( node ) {\n\t\t\t// Set ref to be used when unmounting.\n\t\t\tref.current = node;\n\n\t\t\t// Only set when the node mounts.\n\t\t\tif ( focusedBeforeMount.current ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst activeDocument =\n\t\t\t\tnode.ownerDocument.activeElement instanceof\n\t\t\t\twindow.HTMLIFrameElement\n\t\t\t\t\t? node.ownerDocument.activeElement.contentDocument\n\t\t\t\t\t: node.ownerDocument;\n\n\t\t\tfocusedBeforeMount.current = activeDocument?.activeElement ?? null;\n\t\t} else if ( focusedBeforeMount.current ) {\n\t\t\tconst isFocused = ref.current?.contains(\n\t\t\t\tref.current?.ownerDocument.activeElement\n\t\t\t);\n\n\t\t\tif ( ref.current?.isConnected && ! isFocused ) {\n\t\t\t\torigin ??= focusedBeforeMount.current;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Defer to the component's own explicit focus return behavior, if\n\t\t\t// specified. This allows for support that the `onFocusReturn`\n\t\t\t// decides to allow the default behavior to occur under some\n\t\t\t// conditions.\n\t\t\tif ( onFocusReturnRef.current ) {\n\t\t\t\tonFocusReturnRef.current();\n\t\t\t} else {\n\t\t\t\t/** @type {null|HTMLElement} */ (\n\t\t\t\t\t! focusedBeforeMount.current.isConnected\n\t\t\t\t\t\t? origin\n\t\t\t\t\t\t: focusedBeforeMount.current\n\t\t\t\t)?.focus();\n\t\t\t}\n\t\t\torigin = null;\n\t\t}\n\t}, [] );\n}\n\nexport default useFocusReturn;\n"],
|
|
5
|
+
"mappings": "AAGA,SAAS,QAAQ,WAAW,mBAAmB;AAG/C,IAAI,SAAS;AAwBb,SAAS,eAAgB,eAAgB;AAExC,QAAM,MAAM,OAAQ,IAAK;AAEzB,QAAM,qBAAqB,OAAQ,IAAK;AACxC,QAAM,mBAAmB,OAAQ,aAAc;AAC/C,YAAW,MAAM;AAChB,qBAAiB,UAAU;AAAA,EAC5B,GAAG,CAAE,aAAc,CAAE;AAErB,SAAO,YAAa,CAAE,SAAU;AAC/B,QAAK,MAAO;AAEX,UAAI,UAAU;AAGd,UAAK,mBAAmB,SAAU;AACjC;AAAA,MACD;AAEA,YAAM,iBACL,KAAK,cAAc,yBACnB,OAAO,oBACJ,KAAK,cAAc,cAAc,kBACjC,KAAK;AAET,yBAAmB,UAAU,gBAAgB,iBAAiB;AAAA,IAC/D,WAAY,mBAAmB,SAAU;AACxC,YAAM,YAAY,IAAI,SAAS;AAAA,QAC9B,IAAI,SAAS,cAAc;AAAA,MAC5B;AAEA,UAAK,IAAI,SAAS,eAAe,CAAE,WAAY;AAC9C,mBAAW,mBAAmB;AAC9B;AAAA,MACD;AAMA,UAAK,iBAAiB,SAAU;AAC/B,yBAAiB,QAAQ;AAAA,MAC1B,OAAO;AAC0B,SAC/B,CAAE,mBAAmB,QAAQ,cAC1B,SACA,mBAAmB,UACpB,MAAM;AAAA,MACV;AACA,eAAS;AAAA,IACV;AAAA,EACD,GAAG,CAAC,CAAE;AACP;AAEA,IAAO,2BAAQ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,46 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Internal dependencies
|
|
7
|
-
*/
|
|
8
|
-
import useRefEffect from '../use-ref-effect';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Dispatches a bubbling focus event when the iframe receives focus. Use
|
|
12
|
-
* `onFocus` as usual on the iframe or a parent element.
|
|
13
|
-
*
|
|
14
|
-
* @return Ref to pass to the iframe.
|
|
15
|
-
*/
|
|
16
|
-
export default function useFocusableIframe() {
|
|
17
|
-
return useRefEffect(element => {
|
|
18
|
-
const {
|
|
19
|
-
ownerDocument
|
|
20
|
-
} = element;
|
|
1
|
+
import useRefEffect from "../use-ref-effect";
|
|
2
|
+
function useFocusableIframe() {
|
|
3
|
+
return useRefEffect((element) => {
|
|
4
|
+
const { ownerDocument } = element;
|
|
21
5
|
if (!ownerDocument) {
|
|
22
6
|
return;
|
|
23
7
|
}
|
|
24
|
-
const {
|
|
25
|
-
defaultView
|
|
26
|
-
} = ownerDocument;
|
|
8
|
+
const { defaultView } = ownerDocument;
|
|
27
9
|
if (!defaultView) {
|
|
28
10
|
return;
|
|
29
11
|
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Checks whether the iframe is the activeElement, inferring that it has
|
|
33
|
-
* then received focus, and dispatches a focus event.
|
|
34
|
-
*/
|
|
35
12
|
function checkFocus() {
|
|
36
13
|
if (ownerDocument && ownerDocument.activeElement === element) {
|
|
37
14
|
element.focus();
|
|
38
15
|
}
|
|
39
16
|
}
|
|
40
|
-
defaultView.addEventListener(
|
|
17
|
+
defaultView.addEventListener("blur", checkFocus);
|
|
41
18
|
return () => {
|
|
42
|
-
defaultView.removeEventListener(
|
|
19
|
+
defaultView.removeEventListener("blur", checkFocus);
|
|
43
20
|
};
|
|
44
21
|
}, []);
|
|
45
22
|
}
|
|
46
|
-
|
|
23
|
+
export {
|
|
24
|
+
useFocusableIframe as default
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/hooks/use-focusable-iframe/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * External dependencies\n */\nimport type { RefCallback } from 'react';\n\n/**\n * Internal dependencies\n */\nimport useRefEffect from '../use-ref-effect';\n\n/**\n * Dispatches a bubbling focus event when the iframe receives focus. Use\n * `onFocus` as usual on the iframe or a parent element.\n *\n * @return Ref to pass to the iframe.\n */\nexport default function useFocusableIframe(): RefCallback< HTMLIFrameElement > {\n\treturn useRefEffect( ( element ) => {\n\t\tconst { ownerDocument } = element;\n\t\tif ( ! ownerDocument ) {\n\t\t\treturn;\n\t\t}\n\t\tconst { defaultView } = ownerDocument;\n\t\tif ( ! defaultView ) {\n\t\t\treturn;\n\t\t}\n\n\t\t/**\n\t\t * Checks whether the iframe is the activeElement, inferring that it has\n\t\t * then received focus, and dispatches a focus event.\n\t\t */\n\t\tfunction checkFocus() {\n\t\t\tif ( ownerDocument && ownerDocument.activeElement === element ) {\n\t\t\t\t( element as HTMLElement ).focus();\n\t\t\t}\n\t\t}\n\n\t\tdefaultView.addEventListener( 'blur', checkFocus );\n\t\treturn () => {\n\t\t\tdefaultView.removeEventListener( 'blur', checkFocus );\n\t\t};\n\t}, [] );\n}\n"],
|
|
5
|
+
"mappings": "AAQA,OAAO,kBAAkB;AAQV,SAAR,qBAAwE;AAC9E,SAAO,aAAc,CAAE,YAAa;AACnC,UAAM,EAAE,cAAc,IAAI;AAC1B,QAAK,CAAE,eAAgB;AACtB;AAAA,IACD;AACA,UAAM,EAAE,YAAY,IAAI;AACxB,QAAK,CAAE,aAAc;AACpB;AAAA,IACD;AAMA,aAAS,aAAa;AACrB,UAAK,iBAAiB,cAAc,kBAAkB,SAAU;AAC/D,QAAE,QAAyB,MAAM;AAAA,MAClC;AAAA,IACD;AAEA,gBAAY,iBAAkB,QAAQ,UAAW;AACjD,WAAO,MAAM;AACZ,kBAAY,oBAAqB,QAAQ,UAAW;AAAA,IACrD;AAAA,EACD,GAAG,CAAC,CAAE;AACP;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -1,42 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*/
|
|
4
|
-
import { useMemo } from '@wordpress/element';
|
|
5
|
-
const instanceMap = new WeakMap();
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Creates a new id for a given object.
|
|
9
|
-
*
|
|
10
|
-
* @param object Object reference to create an id for.
|
|
11
|
-
* @return The instance id (index).
|
|
12
|
-
*/
|
|
1
|
+
import { useMemo } from "@wordpress/element";
|
|
2
|
+
const instanceMap = /* @__PURE__ */ new WeakMap();
|
|
13
3
|
function createId(object) {
|
|
14
4
|
const instances = instanceMap.get(object) || 0;
|
|
15
5
|
instanceMap.set(object, instances + 1);
|
|
16
6
|
return instances;
|
|
17
7
|
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Specify the useInstanceId *function* signatures.
|
|
21
|
-
*
|
|
22
|
-
* More accurately, useInstanceId distinguishes between three different
|
|
23
|
-
* signatures:
|
|
24
|
-
*
|
|
25
|
-
* 1. When only object is given, the returned value is a number
|
|
26
|
-
* 2. When object and prefix is given, the returned value is a string
|
|
27
|
-
* 3. When preferredId is given, the returned value is the type of preferredId
|
|
28
|
-
*
|
|
29
|
-
* @param object Object reference to create an id for.
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Provides a unique instance ID.
|
|
34
|
-
*
|
|
35
|
-
* @param object Object reference to create an id for.
|
|
36
|
-
* @param [prefix] Prefix for the unique id.
|
|
37
|
-
* @param [preferredId] Default ID to use.
|
|
38
|
-
* @return The unique instance id.
|
|
39
|
-
*/
|
|
40
8
|
function useInstanceId(object, prefix, preferredId) {
|
|
41
9
|
return useMemo(() => {
|
|
42
10
|
if (preferredId) {
|
|
@@ -46,5 +14,8 @@ function useInstanceId(object, prefix, preferredId) {
|
|
|
46
14
|
return prefix ? `${prefix}-${id}` : id;
|
|
47
15
|
}, [object, preferredId, prefix]);
|
|
48
16
|
}
|
|
49
|
-
|
|
50
|
-
|
|
17
|
+
var use_instance_id_default = useInstanceId;
|
|
18
|
+
export {
|
|
19
|
+
use_instance_id_default as default
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1,7 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/hooks/use-instance-id/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useMemo } from '@wordpress/element';\n\nconst instanceMap = new WeakMap< object, number >();\n\n/**\n * Creates a new id for a given object.\n *\n * @param object Object reference to create an id for.\n * @return The instance id (index).\n */\nfunction createId( object: object ): number {\n\tconst instances = instanceMap.get( object ) || 0;\n\tinstanceMap.set( object, instances + 1 );\n\treturn instances;\n}\n\n/**\n * Specify the useInstanceId *function* signatures.\n *\n * More accurately, useInstanceId distinguishes between three different\n * signatures:\n *\n * 1. When only object is given, the returned value is a number\n * 2. When object and prefix is given, the returned value is a string\n * 3. When preferredId is given, the returned value is the type of preferredId\n *\n * @param object Object reference to create an id for.\n */\nfunction useInstanceId( object: object ): number;\nfunction useInstanceId( object: object, prefix: string ): string;\nfunction useInstanceId< T extends string | number >(\n\tobject: object,\n\tprefix: string,\n\tpreferredId?: T\n): T;\n\n/**\n * Provides a unique instance ID.\n *\n * @param object Object reference to create an id for.\n * @param [prefix] Prefix for the unique id.\n * @param [preferredId] Default ID to use.\n * @return The unique instance id.\n */\nfunction useInstanceId(\n\tobject: object,\n\tprefix?: string,\n\tpreferredId?: string | number\n): string | number {\n\treturn useMemo( () => {\n\t\tif ( preferredId ) {\n\t\t\treturn preferredId;\n\t\t}\n\t\tconst id = createId( object );\n\n\t\treturn prefix ? `${ prefix }-${ id }` : id;\n\t}, [ object, preferredId, prefix ] );\n}\n\nexport default useInstanceId;\n"],
|
|
5
|
+
"mappings": "AAGA,SAAS,eAAe;AAExB,MAAM,cAAc,oBAAI,QAA0B;AAQlD,SAAS,SAAU,QAAyB;AAC3C,QAAM,YAAY,YAAY,IAAK,MAAO,KAAK;AAC/C,cAAY,IAAK,QAAQ,YAAY,CAAE;AACvC,SAAO;AACR;AA8BA,SAAS,cACR,QACA,QACA,aACkB;AAClB,SAAO,QAAS,MAAM;AACrB,QAAK,aAAc;AAClB,aAAO;AAAA,IACR;AACA,UAAM,KAAK,SAAU,MAAO;AAE5B,WAAO,SAAS,GAAI,MAAO,IAAK,EAAG,KAAK;AAAA,EACzC,GAAG,CAAE,QAAQ,aAAa,MAAO,CAAE;AACpC;AAEA,IAAO,0BAAQ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|