Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restore Standard Select Controls #974

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

ZachAlanMueller
Copy link

@ZachAlanMueller ZachAlanMueller commented Aug 14, 2023

Vanilla HTML Selects standard controls allow for arrow keys up/down to select the previous/next option, and then when a user tabs, it keeps that selected option. This commit implements that functionality into rc-select.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select#technical_summary

This functionality has been asked for by the community for Ant Design over the years, see issue here:
close ant-design/ant-design#26876

Please forgive me if I've done this PR incorrectly, I'm unfamiliar with the procedure, and if I did anything wrong, please let me know so that I can do better next time.

Selects standard controls allow for arrow keys up/down to select the previous/next option, and then when a user tabs, it keeps that selected option. 
This commit restores that lost functionality.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select#technical_summary
@vercel
Copy link

vercel bot commented Aug 14, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
select ❌ Failed (Inspect) Aug 14, 2023 4:00pm

@yoyo837
Copy link
Member

yoyo837 commented Aug 14, 2023

Please add some test case for it.

@ZachAlanMueller
Copy link
Author

Thank you for your feedback. I understand that you would like me to add some test cases for the new feature. I apologize for not knowing how to do this, as I am still new to unit testing.

I would like to learn how to add test cases, so that I can be more helpful in the future. Would you be able to provide me with some resources or training on unit testing?

@yoyo837
Copy link
Member

yoyo837 commented Aug 15, 2023

@sixwinds
Copy link

sixwinds commented Sep 4, 2023

I have a temp fall back implementation, the idea is that find the active option dom node when blur:

// libs
import { useRef } from 'react';
import { Select } from 'antd';
// utils
import isFunction from '@/utils/isFunction';

// this func is based on antd version 4, you can customized it on your antd version
const getActiveOpitonContentElement = (rootElement) => {
  if (rootElement) {
    const activeOptionElement = rootElement.getElementsByClassName(
      'ant-select-item-option-active',
    )?.[0];
    if (activeOptionElement) {
      const optionContentElement = activeOptionElement.getElementsByClassName(
        'ant-select-item-option-content',
      )?.[0];
      return optionContentElement;
    }
  }
  return void 0;
};

const MySelect = (props) => {
  const {
    options,
    optionFilterProp,
    dropdownRender,
    onBlur,
    onChange,
    ...restProps
  } = props;

  const dropdownWrapperElementRef = useRef();

  return (
    <Select
      {...restProps}
      onChange={onChange}
      optionFilterProp={optionFilterProp}
      options={options}
      dropdownRender={(originNode) => {
        if (isFunction(dropdownRender)) {
          return (
            <div ref={dropdownWrapperElementRef}>
              {dropdownRender(originNode)}
            </div>
          )
        }
        return (
          <div ref={dropdownWrapperElementRef}>
            {originNode}
          </div>
        );
      }}
      onBlur={(...args) => {
        // ---- [implementation of tabbing to select active option] start -----
        const activeOptionContentElement = getActiveOpitonContentElement(
          dropdownWrapperElementRef.current,
        );
        if (
          activeOptionContentElement &&
          Array.isArray(options) &&
          options.length > 0
        ) {
          const activeOption = options.find((el) => {
            return (
              el[optionFilterProp ?? 'value'] ===
              activeOptionContentElement.innerText
            );
          });
          if (activeOption && isFunction(onChange)) {
            onChange(activeOption.value);
          }
        }
        // ---- [implementation of tabbing to select active option] end -----

        if (isFunction(onBlur)) {
          onBlur(...args);
        }
      }}
    />
  );
};

It is based on antd version 4, but I think developer can customized the implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Tabbing to select active option in <Select>
3 participants