summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/jetpack/extensions/blocks/map/lookup/index.js')
-rw-r--r--plugins/jetpack/extensions/blocks/map/lookup/index.js230
1 files changed, 0 insertions, 230 deletions
diff --git a/plugins/jetpack/extensions/blocks/map/lookup/index.js b/plugins/jetpack/extensions/blocks/map/lookup/index.js
deleted file mode 100644
index c9d41969..00000000
--- a/plugins/jetpack/extensions/blocks/map/lookup/index.js
+++ /dev/null
@@ -1,230 +0,0 @@
-/**
- * External dependencies
- */
-import classnames from 'classnames';
-import { __, _n, sprintf } from '@wordpress/i18n';
-import { Button, Popover, withFocusOutside, withSpokenMessages } from '@wordpress/components';
-import { Component } from '@wordpress/element';
-import { debounce, map } from 'lodash';
-import { ENTER, ESCAPE, UP, DOWN, LEFT, RIGHT } from '@wordpress/keycodes';
-import { withInstanceId, compose } from '@wordpress/compose';
-
-function filterOptions( options = [], maxResults = 10 ) {
- const filtered = [];
- for ( let i = 0; i < options.length; i++ ) {
- const option = options[ i ];
-
- // Merge label into keywords
- let { keywords = [] } = option;
- if ( 'string' === typeof option.label ) {
- keywords = [ ...keywords, option.label ];
- }
-
- filtered.push( option );
-
- // Abort early if max reached
- if ( filtered.length === maxResults ) {
- break;
- }
- }
-
- return filtered;
-}
-
-export class Lookup extends Component {
- static getInitialState() {
- return {
- selectedIndex: 0,
- query: undefined,
- filteredOptions: [],
- isOpen: false,
- };
- }
-
- constructor() {
- super( ...arguments );
- this.debouncedLoadOptions = debounce( this.loadOptions, 250 );
- this.state = this.constructor.getInitialState();
- }
-
- componentWillUnmount() {
- this.debouncedLoadOptions.cancel();
- }
-
- select = option => {
- const { completer } = this.props;
- const getOptionCompletion = completer.getOptionCompletion || {};
- getOptionCompletion( option );
- this.reset();
- };
-
- reset = () => {
- this.setState( this.constructor.getInitialState() );
- };
-
- handleFocusOutside() {
- this.reset();
- }
-
- loadOptions( completer, query ) {
- const { options } = completer;
- const promise = ( this.activePromise = Promise.resolve(
- typeof options === 'function' ? options( query ) : options
- ).then( optionsData => {
- if ( promise !== this.activePromise ) {
- // Another promise has become active since this one was asked to resolve, so do nothing,
- // or else we might end triggering a race condition updating the state.
- return;
- }
- const keyedOptions = optionsData.map( ( optionData, optionIndex ) => ( {
- key: `${ optionIndex }`,
- value: optionData,
- label: completer.getOptionLabel( optionData ),
- keywords: completer.getOptionKeywords ? completer.getOptionKeywords( optionData ) : [],
- } ) );
-
- const filteredOptions = filterOptions( keyedOptions );
- const selectedIndex =
- filteredOptions.length === this.state.filteredOptions.length ? this.state.selectedIndex : 0;
- this.setState( {
- [ 'options' ]: keyedOptions,
- filteredOptions,
- selectedIndex,
- isOpen: filteredOptions.length > 0,
- } );
- this.announce( filteredOptions );
- } ) );
- }
-
- onChange = query => {
- const { completer } = this.props;
- const { options } = this.state;
-
- if ( ! query ) {
- this.reset();
- return;
- }
-
- if ( completer ) {
- if ( completer.isDebounced ) {
- this.debouncedLoadOptions( completer, query );
- } else {
- this.loadOptions( completer, query );
- }
- }
-
- const filteredOptions = completer ? filterOptions( options ) : [];
- if ( completer ) {
- this.setState( { selectedIndex: 0, filteredOptions, query } );
- }
- };
-
- onKeyDown = event => {
- const { isOpen, selectedIndex, filteredOptions } = this.state;
- if ( ! isOpen ) {
- return;
- }
- let nextSelectedIndex;
- switch ( event.keyCode ) {
- case UP:
- nextSelectedIndex = ( selectedIndex === 0 ? filteredOptions.length : selectedIndex ) - 1;
- this.setState( { selectedIndex: nextSelectedIndex } );
- break;
-
- case DOWN:
- nextSelectedIndex = ( selectedIndex + 1 ) % filteredOptions.length;
- this.setState( { selectedIndex: nextSelectedIndex } );
- break;
-
- case ENTER:
- this.select( filteredOptions[ selectedIndex ] );
- break;
-
- case LEFT:
- case RIGHT:
- case ESCAPE:
- this.reset();
- return;
-
- default:
- return;
- }
-
- // Any handled keycode should prevent original behavior. This relies on
- // the early return in the default case.
- event.preventDefault();
- event.stopPropagation();
- };
- announce( filteredOptions ) {
- const { debouncedSpeak } = this.props;
- if ( ! debouncedSpeak ) {
- return;
- }
- if ( filteredOptions.length ) {
- debouncedSpeak(
- sprintf(
- _n(
- '%d result found, use up and down arrow keys to navigate.',
- '%d results found, use up and down arrow keys to navigate.',
- filteredOptions.length,
- 'jetpack',
- 'jetpack'
- ),
- filteredOptions.length
- ),
- 'assertive'
- );
- } else {
- debouncedSpeak( __( 'No results.', 'jetpack' ), 'assertive' );
- }
- }
- render() {
- const { onChange, onKeyDown } = this;
- const { children, instanceId, completer } = this.props;
- const { selectedIndex, filteredOptions } = this.state;
- const { key: selectedKey = '' } = filteredOptions[ selectedIndex ] || {};
- const { className } = completer;
- const isExpanded = filteredOptions.length > 0;
- const listBoxId = isExpanded ? `components-autocomplete-listbox-${ instanceId }` : null;
- const activeId = isExpanded
- ? `components-autocomplete-item-${ instanceId }-${ selectedKey }`
- : null;
- return (
- <div className="components-autocomplete">
- { children( { isExpanded, listBoxId, activeId, onChange, onKeyDown } ) }
- { isExpanded && (
- <Popover
- focusOnMount={ false }
- onClose={ this.reset }
- position="top center"
- className="components-autocomplete__popover"
- noArrow
- >
- <div id={ listBoxId } role="listbox" className="components-autocomplete__results">
- { map( filteredOptions, ( option, index ) => (
- <Button
- key={ option.key }
- id={ `components-autocomplete-item-${ instanceId }-${ option.key }` }
- role="option"
- aria-selected={ index === selectedIndex }
- disabled={ option.isDisabled }
- className={ classnames( 'components-autocomplete__result', className, {
- 'is-selected': index === selectedIndex,
- } ) }
- onClick={ () => this.select( option ) }
- >
- { option.label }
- </Button>
- ) ) }
- </div>
- </Popover>
- ) }
- </div>
- );
- }
-}
-export default compose( [
- withSpokenMessages,
- withInstanceId,
- withFocusOutside, // this MUST be the innermost HOC as it calls handleFocusOutside
-] )( Lookup );