UNPKG

@wordpress/components

Version:
8 lines (7 loc) 8.63 kB
{ "version": 3, "sources": ["../../src/autocomplete/autocompleter-ui.tsx"], "sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\nimport { createPortal } from 'react-dom';\n\n/**\n * WordPress dependencies\n */\nimport { useLayoutEffect, useRef, useEffect, useState } from '@wordpress/element';\nimport { useAnchor } from '@wordpress/rich-text';\nimport { useDebounce, useMergeRefs, useRefEffect } from '@wordpress/compose';\nimport { speak } from '@wordpress/a11y';\nimport { __, _n, sprintf } from '@wordpress/i18n';\n\n/**\n * Internal dependencies\n */\nimport getDefaultUseItems from './get-default-use-items';\nimport Button from '../button';\nimport Popover from '../popover';\nimport { VisuallyHidden } from '../visually-hidden';\nimport { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from \"react/jsx-runtime\";\nfunction ListBox({\n items,\n onSelect,\n selectedIndex,\n instanceId,\n listBoxId,\n className,\n Component = 'div'\n}) {\n return /*#__PURE__*/_jsx(Component, {\n id: listBoxId,\n role: \"listbox\",\n className: \"components-autocomplete__results\",\n children: items.map((option, index) => /*#__PURE__*/_jsx(Button, {\n id: `components-autocomplete-item-${instanceId}-${option.key}`,\n role: \"option\",\n __next40pxDefaultSize: true,\n \"aria-selected\": index === selectedIndex,\n accessibleWhenDisabled: true,\n disabled: option.isDisabled,\n className: clsx('components-autocomplete__result', className, {\n // Unused, for backwards compatibility.\n 'is-selected': index === selectedIndex\n }),\n variant: index === selectedIndex ? 'primary' : undefined,\n onClick: () => onSelect(option),\n children: option.label\n }, option.key))\n });\n}\nexport function AutocompleterUI({\n autocompleter,\n filterValue,\n instanceId,\n listBoxId,\n className,\n selectedIndex,\n onChangeOptions,\n onSelect,\n reset,\n contentRef\n}) {\n // The useItems hook is derived from the autocompleter prop. This is safe\n // because the parent renders this component with key={autocompleter.name},\n // ensuring a fresh mount (and stable hook identity) when the completer changes.\n const useItems = autocompleter.useItems ?? getDefaultUseItems(autocompleter);\n // eslint-disable-next-line react-compiler/react-compiler\n const [items] = useItems(filterValue);\n const popoverAnchor = useAnchor({\n editableContentElement: contentRef.current\n });\n const [needsA11yCompat, setNeedsA11yCompat] = useState(false);\n const popoverRef = useRef(null);\n const popoverRefs = useMergeRefs([popoverRef, useRefEffect(node => {\n if (!contentRef.current) {\n return;\n }\n\n // If the popover is rendered in a different document than\n // the content, we need to duplicate the options list in the\n // content document so that it's available to the screen\n // readers, which check the DOM ID based aria-* attributes.\n setNeedsA11yCompat(node.ownerDocument !== contentRef.current.ownerDocument);\n }, [contentRef])]);\n useOnClickOutside(popoverRef, reset);\n const debouncedSpeak = useDebounce(speak, 500);\n function announce(options) {\n if (!debouncedSpeak) {\n return;\n }\n if (!!options.length) {\n if (filterValue) {\n debouncedSpeak(sprintf(/* translators: %d: number of results. */\n _n('%d result found, use up and down arrow keys to navigate.', '%d results found, use up and down arrow keys to navigate.', options.length), options.length), 'assertive');\n } else {\n debouncedSpeak(sprintf(/* translators: %d: number of results. */\n _n('Initial %d result loaded. Type to filter all available results. Use up and down arrow keys to navigate.', 'Initial %d results loaded. Type to filter all available results. Use up and down arrow keys to navigate.', options.length), options.length), 'assertive');\n }\n } else {\n debouncedSpeak(__('No results.'), 'assertive');\n }\n }\n useLayoutEffect(() => {\n onChangeOptions(items);\n announce(items);\n // We want to avoid introducing unexpected side effects.\n // See https://github.com/WordPress/gutenberg/pull/41820\n }, [items]);\n if (items.length === 0) {\n return null;\n }\n return /*#__PURE__*/_jsxs(_Fragment, {\n children: [/*#__PURE__*/_jsx(Popover, {\n offset: 8,\n focusOnMount: false,\n placement: \"top-start\",\n className: \"components-autocomplete__popover\",\n anchor: popoverAnchor,\n ref: popoverRefs,\n children: /*#__PURE__*/_jsx(ListBox, {\n items: items,\n onSelect: onSelect,\n selectedIndex: selectedIndex,\n instanceId: instanceId,\n listBoxId: listBoxId,\n className: className\n })\n }), contentRef.current && needsA11yCompat && createPortal(/*#__PURE__*/_jsx(ListBox, {\n items: items,\n onSelect: onSelect,\n selectedIndex: selectedIndex,\n instanceId: instanceId,\n listBoxId: listBoxId,\n className: className,\n Component: VisuallyHidden\n }), contentRef.current.ownerDocument.body)]\n });\n}\nfunction useOnClickOutside(ref, handler) {\n useEffect(() => {\n const listener = event => {\n // Do nothing if clicking ref's element or descendent elements, or if the ref is not referencing an element\n if (!ref.current || ref.current.contains(event.target)) {\n return;\n }\n handler(event);\n };\n document.addEventListener('mousedown', listener);\n document.addEventListener('touchstart', listener);\n return () => {\n document.removeEventListener('mousedown', listener);\n document.removeEventListener('touchstart', listener);\n };\n }, [handler, ref]);\n}"], "mappings": "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", "names": ["_jsx", "Button", "clsx", "getDefaultUseItems", "_jsxs", "_Fragment", "Popover"] }