在切换到下一个元素时禁用语义 UI 下拉选项

Disable Semantic UI dropdown option being selected when tabbing to next element

我正在使用 ReactJS 并使用语义 UI。

我的页面上有一个面包屑样式的导航菜单,使用来自 Semantic UI.

的 'Breadcrumb' 和 'Dropdown' 组件构建

我正在尝试通过允许用户使用键盘(制表符、箭头和回车)导航菜单、下拉选项并从 selection 来使菜单的行为可访问下拉选项。

我要解决的问题是,当使用键盘时,用户应该只能select一个选项,当它被聚焦时(使用箭头键)其次是按'enter'键。当用户关注一个选项时,当他们 'tab' 到下一个元素时,它会 selected。

是否可以更改此行为,以便仅在按下回车键时 select 编辑一个选项?

我尝试在 Dropdown 组件上实现 "selectOnNavigation={false}" 但是当 'tabbing' 远离元素.

我也尝试过操纵事件处理程序 onBlur(),但它仍然 select在 Tab 键时编辑了选项。

我的组件代码:

import React from 'react';
import { connect } from 'react-redux';
import { Breadcrumb, Dropdown } from 'semantic-ui-react';
import PropTypes from 'prop-types';
import {
  saveBreadcrumbOptions,
  changeBreadcrumbMarket,
  changeBreadcrumbParentGroup,
  changeBreadcrumbAgency
} from '../../actions/breadcrumbActions';
import MenuFiltersAPI from '../../api/MenuFiltersAPI';
import './OMGBreadcrumb.css';

export class OMGBreadcrumb extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      markets: [],
      parentGroups: [],
      agencies: []
    };

    this.getBreadcrumbOptions = this.getBreadcrumbOptions.bind(this);
    this.handleMarketChange = this.handleMarketChange.bind(this);
    this.handleParentGroupChange = this.handleParentGroupChange.bind(this);
    this.handleAgencyChange = this.handleAgencyChange.bind(this);
    this.handleParentGroupBlur = this.handleParentGroupBlur.bind(this);
  }

  componentDidMount() {
    this.getBreadcrumbOptions();
  }

  async getBreadcrumbOptions() {
    // get all options
    const breadcrumb = this.props.breadcrumb.options.length
      ? this.props.breadcrumb.options
      : await MenuFiltersAPI.getBreadcrumb();

    // if a market is selected, use it
    // otherwise use the first one
    let selectedMarket = breadcrumb.find(m => (
      m.id === this.props.breadcrumb.selectedMarket
    ));

    selectedMarket = selectedMarket
      ? selectedMarket.id
      : breadcrumb[0].id;

    this.props.saveBreadcrumbOptions(breadcrumb);
    this.setState({ markets: breadcrumb }, () => this.changeMarket(selectedMarket));
  }

  changeMarket(id) {
    // get parent group options for given market
    const parentGroups = this.state.markets.find(market => market.id === id).parent_groups;

    // if a parent group is selected, use it
    // otherwise use the first one
    let selectedParentGroup = parentGroups.find(pg => (
      pg.id === this.props.breadcrumb.selectedParentGroup
    ));

    selectedParentGroup = selectedParentGroup
      ? selectedParentGroup.id
      : parentGroups[0].id;

    this.props.changeBreadcrumbMarket(id);
    this.setState({ parentGroups }, () => this.changeParentGroup(selectedParentGroup));
  }

  changeParentGroup(id) {
    // get agency options for dropdown menu
    const agencies = this.state.parentGroups.find(parentGroup => parentGroup.id === id).agencies;

    let selectedAgency = agencies.find(a => (
      a.id === this.props.breadcrumb.selectedAgency
    ));

    selectedAgency = selectedAgency
      ? selectedAgency.id
      : agencies[0].id;

    this.props.changeBreadcrumbParentGroup(id);
    this.setState({ agencies }, () => this.changeAgency(selectedAgency));
  }

  changeAgency(id) {
    // const selectedAgency = agencyOptions[0].value
    this.props.changeBreadcrumbAgency(id);
  }

  handleMarketChange(e, { value }) {
    console.log(value)
    this.changeMarket(value);
  }

  handleParentGroupChange(e, { value }) {
    console.log(value)
    // if(!!value){
    //   return;
    // }
    this.changeParentGroup(value);
  }

  handleAgencyChange(e, { value }) {
    console.log(value)
    this.changeAgency(value);
  }

  handleParentGroupBlur(e, {value}) {
    e.preventDefault();
    console.log(e.key)
    if(e.key !== 'Enter'){
      console.log('key was not enter')
      return;
    }
    
  }

  render() {
    return (
      <div id="OMGBreadcrumb">
        <b>Show information by: </b>
        <Breadcrumb>
          <Breadcrumb.Section>
            <Dropdown
              selectOnNavigation={false}
              options={this.state.markets.reduce((acc, cur) => {
                acc.push({ text: cur.name, value: cur.id });
                return acc;
              }, [])}
              value={this.props.breadcrumb.selectedMarket}
              onChange={this.handleMarketChange}
              openOnFocus={false}
            />
          </Breadcrumb.Section>

          <Breadcrumb.Divider icon='right chevron' />

          <Breadcrumb.Section>
            <Dropdown
              selectOnNavigation={false}
              options={this.state.parentGroups.reduce((acc, cur) => {
                acc.push({ text: cur.name, value: cur.id });
                return acc;
              }, [])}
              value={this.props.breadcrumb.selectedParentGroup}
              onChange={this.handleParentGroupChange}
              openOnFocus={false}   
              onBlur={this.handleParentGroupBlur}         
            />
          </Breadcrumb.Section>

          <Breadcrumb.Divider icon='right chevron' />

          <Breadcrumb.Section>
            <Dropdown
              // selectOnNavigation={false}
              options={this.state.agencies.reduce((acc, cur) => {
                acc.push({ text: cur.name, value: cur.id });
                return acc;
              }, [])}
              value={this.props.breadcrumb.selectedAgency}
              onChange={this.handleAgencyChange}
              openOnFocus={false}
            />
          </Breadcrumb.Section>
        </Breadcrumb>
      </div>
    );
  }
}

OMGBreadcrumb.propTypes = {
  saveBreadcrumbOptions: PropTypes.func.isRequired,
  changeBreadcrumbMarket: PropTypes.func.isRequired,
  changeBreadcrumbParentGroup: PropTypes.func.isRequired,
  changeBreadcrumbAgency: PropTypes.func.isRequired,
  breadcrumb: PropTypes.objectOf(
    PropTypes.oneOfType([
      PropTypes.number,
      PropTypes.array
    ])
  ).isRequired
};

export default connect(
  store => ({
    breadcrumb: store.breadcrumb
  }),
  {
    saveBreadcrumbOptions,
    changeBreadcrumbMarket,
    changeBreadcrumbParentGroup,
    changeBreadcrumbAgency
  }
)(OMGBreadcrumb);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

感谢任何指导。

您可以将 selectOnBlur={false} 添加到您的下拉组件,当下拉列表模糊时,它不再 select。

<Dropdown
  ...
  selectOnBlur={false}
/>

https://codesandbox.io/s/semantic-ui-example-7qgcu?module=%2Fexample.js