UNPKG

@wordpress/block-library

Version:
8 lines (7 loc) 3.93 kB
{ "version": 3, "sources": ["../../../src/list-item/hooks/use-multi-select-tab.js"], "sourcesContent": ["import { useRefEffect } from '@wordpress/compose';\nimport { TAB } from '@wordpress/keycodes';\nimport { store as blockEditorStore } from '@wordpress/block-editor';\nimport { useSelect, useRegistry } from '@wordpress/data';\nimport { indentListItems, outdentListItems } from '../utils';\n\nexport default function useMultiSelectTab( clientId ) {\n\tconst registry = useRegistry();\n\t// Only the first item of an all-list-item multi selection attaches the\n\t// listener, so there is a single handler regardless of how many list items\n\t// are rendered, and only while such a selection exists.\n\tconst isActive = useSelect(\n\t\t( select ) => {\n\t\t\tconst {\n\t\t\t\thasMultiSelection,\n\t\t\t\tgetMultiSelectedBlockClientIds,\n\t\t\t\tgetBlockName,\n\t\t\t} = select( blockEditorStore );\n\t\t\tif ( ! hasMultiSelection() ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tconst clientIds = getMultiSelectedBlockClientIds();\n\t\t\treturn (\n\t\t\t\tclientIds[ 0 ] === clientId &&\n\t\t\t\tclientIds.every(\n\t\t\t\t\t( id ) => getBlockName( id ) === 'core/list-item'\n\t\t\t\t)\n\t\t\t);\n\t\t},\n\t\t[ clientId ]\n\t);\n\n\treturn useRefEffect(\n\t\t( element ) => {\n\t\t\tif ( ! isActive ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfunction onKeyDown( event ) {\n\t\t\t\tconst { keyCode, shiftKey, altKey, metaKey, ctrlKey } = event;\n\n\t\t\t\tif (\n\t\t\t\t\tkeyCode !== TAB ||\n\t\t\t\t\tevent.defaultPrevented ||\n\t\t\t\t\taltKey ||\n\t\t\t\t\tmetaKey ||\n\t\t\t\t\tctrlKey\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// The listener is on the document, so it also sees a Tab from\n\t\t\t\t// other editor UI while the multi selection lingers (moving\n\t\t\t\t// focus does not clear it). A multi selection keeps focus on the\n\t\t\t\t// canvas host that wraps the blocks, so only act when the key\n\t\t\t\t// comes from an ancestor of them, not from a toolbar or panel.\n\t\t\t\tif ( ! event.target.contains( element ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif ( shiftKey ) {\n\t\t\t\t\tif ( outdentListItems( registry ) ) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t} else if ( indentListItems( registry ) ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// During a multi selection focus sits on the writing flow\n\t\t\t// container, not inside any item, so an element listener never sees\n\t\t\t// the key. Listen on the document. Capture phase so we run before\n\t\t\t// writing-flow's keydown handlers, which gate on\n\t\t\t// `event.defaultPrevented`.\n\t\t\tconst { ownerDocument } = element;\n\t\t\townerDocument.addEventListener( 'keydown', onKeyDown, true );\n\t\t\treturn () => {\n\t\t\t\townerDocument.removeEventListener( 'keydown', onKeyDown, true );\n\t\t\t};\n\t\t},\n\t\t[ isActive, registry ]\n\t);\n}\n"], "mappings": ";AAAA,SAAS,oBAAoB;AAC7B,SAAS,WAAW;AACpB,SAAS,SAAS,wBAAwB;AAC1C,SAAS,WAAW,mBAAmB;AACvC,SAAS,iBAAiB,wBAAwB;AAEnC,SAAR,kBAAoC,UAAW;AACrD,QAAM,WAAW,YAAY;AAI7B,QAAM,WAAW;AAAA,IAChB,CAAE,WAAY;AACb,YAAM;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,MACD,IAAI,OAAQ,gBAAiB;AAC7B,UAAK,CAAE,kBAAkB,GAAI;AAC5B,eAAO;AAAA,MACR;AACA,YAAM,YAAY,+BAA+B;AACjD,aACC,UAAW,CAAE,MAAM,YACnB,UAAU;AAAA,QACT,CAAE,OAAQ,aAAc,EAAG,MAAM;AAAA,MAClC;AAAA,IAEF;AAAA,IACA,CAAE,QAAS;AAAA,EACZ;AAEA,SAAO;AAAA,IACN,CAAE,YAAa;AACd,UAAK,CAAE,UAAW;AACjB;AAAA,MACD;AAEA,eAAS,UAAW,OAAQ;AAC3B,cAAM,EAAE,SAAS,UAAU,QAAQ,SAAS,QAAQ,IAAI;AAExD,YACC,YAAY,OACZ,MAAM,oBACN,UACA,WACA,SACC;AACD;AAAA,QACD;AAOA,YAAK,CAAE,MAAM,OAAO,SAAU,OAAQ,GAAI;AACzC;AAAA,QACD;AAEA,YAAK,UAAW;AACf,cAAK,iBAAkB,QAAS,GAAI;AACnC,kBAAM,eAAe;AAAA,UACtB;AAAA,QACD,WAAY,gBAAiB,QAAS,GAAI;AACzC,gBAAM,eAAe;AAAA,QACtB;AAAA,MACD;AAOA,YAAM,EAAE,cAAc,IAAI;AAC1B,oBAAc,iBAAkB,WAAW,WAAW,IAAK;AAC3D,aAAO,MAAM;AACZ,sBAAc,oBAAqB,WAAW,WAAW,IAAK;AAAA,MAC/D;AAAA,IACD;AAAA,IACA,CAAE,UAAU,QAAS;AAAA,EACtB;AACD;", "names": [] }